|
@@ -11,7 +11,7 @@ import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
-import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
@@ -37,7 +37,6 @@ import org.jeecg.modules.billet.billetHotsend.entity.BilletHotsend;
|
|
|
import org.jeecg.modules.billet.billetHotsend.service.IBilletHotsendBaseService;
|
|
|
import org.jeecg.modules.billet.billetHotsendChangeShift.entity.BilletHotsendChangeShift;
|
|
|
import org.jeecg.modules.billet.billetHotsendChangeShift.service.IBilletHotsendChangeShiftService;
|
|
|
-import org.jeecg.modules.billet.billetOriginalProductRecord.dto.BilletOriginalProductRecordEditDTO;
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.dto.LengthCountQueryDTO;
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.dto.QualityInspectionQueryDTO;
|
|
|
import org.jeecg.modules.billet.billetOriginalProductRecord.entity.BilletOriginalProductRecord;
|
|
@@ -58,7 +57,7 @@ import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
import org.springframework.web.servlet.ModelAndView;
|
|
|
|
|
|
- /**
|
|
|
+/**
|
|
|
* @Description: 钢坯生成原始记录
|
|
|
* @Author: jeecg-boot
|
|
|
* @Date: 2025-06-23
|
|
@@ -79,28 +78,28 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
@Autowired
|
|
|
private IBilletHotsendChangeShiftService billetHotsendChangeShiftService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IBilletHotsendBaseService billetHotsendBaseService;
|
|
|
+ @Autowired
|
|
|
+ private IBilletHotsendBaseService billetHotsendBaseService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IBilletBasicInfoService billetBasicInfoService;
|
|
|
+ @Autowired
|
|
|
+ private IBilletBasicInfoService billetBasicInfoService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IStorageBillPrintService storageBillPrintService;
|
|
|
+ @Autowired
|
|
|
+ private IStorageBillPrintService storageBillPrintService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private ISysDictService sysDictService;
|
|
|
+ @Autowired
|
|
|
+ private ISysDictService sysDictService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private StackingAndLoadingVehiclesMapper stackingAndLoadingVehiclesMapper;
|
|
|
+ @Autowired
|
|
|
+ private StackingAndLoadingVehiclesMapper stackingAndLoadingVehiclesMapper;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IStorageBillService storageBillService;
|
|
|
+ @Autowired
|
|
|
+ private IStorageBillService storageBillService;
|
|
|
|
|
|
- @Autowired
|
|
|
- private IShiftConfigurationService shiftConfigurationService;
|
|
|
-
|
|
|
- /**
|
|
|
+ @Autowired
|
|
|
+ private IShiftConfigurationService shiftConfigurationService;
|
|
|
+
|
|
|
+ /**
|
|
|
* 分页列表查询
|
|
|
*
|
|
|
* @param billetOriginalProductRecord
|
|
@@ -113,15 +112,15 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
@ApiOperation(value="钢坯生成原始记录-分页列表查询", notes="钢坯生成原始记录-分页列表查询")
|
|
|
@GetMapping(value = "/list")
|
|
|
public Result<IPage<BilletOriginalProductRecord>> queryPageList(BilletOriginalProductRecord billetOriginalProductRecord,
|
|
|
- @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
|
|
- @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
|
|
- HttpServletRequest req) {
|
|
|
+ @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
|
|
|
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize,
|
|
|
+ HttpServletRequest req) {
|
|
|
QueryWrapper<BilletOriginalProductRecord> queryWrapper = QueryGenerator.initQueryWrapper(billetOriginalProductRecord, req.getParameterMap());
|
|
|
Page<BilletOriginalProductRecord> page = new Page<BilletOriginalProductRecord>(pageNo, pageSize);
|
|
|
IPage<BilletOriginalProductRecord> pageList = billetOriginalProductRecordService.page(page, queryWrapper);
|
|
|
return Result.OK(pageList);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 添加
|
|
|
*
|
|
@@ -189,7 +188,7 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
billetOriginalProductRecordService.save(billetOriginalProductRecord);
|
|
|
return Result.OK("添加成功!");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 编辑
|
|
|
*
|
|
@@ -239,277 +238,319 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
return Result.OK("编辑成功!");
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 处理编辑操作中的公共逻辑
|
|
|
- */
|
|
|
- private void processCommonEditLogic(BilletOriginalProductRecord bopr, BilletOriginalProductRecord newRecord, boolean hotChargeLengthUpdated) {
|
|
|
- // 复制所有非空字段(忽略ID和流支数字段)
|
|
|
- String[] ignoreProperties = {"id", "oneStrandSum", "twoStrandSum", "threeStrandSum",
|
|
|
- "fourStrandSum", "fiveStrandSum", "sixStrandSum",
|
|
|
- "sevenStrandSum", "eightStrandSum", "amount"};
|
|
|
- BeanUtils.copyProperties(newRecord, bopr, ignoreProperties);
|
|
|
-
|
|
|
- // 如果更新了hotChargeLength,设置is_edit_charge为2
|
|
|
- if (hotChargeLengthUpdated) {
|
|
|
- bopr.setIsEditCharge("2");
|
|
|
- }
|
|
|
-
|
|
|
- // 判断stackInfo字段是否为非空,不为空代表需要起垛
|
|
|
- if (oConvertUtils.isNotEmpty(bopr.getStackInfo())) {
|
|
|
- String str = bopr.getStackInfo();
|
|
|
- String[] parts = str.split("-");
|
|
|
- // 起垛的数量
|
|
|
- int stackingSum = Integer.parseInt(parts[0]);
|
|
|
- // 定尺
|
|
|
- String size = parts[1];
|
|
|
- String typeConfigId = parts[2];
|
|
|
- handleAddStack(bopr.getCcmNo(), bopr.getHeatNo(), stackingSum, size, typeConfigId);
|
|
|
- // 备注stackInfo字段重置
|
|
|
- bopr.setStackInfo("");
|
|
|
- }
|
|
|
- // 保存修改
|
|
|
- billetOriginalProductRecordService.updateById(bopr);
|
|
|
- }
|
|
|
-
|
|
|
- /***
|
|
|
- * 处理起垛
|
|
|
- * @param ccmNo
|
|
|
- * @param heatNo
|
|
|
- * @param stackingSum
|
|
|
- * @param size
|
|
|
- * @param typeConfigId
|
|
|
- */
|
|
|
- private void handleAddStack(String ccmNo, String heatNo, int stackingSum, String size, String typeConfigId) {
|
|
|
- // 获取班次信息
|
|
|
- String classShiftGroup = String.format("class:shift:group:%s", ccmNo);
|
|
|
- String classShift = String.format("class:shift:%s", ccmNo);
|
|
|
- String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ?
|
|
|
- oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
- String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ?
|
|
|
- oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
-
|
|
|
- // 计算需要起垛的数量
|
|
|
- int demandStackingSum = stackingSum / 4;
|
|
|
- if (demandStackingSum <= 0) {
|
|
|
- log.info("起垛数量计算结果为非正数,起垛失败!heatNo={}, stackingSum={}", heatNo, stackingSum);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 查询所有可能的位置,并按layer和address排序(低layer优先,address从1到9)
|
|
|
- List<StackingAndLoadingVehicles> allPositions = stackingAndLoadingVehiclesMapper.selectList(
|
|
|
- new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
- .eq("ccm_no", ccmNo)
|
|
|
- .eq("type_config_id", typeConfigId));
|
|
|
-
|
|
|
- if (allPositions != null) {
|
|
|
- allPositions.sort(Comparator.comparing(StackingAndLoadingVehicles::getLayer,
|
|
|
- Comparator.comparingInt(Integer::parseInt))
|
|
|
- .thenComparing(StackingAndLoadingVehicles::getAddress,
|
|
|
- Comparator.comparingInt(Integer::parseInt)));
|
|
|
- }
|
|
|
-
|
|
|
- // 获取所有可用的空位置(按排序后的顺序)
|
|
|
- List<StackingAndLoadingVehicles> availablePositions = allPositions.stream()
|
|
|
- .filter(v -> oConvertUtils.isEmpty(v.getBilletNos()))
|
|
|
- .collect(Collectors.toList());
|
|
|
-
|
|
|
- // 如果没有可用的空位置,则尝试计算新位置
|
|
|
- if (availablePositions.isEmpty()) {
|
|
|
- // 获取最高占用层
|
|
|
- StackingAndLoadingVehicles highAddressSALV = getHighestOccupiedLayer(allPositions);
|
|
|
-
|
|
|
- // 如果没有任何占用层,从1.1开始
|
|
|
- if (highAddressSALV == null) {
|
|
|
- highAddressSALV = new StackingAndLoadingVehicles();
|
|
|
- highAddressSALV.setAddress("1");
|
|
|
- highAddressSALV.setLayer("1");
|
|
|
- highAddressSALV.setCcmNo(ccmNo);
|
|
|
- highAddressSALV.setTypeConfigId(typeConfigId);
|
|
|
- } else {
|
|
|
- log.info("最高占用层位置:{}.{}", highAddressSALV.getLayer(), highAddressSALV.getAddress());
|
|
|
- }
|
|
|
-
|
|
|
- // 计算新的位置(按address优先、layer其次的顺序)
|
|
|
- availablePositions = calculateNextPositions(highAddressSALV, demandStackingSum, ccmNo, typeConfigId);
|
|
|
-
|
|
|
- // 验证生成的位置顺序
|
|
|
- if (!availablePositions.isEmpty()) {
|
|
|
- StringBuilder positionLog = new StringBuilder("生成的新位置顺序:");
|
|
|
- availablePositions.forEach(p ->
|
|
|
- positionLog.append(p.getLayer()).append(".").append(p.getAddress()).append(" → "));
|
|
|
- log.info(positionLog.substring(0, positionLog.length() - 4)); // 移除最后的" → "
|
|
|
- }
|
|
|
- if (availablePositions.isEmpty()) {
|
|
|
- log.info("无法计算出可用位置,起垛失败!heatNo={}", heatNo);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 处理每个位置
|
|
|
- int positionsToProcess = Math.min(demandStackingSum, availablePositions.size());
|
|
|
- log.info("需要处理{}个位置,实际可用{}个位置", demandStackingSum, positionsToProcess);
|
|
|
-
|
|
|
- for (int i = 0; i < positionsToProcess; i++) {
|
|
|
- StackingAndLoadingVehicles position = availablePositions.get(i);
|
|
|
-
|
|
|
- // 如果是计算出来的新位置,需要查询数据库获取完整信息
|
|
|
- if (position.getId() == null) {
|
|
|
- StackingAndLoadingVehicles dbPosition = stackingAndLoadingVehiclesMapper.selectOne(
|
|
|
- new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
- .eq("ccm_no", position.getCcmNo())
|
|
|
- .eq("address", position.getAddress())
|
|
|
- .eq("layer", position.getLayer())
|
|
|
- .eq("type_config_id", position.getTypeConfigId()));
|
|
|
-
|
|
|
- if (dbPosition == null) {
|
|
|
- // 如果数据库中不存在该位置,可能需要创建新记录
|
|
|
- log.info("创建新的堆垛容器位置:layer={}, address={}", position.getLayer(), position.getAddress());
|
|
|
- position.setCreateTime(new Date());
|
|
|
- position.setUpdateTime(new Date());
|
|
|
- stackingAndLoadingVehiclesMapper.insert(position);
|
|
|
- } else {
|
|
|
- position.setId(dbPosition.getId());
|
|
|
- position.setCreateTime(dbPosition.getCreateTime());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 设置位置属性
|
|
|
- position.setSize(size);
|
|
|
- position.setShift(shift);
|
|
|
- position.setShiftGroup(shiftGroup);
|
|
|
- position.setHeatNo(heatNo);
|
|
|
- position.setUpdateTime(new Date());
|
|
|
- position.setSteel("");
|
|
|
- position.setSpec("");
|
|
|
- position.setBilletNos(generateBilletNos(heatNo, ccmNo)); // 生成带序号的钢坯编号
|
|
|
-
|
|
|
- try {
|
|
|
- // 更新位置信息
|
|
|
- stackingAndLoadingVehiclesMapper.updateById(position);
|
|
|
- log.info("成功更新堆垛容器位置:layer={}, address={}, id={}",
|
|
|
- position.getLayer(), position.getAddress(), position.getId());
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("更新堆垛容器位置失败:layer={}, address={}",
|
|
|
- position.getLayer(), position.getAddress(), e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * 编辑
|
|
|
- *
|
|
|
- * @param billetOriginalProductRecord
|
|
|
- * @return
|
|
|
- */
|
|
|
- @AutoLog(value = "确认钢坯生成原始记录")
|
|
|
- @ApiOperation(value="确认钢坯生成原始记录", notes="确认钢坯生成原始记录")
|
|
|
- @RequestMapping(value = "/confirmRecord", method = {RequestMethod.PUT})
|
|
|
- public Result<String> confirmRecord(@RequestBody BilletOriginalProductRecord billetOriginalProductRecord) {
|
|
|
- BilletOriginalProductRecord bopr = billetOriginalProductRecordService.getById(billetOriginalProductRecord.getId());
|
|
|
- if(bopr == null) {
|
|
|
- return Result.error("未找到对应数据,编辑失败!");
|
|
|
- }
|
|
|
- LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
- applyConfirmInfo(billetOriginalProductRecord, sysUser);
|
|
|
- billetOriginalProductRecordService.updateById(billetOriginalProductRecord);
|
|
|
-
|
|
|
- return Result.OK("确认成功!");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 推钢室快速创建装运单
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- */
|
|
|
- @AutoLog(value = "推钢室快速创建装运单")
|
|
|
- @ApiOperation(value="推钢室快速创建装运单", notes="推钢室快速创建装运单")
|
|
|
- @RequestMapping(value = "/addStorageBill", method = {RequestMethod.PUT})
|
|
|
- public Result<String> addStorageBillHandle(@RequestParam(name="ccmNo",required = false) String ccmNo,
|
|
|
- @RequestParam(name="positionNum",required = true) Integer positionNum,
|
|
|
- @RequestParam(name="licensePlate",required = true) String licensePlate) {
|
|
|
- // 参数验证
|
|
|
- if (positionNum == 2 && StringUtils.isEmpty(ccmNo)) {
|
|
|
- return Result.error("车位2铸机号不能为空!");
|
|
|
- }
|
|
|
-
|
|
|
- StorageBill storageBill = new StorageBill();
|
|
|
- storageBill.setId(String.valueOf(IdWorker.getId()));
|
|
|
- // 确定最终的ccmNo
|
|
|
- String finalCcmNo;
|
|
|
- if (positionNum == 1) {
|
|
|
- finalCcmNo = "5";
|
|
|
- } else if (positionNum == 2) {
|
|
|
- finalCcmNo = ccmNo;
|
|
|
- } else if (positionNum == 3 || positionNum == 4) {
|
|
|
- finalCcmNo = "6";
|
|
|
- } else {
|
|
|
- return Result.error("无效的车位号!");
|
|
|
- }
|
|
|
- storageBill.setCcmNo(finalCcmNo);
|
|
|
- // 从 Redis 获取班次信息
|
|
|
- String shiftGroup = getShiftInfo(storageBill.getCcmNo(), "class:shift:group:%s");
|
|
|
- String shift = getShiftInfo(storageBill.getCcmNo(), "class:shift:%s");
|
|
|
- // 空值检查
|
|
|
- if (shiftGroup == null || shift == null) {
|
|
|
- return Result.error("班组、班别不存在,创建失败!");
|
|
|
- }
|
|
|
- // 判断车牌号是否存在未发车的装运单信息
|
|
|
- LambdaQueryWrapper<StorageBill> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(StorageBill::getLicensePlate, licensePlate)
|
|
|
- .eq(StorageBill::getShiftGroup, shiftGroup)
|
|
|
- .eq(StorageBill::getShift, shift)
|
|
|
- .isNull(StorageBill::getOutTime);
|
|
|
- StorageBill isStorageBill = storageBillService.getOne(queryWrapper);
|
|
|
- if (oConvertUtils.isNotEmpty(isStorageBill)) {
|
|
|
- log.info("推钢室查询到存在未发车车辆,车牌号为:{},新增钢坯装运单失败!", storageBill.getLicensePlate());
|
|
|
- return Result.error("该车存在未发车信息,创建失败!");
|
|
|
- }
|
|
|
- // 判断车位是否存在未发车车辆(2025/3.3,半自动化逻辑,等自动化发车车位发车完善后,在添加此段逻辑)
|
|
|
- List<StorageBill> storageBillList = storageBillService.list(new LambdaQueryWrapper<StorageBill>()
|
|
|
- .eq(StorageBill::getPositionNum, positionNum)
|
|
|
- .isNull(StorageBill::getOutTime));
|
|
|
- if (oConvertUtils.listIsNotEmpty(storageBillList)){
|
|
|
- log.info("{}{}", "推钢室该车位存在未发车信息,新增钢坯装运单失败!", JSON.toJSON(storageBillList));
|
|
|
- return Result.error("该车位存在未发车信息,创建失败!");
|
|
|
- }
|
|
|
-
|
|
|
- // 根据铸机号、班组、班别,创建时间倒序 只返回一条,查询储运配置信息
|
|
|
- LambdaQueryWrapper<ShiftConfiguration> queryWrapper1 = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper1.eq(ShiftConfiguration::getCcmNo, storageBill.getCcmNo())
|
|
|
- .eq(ShiftConfiguration::getShiftGroup, shiftGroup)
|
|
|
- .eq(ShiftConfiguration::getShift, shift)
|
|
|
- .orderByDesc(ShiftConfiguration::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- ShiftConfiguration shiftConfiguration = shiftConfigurationService.getOne(queryWrapper1);
|
|
|
- if (shiftConfiguration != null && oConvertUtils.isNotEmpty(shiftConfiguration.getDestination())){
|
|
|
- storageBill.setBrandNum(shiftConfiguration.getSteelGrade());//牌号
|
|
|
- storageBill.setNewOldPlatform(shiftConfiguration.getNewOldPlatform());
|
|
|
- storageBill.setTypeConfigId("1024");
|
|
|
- }else {
|
|
|
- // C端自动化创建装运单时,默认未知目的地
|
|
|
- storageBill.setTypeConfigId("1024");
|
|
|
- }
|
|
|
-
|
|
|
- storageBill.setArrivalTime(new Date());// 到达时间
|
|
|
- // 更新交班记录 通过铸机号、班组、班别去查询交班记录并初始化 出车号
|
|
|
- updateBilletHotsendChangeShift(storageBill.getCcmNo(), shiftGroup, shift);
|
|
|
- storageBill.setPositionNum(positionNum);
|
|
|
- storageBill.setLicensePlate(licensePlate);
|
|
|
- storageBill.setAmountTotal(0);
|
|
|
- storageBill.setPanelAmountTotal(0);
|
|
|
- storageBill.setShiftGroup(shiftGroup);
|
|
|
- storageBill.setShift(shift);
|
|
|
- String uniqueCode = generateUniqueCode(new Date(), storageBill.getCcmNo(), shift, shiftGroup);
|
|
|
- storageBill.setUniqueCode(uniqueCode);
|
|
|
- storageBill.setLicensePlateStatus(0);
|
|
|
- storageBill.setCarNum(0); // 本车车次
|
|
|
- storageBill.setCarAllNum(0); // 总车车次
|
|
|
- storageBill.setBtype("0");
|
|
|
- storageBillService.save(storageBill);
|
|
|
-
|
|
|
- return Result.OK("创建成功!");
|
|
|
- }
|
|
|
-
|
|
|
+ /**
|
|
|
+ * 处理编辑操作中的公共逻辑
|
|
|
+ */
|
|
|
+ private void processCommonEditLogic(BilletOriginalProductRecord bopr, BilletOriginalProductRecord newRecord, boolean hotChargeLengthUpdated) {
|
|
|
+ // 复制所有非空字段(忽略ID和流支数字段)
|
|
|
+ String[] ignoreProperties = {"id", "oneStrandSum", "twoStrandSum", "threeStrandSum",
|
|
|
+ "fourStrandSum", "fiveStrandSum", "sixStrandSum",
|
|
|
+ "sevenStrandSum", "eightStrandSum", "amount"};
|
|
|
+ BeanUtils.copyProperties(newRecord, bopr, ignoreProperties);
|
|
|
+
|
|
|
+ // 如果更新了hotChargeLength,设置is_edit_charge为2
|
|
|
+ if (hotChargeLengthUpdated) {
|
|
|
+ bopr.setIsEditCharge("2");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 判断stackInfo字段是否为非空,不为空代表需要起垛
|
|
|
+ if (oConvertUtils.isNotEmpty(bopr.getStackInfo())) {
|
|
|
+ String str = bopr.getStackInfo();
|
|
|
+ String[] parts = str.split("-");
|
|
|
+ // 起垛的数量
|
|
|
+ int stackingSum = Integer.parseInt(parts[0]);
|
|
|
+ // 定尺
|
|
|
+ String size = parts[1];
|
|
|
+ String typeConfigId = parts[2];
|
|
|
+ // 根据炉号清空已起垛数据
|
|
|
+ clearStackByHeatNo(bopr.getCcmNo(), bopr.getHeatNo(), size, typeConfigId);
|
|
|
+ // 根据炉号、数量进行起垛
|
|
|
+ handleAddStack(bopr.getCcmNo(), bopr.getHeatNo(), stackingSum, size, typeConfigId);
|
|
|
+ // 备注stackInfo字段重置
|
|
|
+ bopr.setStackInfo("");
|
|
|
+ }
|
|
|
+ // 保存修改
|
|
|
+ billetOriginalProductRecordService.updateById(bopr);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 清空指定炉已经起垛的 数据
|
|
|
+ * @param ccmNo
|
|
|
+ * @param heatNo
|
|
|
+ * @param typeConfigId
|
|
|
+ */
|
|
|
+ private void clearStackByHeatNo(String ccmNo, String heatNo, String size, String typeConfigId) {
|
|
|
+ if (oConvertUtils.isEmpty(ccmNo) || oConvertUtils.isEmpty(heatNo) || oConvertUtils.isEmpty(typeConfigId) || oConvertUtils.isEmpty(size)){
|
|
|
+ log.info("{}{}", "清空指定炉已经起垛的数据时参数为空:", ccmNo + ">|<" + heatNo + ">|<" + size + ">|<" + typeConfigId);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 根据ccmNo、heatNo、typeConfigId查询出已经起垛的记录
|
|
|
+ LambdaQueryWrapper<StackingAndLoadingVehicles> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(StackingAndLoadingVehicles::getCcmNo, ccmNo)
|
|
|
+ .eq(StackingAndLoadingVehicles::getHeatNo, heatNo)
|
|
|
+ .eq(StackingAndLoadingVehicles::getSize, size)
|
|
|
+ .eq(StackingAndLoadingVehicles::getTypeConfigId, typeConfigId);
|
|
|
+ List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList = stackingAndLoadingVehiclesMapper.selectList(queryWrapper);
|
|
|
+ if (oConvertUtils.listIsEmpty(stackingAndLoadingVehiclesList)){
|
|
|
+ log.info("{}{}", "该炉没有需要清空的堆垛信息:", heatNo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<String> ids = stackingAndLoadingVehiclesList.stream().map(StackingAndLoadingVehicles::getId).collect(Collectors.toList());
|
|
|
+ // 创建更新包装器
|
|
|
+ LambdaUpdateWrapper<StackingAndLoadingVehicles> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ updateWrapper.in(StackingAndLoadingVehicles::getId, ids)
|
|
|
+ .set(StackingAndLoadingVehicles::getBilletNos, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getSpec, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getSteel, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getSize, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getShift, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getHeatNo, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getCreateDate, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getShiftGroup, null)
|
|
|
+ .set(StackingAndLoadingVehicles::getUpdateTime, new Date());
|
|
|
+ // 执行批量更新
|
|
|
+ stackingAndLoadingVehiclesMapper.update(null, updateWrapper);
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * 处理起垛
|
|
|
+ * @param ccmNo
|
|
|
+ * @param heatNo
|
|
|
+ * @param stackingSum
|
|
|
+ * @param size
|
|
|
+ * @param typeConfigId
|
|
|
+ */
|
|
|
+ private void handleAddStack(String ccmNo, String heatNo, int stackingSum, String size, String typeConfigId) {
|
|
|
+ // 获取班次信息
|
|
|
+ String classShiftGroup = String.format("class:shift:group:%s", ccmNo);
|
|
|
+ String classShift = String.format("class:shift:%s", ccmNo);
|
|
|
+ String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ?
|
|
|
+ oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
+ String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ?
|
|
|
+ oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
+
|
|
|
+ // 计算需要起垛的数量
|
|
|
+ int demandStackingSum = stackingSum / 4;
|
|
|
+ if (demandStackingSum <= 0) {
|
|
|
+ log.info("起垛数量计算结果为非正数,起垛失败!heatNo={}, stackingSum={}", heatNo, stackingSum);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询所有可能的位置,并按layer和address排序(低layer优先,address从1到9)
|
|
|
+ List<StackingAndLoadingVehicles> allPositions = stackingAndLoadingVehiclesMapper.selectList(
|
|
|
+ new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
+ .eq("ccm_no", ccmNo)
|
|
|
+ .eq("type_config_id", typeConfigId));
|
|
|
+
|
|
|
+ if (allPositions != null) {
|
|
|
+ allPositions.sort(Comparator.comparing(StackingAndLoadingVehicles::getLayer,
|
|
|
+ Comparator.comparingInt(Integer::parseInt))
|
|
|
+ .thenComparing(StackingAndLoadingVehicles::getAddress,
|
|
|
+ Comparator.comparingInt(Integer::parseInt)));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取所有可用的空位置(按排序后的顺序)
|
|
|
+ List<StackingAndLoadingVehicles> availablePositions = allPositions.stream()
|
|
|
+ .filter(v -> oConvertUtils.isEmpty(v.getBilletNos()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 如果没有可用的空位置,则尝试计算新位置
|
|
|
+ if (availablePositions.isEmpty()) {
|
|
|
+ // 获取最高占用层
|
|
|
+ StackingAndLoadingVehicles highAddressSALV = getHighestOccupiedLayer(allPositions);
|
|
|
+
|
|
|
+ // 如果没有任何占用层,从1.1开始
|
|
|
+ if (highAddressSALV == null) {
|
|
|
+ highAddressSALV = new StackingAndLoadingVehicles();
|
|
|
+ highAddressSALV.setAddress("1");
|
|
|
+ highAddressSALV.setLayer("1");
|
|
|
+ highAddressSALV.setCcmNo(ccmNo);
|
|
|
+ highAddressSALV.setTypeConfigId(typeConfigId);
|
|
|
+ } else {
|
|
|
+ log.info("最高占用层位置:{}.{}", highAddressSALV.getLayer(), highAddressSALV.getAddress());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算新的位置(按address优先、layer其次的顺序)
|
|
|
+ availablePositions = calculateNextPositions(highAddressSALV, demandStackingSum, ccmNo, typeConfigId);
|
|
|
+
|
|
|
+ // 验证生成的位置顺序
|
|
|
+ if (!availablePositions.isEmpty()) {
|
|
|
+ StringBuilder positionLog = new StringBuilder("生成的新位置顺序:");
|
|
|
+ availablePositions.forEach(p ->
|
|
|
+ positionLog.append(p.getLayer()).append(".").append(p.getAddress()).append(" → "));
|
|
|
+ log.info(positionLog.substring(0, positionLog.length() - 4)); // 移除最后的" → "
|
|
|
+ }
|
|
|
+ if (availablePositions.isEmpty()) {
|
|
|
+ log.info("无法计算出可用位置,起垛失败!heatNo={}", heatNo);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理每个位置
|
|
|
+ int positionsToProcess = Math.min(demandStackingSum, availablePositions.size());
|
|
|
+ log.info("需要处理{}个位置,实际可用{}个位置", demandStackingSum, positionsToProcess);
|
|
|
+
|
|
|
+ for (int i = 0; i < positionsToProcess; i++) {
|
|
|
+ StackingAndLoadingVehicles position = availablePositions.get(i);
|
|
|
+
|
|
|
+ // 如果是计算出来的新位置,需要查询数据库获取完整信息
|
|
|
+ if (position.getId() == null) {
|
|
|
+ StackingAndLoadingVehicles dbPosition = stackingAndLoadingVehiclesMapper.selectOne(
|
|
|
+ new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
+ .eq("ccm_no", position.getCcmNo())
|
|
|
+ .eq("address", position.getAddress())
|
|
|
+ .eq("layer", position.getLayer())
|
|
|
+ .eq("type_config_id", position.getTypeConfigId()));
|
|
|
+
|
|
|
+ if (dbPosition == null) {
|
|
|
+ // 如果数据库中不存在该位置,可能需要创建新记录
|
|
|
+ log.info("创建新的堆垛容器位置:layer={}, address={}", position.getLayer(), position.getAddress());
|
|
|
+ position.setCreateTime(new Date());
|
|
|
+ position.setUpdateTime(new Date());
|
|
|
+ stackingAndLoadingVehiclesMapper.insert(position);
|
|
|
+ } else {
|
|
|
+ position.setId(dbPosition.getId());
|
|
|
+ position.setCreateTime(dbPosition.getCreateTime());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置位置属性
|
|
|
+ position.setSize(size);
|
|
|
+ position.setShift(shift);
|
|
|
+ position.setShiftGroup(shiftGroup);
|
|
|
+ position.setHeatNo(heatNo);
|
|
|
+ position.setUpdateTime(new Date());
|
|
|
+ position.setSteel("");
|
|
|
+ position.setSpec("");
|
|
|
+ position.setBilletNos(generateBilletNos(heatNo, ccmNo)); // 生成带序号的钢坯编号
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 更新位置信息
|
|
|
+ stackingAndLoadingVehiclesMapper.updateById(position);
|
|
|
+ log.info("成功更新堆垛容器位置:layer={}, address={}, id={}",
|
|
|
+ position.getLayer(), position.getAddress(), position.getId());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新堆垛容器位置失败:layer={}, address={}",
|
|
|
+ position.getLayer(), position.getAddress(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 编辑
|
|
|
+ *
|
|
|
+ * @param billetOriginalProductRecord
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @AutoLog(value = "确认钢坯生成原始记录")
|
|
|
+ @ApiOperation(value="确认钢坯生成原始记录", notes="确认钢坯生成原始记录")
|
|
|
+ @RequestMapping(value = "/confirmRecord", method = {RequestMethod.PUT})
|
|
|
+ public Result<String> confirmRecord(@RequestBody BilletOriginalProductRecord billetOriginalProductRecord) {
|
|
|
+ BilletOriginalProductRecord bopr = billetOriginalProductRecordService.getById(billetOriginalProductRecord.getId());
|
|
|
+ if(bopr == null) {
|
|
|
+ return Result.error("未找到对应数据,编辑失败!");
|
|
|
+ }
|
|
|
+ LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
|
|
+ applyConfirmInfo(billetOriginalProductRecord, sysUser);
|
|
|
+ billetOriginalProductRecordService.updateById(billetOriginalProductRecord);
|
|
|
+
|
|
|
+ return Result.OK("确认成功!");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 推钢室快速创建装运单
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @AutoLog(value = "推钢室快速创建装运单")
|
|
|
+ @ApiOperation(value="推钢室快速创建装运单", notes="推钢室快速创建装运单")
|
|
|
+ @RequestMapping(value = "/addStorageBill", method = {RequestMethod.PUT})
|
|
|
+ public Result<String> addStorageBillHandle(@RequestParam(name="ccmNo",required = false) String ccmNo,
|
|
|
+ @RequestParam(name="positionNum",required = true) Integer positionNum,
|
|
|
+ @RequestParam(name="licensePlate",required = true) String licensePlate) {
|
|
|
+ // 参数验证
|
|
|
+ if (positionNum == 2 && StringUtils.isEmpty(ccmNo)) {
|
|
|
+ return Result.error("车位2铸机号不能为空!");
|
|
|
+ }
|
|
|
+
|
|
|
+ StorageBill storageBill = new StorageBill();
|
|
|
+ storageBill.setId(String.valueOf(IdWorker.getId()));
|
|
|
+ // 确定最终的ccmNo
|
|
|
+ String finalCcmNo;
|
|
|
+ if (positionNum == 1) {
|
|
|
+ finalCcmNo = "5";
|
|
|
+ } else if (positionNum == 2) {
|
|
|
+ finalCcmNo = ccmNo;
|
|
|
+ } else if (positionNum == 3 || positionNum == 4) {
|
|
|
+ finalCcmNo = "6";
|
|
|
+ } else {
|
|
|
+ return Result.error("无效的车位号!");
|
|
|
+ }
|
|
|
+ storageBill.setCcmNo(finalCcmNo);
|
|
|
+ // 从 Redis 获取班次信息
|
|
|
+ String shiftGroup = getShiftInfo(storageBill.getCcmNo(), "class:shift:group:%s");
|
|
|
+ String shift = getShiftInfo(storageBill.getCcmNo(), "class:shift:%s");
|
|
|
+ // 空值检查
|
|
|
+ if (shiftGroup == null || shift == null) {
|
|
|
+ return Result.error("班组、班别不存在,创建失败!");
|
|
|
+ }
|
|
|
+ // 判断车牌号是否存在未发车的装运单信息
|
|
|
+ LambdaQueryWrapper<StorageBill> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(StorageBill::getLicensePlate, licensePlate)
|
|
|
+ .eq(StorageBill::getShiftGroup, shiftGroup)
|
|
|
+ .eq(StorageBill::getShift, shift)
|
|
|
+ .isNull(StorageBill::getOutTime);
|
|
|
+ StorageBill isStorageBill = storageBillService.getOne(queryWrapper);
|
|
|
+ if (oConvertUtils.isNotEmpty(isStorageBill)) {
|
|
|
+ log.info("推钢室查询到存在未发车车辆,车牌号为:{},新增钢坯装运单失败!", storageBill.getLicensePlate());
|
|
|
+ return Result.error("该车存在未发车信息,创建失败!");
|
|
|
+ }
|
|
|
+ // 判断车位是否存在未发车车辆(2025/3.3,半自动化逻辑,等自动化发车车位发车完善后,在添加此段逻辑)
|
|
|
+ List<StorageBill> storageBillList = storageBillService.list(new LambdaQueryWrapper<StorageBill>()
|
|
|
+ .eq(StorageBill::getPositionNum, positionNum)
|
|
|
+ .isNull(StorageBill::getOutTime));
|
|
|
+ if (oConvertUtils.listIsNotEmpty(storageBillList)){
|
|
|
+ log.info("{}{}", "推钢室该车位存在未发车信息,新增钢坯装运单失败!", JSON.toJSON(storageBillList));
|
|
|
+ return Result.error("该车位存在未发车信息,创建失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据铸机号、班组、班别,创建时间倒序 只返回一条,查询储运配置信息
|
|
|
+ LambdaQueryWrapper<ShiftConfiguration> queryWrapper1 = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper1.eq(ShiftConfiguration::getCcmNo, storageBill.getCcmNo())
|
|
|
+ .eq(ShiftConfiguration::getShiftGroup, shiftGroup)
|
|
|
+ .eq(ShiftConfiguration::getShift, shift)
|
|
|
+ .orderByDesc(ShiftConfiguration::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+ ShiftConfiguration shiftConfiguration = shiftConfigurationService.getOne(queryWrapper1);
|
|
|
+ if (shiftConfiguration != null && oConvertUtils.isNotEmpty(shiftConfiguration.getDestination())){
|
|
|
+ storageBill.setBrandNum(shiftConfiguration.getSteelGrade());//牌号
|
|
|
+ storageBill.setNewOldPlatform(shiftConfiguration.getNewOldPlatform());
|
|
|
+ storageBill.setTypeConfigId("1024");
|
|
|
+ }else {
|
|
|
+ // C端自动化创建装运单时,默认未知目的地
|
|
|
+ storageBill.setTypeConfigId("1024");
|
|
|
+ }
|
|
|
+
|
|
|
+ storageBill.setArrivalTime(new Date());// 到达时间
|
|
|
+ // 更新交班记录 通过铸机号、班组、班别去查询交班记录并初始化 出车号
|
|
|
+ updateBilletHotsendChangeShift(storageBill.getCcmNo(), shiftGroup, shift);
|
|
|
+ storageBill.setPositionNum(positionNum);
|
|
|
+ storageBill.setLicensePlate(licensePlate);
|
|
|
+ storageBill.setAmountTotal(0);
|
|
|
+ storageBill.setPanelAmountTotal(0);
|
|
|
+ storageBill.setShiftGroup(shiftGroup);
|
|
|
+ storageBill.setShift(shift);
|
|
|
+ String uniqueCode = generateUniqueCode(new Date(), storageBill.getCcmNo(), shift, shiftGroup);
|
|
|
+ storageBill.setUniqueCode(uniqueCode);
|
|
|
+ storageBill.setLicensePlateStatus(0);
|
|
|
+ storageBill.setCarNum(0); // 本车车次
|
|
|
+ storageBill.setCarAllNum(0); // 总车车次
|
|
|
+ storageBill.setBtype("0");
|
|
|
+ storageBillService.save(storageBill);
|
|
|
+
|
|
|
+ return Result.OK("创建成功!");
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 通过id删除
|
|
|
*
|
|
@@ -524,7 +565,7 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
billetOriginalProductRecordService.removeById(id);
|
|
|
return Result.OK("删除成功!");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 批量删除
|
|
|
*
|
|
@@ -539,7 +580,7 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
this.billetOriginalProductRecordService.removeByIds(Arrays.asList(ids.split(",")));
|
|
|
return Result.OK("批量删除成功!");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* 通过id查询
|
|
|
*
|
|
@@ -557,1889 +598,1849 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
|
|
|
return Result.OK(billetOriginalProductRecord);
|
|
|
}
|
|
|
|
|
|
- /**
|
|
|
- * 导出excel
|
|
|
- *
|
|
|
- * @param request
|
|
|
- * @param billetOriginalProductRecord
|
|
|
- */
|
|
|
- @RequiresPermissions("billetOriginalProductRecord:billet_original_product_record:exportXls")
|
|
|
- @RequestMapping(value = "/exportXls")
|
|
|
- public ModelAndView exportXls(HttpServletRequest request, BilletOriginalProductRecord billetOriginalProductRecord) {
|
|
|
- return super.exportXls(request, billetOriginalProductRecord, BilletOriginalProductRecord.class, "钢坯生成原始记录");
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 通过excel导入数据
|
|
|
- *
|
|
|
- * @param request
|
|
|
- * @param response
|
|
|
- * @return
|
|
|
- */
|
|
|
- @RequiresPermissions("billetOriginalProductRecord:billet_original_product_record:importExcel")
|
|
|
- @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
|
|
- public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
|
|
- return super.importExcel(request, response, BilletOriginalProductRecord.class);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ApiOperation(value="钢坯原始生产记录查询", notes="钢坯原始生产记录查询")
|
|
|
- @GetMapping(value = "/queryBilletRecordByCcmNo")
|
|
|
- public Result<BilletOriginalProductRecordDetail> queryHeatsActualsByCcmNo(@RequestParam(name="ccmNo", required = false) String ccmNo,
|
|
|
- @RequestParam(name="changeShiftId", required = false) String changeShiftId,
|
|
|
- @RequestParam(name="queryType") String queryType) {
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecords = new ArrayList<>();
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
- if ("1".equals(queryType)){
|
|
|
- String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
- String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
- String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
- String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
-
|
|
|
- if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
- return Result.error("班组班别获取为空,钢坯原始生产记录查询失败!");
|
|
|
- }
|
|
|
- // 根据ccmNo、shift、shiftGroup查询最新的交班记录
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
- .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
- .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
- .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (billetHotsendChangeShift == null){
|
|
|
- log.info("{}{}", "钢坯原始生产记录,交班记录为空!", ccmNo + "失败时间:" + new Date());
|
|
|
- return Result.error("交班信息为空,钢坯原始生产记录查询失败!");
|
|
|
- }
|
|
|
- }else {
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getById(changeShiftId);
|
|
|
- }
|
|
|
- if (billetHotsendChangeShift == null) {
|
|
|
- log.error("未查询到有效的交班记录,无法继续处理");
|
|
|
- return Result.error("未找到对应的交班信息,原始生产记录获取失败!");
|
|
|
- }
|
|
|
- //1、 获取当班浇筑炉次详细信息
|
|
|
- List<HeatsActualsInfo> heatsActualsInfoList = queryCurrentHeatsActualsInfo(ccmNo, billetHotsendChangeShift.getShift(), billetHotsendChangeShift.getShiftGroup(), billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime(), queryType);
|
|
|
- if (oConvertUtils.listIsNotEmpty(heatsActualsInfoList)){
|
|
|
- log.info("原始生产记录,当班浇筑炉次数据信息: " + JSON.toJSON(heatsActualsInfoList));
|
|
|
- //2、把获取到的当班浇筑炉次信息heatsActualsInfoList保存到原始生产记录表
|
|
|
- heatsActualsInfoList.forEach(x -> {
|
|
|
- BilletOriginalProductRecord billetOriginalProductRecord = new BilletOriginalProductRecord();
|
|
|
- billetOriginalProductRecord.setId(String.valueOf(IdWorker.getId()));
|
|
|
- billetOriginalProductRecord.setCcmNo(ccmNo);
|
|
|
- billetOriginalProductRecord.setHeatNo(x.getHeatNo());
|
|
|
- billetOriginalProductRecord.setShift(x.getShift());
|
|
|
- billetOriginalProductRecord.setShiftGroup(x.getShiftGroup());
|
|
|
- billetOriginalProductRecord.setGrade(x.getBrandNum());
|
|
|
- billetOriginalProductRecord.setOneStrandSum(x.getOneSum());
|
|
|
- billetOriginalProductRecord.setTwoStrandSum(x.getTwoSum());
|
|
|
- billetOriginalProductRecord.setThreeStrandSum(x.getThreeSum());
|
|
|
- billetOriginalProductRecord.setFourStrandSum(x.getFourSum());
|
|
|
- billetOriginalProductRecord.setFiveStrandSum(x.getFiveSum());
|
|
|
- billetOriginalProductRecord.setSixStrandSum(x.getSixSum());
|
|
|
- billetOriginalProductRecord.setSevenStrandSum(x.getSevenSum());
|
|
|
- billetOriginalProductRecord.setEightStrandSum(x.getEightSum());
|
|
|
- billetOriginalProductRecord.setBrandNum(x.getBrandNum());
|
|
|
- String totalInfoJson = x.getTotalInfo();
|
|
|
- if (oConvertUtils.isEmpty(totalInfoJson)){
|
|
|
- billetOriginalProductRecord.setAmount(0);// 合计
|
|
|
- }else {
|
|
|
- JSONObject json = JSON.parseObject(totalInfoJson);
|
|
|
- Integer totalCount = json.getInteger("totalCount");
|
|
|
- billetOriginalProductRecord.setAmount(totalCount);// 合计
|
|
|
- }
|
|
|
- billetOriginalProductRecord.setRollClubOneDetails(x.getDirectRolling());// 直轧热送棒一
|
|
|
- billetOriginalProductRecord.setHotChargeLength(x.getHotCharge());
|
|
|
- billetOriginalProductRecord.setStackLength(x.getStacking());
|
|
|
- billetOriginalProductRecord.setLengthDetails(x.getLength());
|
|
|
- billetOriginalProductRecord.setCreateTime(DateUtils.str2Date(x.getCreateTime(), DateUtils.datetimeFormat.get()));
|
|
|
- billetOriginalProductRecord.setDeliveryTime(DateUtils.str2Date(x.getCreateTime(), DateUtils.datetimeFormat.get()));
|
|
|
- billetOriginalProductRecord.setIsEditCharge("1");
|
|
|
- billetOriginalProductRecords.add(billetOriginalProductRecord);
|
|
|
- });
|
|
|
- log.info("钢坯原始生产记录信息: " + JSON.toJSON(billetOriginalProductRecords));
|
|
|
-
|
|
|
- // 在批量保存前,过滤掉已存在的炉号记录
|
|
|
- List<BilletOriginalProductRecord> finalRecords = billetOriginalProductRecords.stream()
|
|
|
- .filter(record -> {
|
|
|
- // 使用 getOne 方法检查是否存在相同记录(铸机号、炉号、班次、班组均相同)
|
|
|
- LambdaQueryWrapper<BilletOriginalProductRecord> checkWrapper = new LambdaQueryWrapper<>();
|
|
|
- checkWrapper.eq(BilletOriginalProductRecord::getCcmNo, record.getCcmNo())
|
|
|
- .eq(BilletOriginalProductRecord::getHeatNo, record.getHeatNo())
|
|
|
- .eq(BilletOriginalProductRecord::getShift, record.getShift())
|
|
|
- .eq(BilletOriginalProductRecord::getShiftGroup, record.getShiftGroup())
|
|
|
- .last("LIMIT 1"); // 只查询一条记录,提高性能
|
|
|
- // 如果 getOne 结果为 null,表示记录不存在,保留该记录
|
|
|
- return billetOriginalProductRecordService.getOne(checkWrapper, false) == null;
|
|
|
- }).collect(Collectors.toList());
|
|
|
- if(oConvertUtils.listIsNotEmpty(finalRecords)){
|
|
|
- try {
|
|
|
- // 批量保存
|
|
|
- billetOriginalProductRecordService.saveBatch(finalRecords);
|
|
|
- } catch (DuplicateKeyException e) {
|
|
|
- log.error("炉号重复插入:{}", JSON.toJSONString(billetOriginalProductRecords), e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- QueryWrapper<BilletOriginalProductRecord> queryWrapper3 = new QueryWrapper<>();
|
|
|
- queryWrapper3.eq("ccm_no", ccmNo)
|
|
|
- .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
- .eq("shift_group", billetHotsendChangeShift.getShiftGroup());
|
|
|
- if ("1".equals(queryType)){
|
|
|
- queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), new Date());
|
|
|
- }else {
|
|
|
- queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime());
|
|
|
- }
|
|
|
- // 通过铸机号、班组、班别、交班开始时间 查询钢坯生产原始记录
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper3);
|
|
|
- BilletOriginalProductRecordDetail billetOriginalProductRecordDetails = new BilletOriginalProductRecordDetail();
|
|
|
- billetOriginalProductRecordDetails.setBilletOriginalProductRecordList(billetOriginalProductRecordList);
|
|
|
- billetOriginalProductRecordDetails.setSizeInfo(billetHotsendChangeShift.getSizeInfo());
|
|
|
- billetOriginalProductRecordDetails.setContent(billetHotsendChangeShift.getContent());
|
|
|
- billetOriginalProductRecordDetails.setConfirmStatus(billetHotsendChangeShift.getConfirmStatus());
|
|
|
- return Result.OK(billetOriginalProductRecordDetails);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ApiOperation("送样卡获取定尺支数明细表")
|
|
|
- @GetMapping("/lengthDetailsTable")
|
|
|
- public Result<List<LengthCountVO>> getLengthDetailsTable(LengthCountQueryDTO queryDTO) {
|
|
|
- if (queryDTO == null || StringUtils.isBlank(queryDTO.getCcmNo())) {
|
|
|
- return Result.error("参数不能为空");
|
|
|
- }
|
|
|
-
|
|
|
- String shift = "";
|
|
|
- String shiftGroup = "";
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
-
|
|
|
- if (oConvertUtils.isEmpty(queryDTO.getChangeShiftId())) {
|
|
|
- String classShiftGroup = String.format("class:shift:group:%s", queryDTO.getCcmNo());
|
|
|
- String classShift = String.format("class:shift:%s", queryDTO.getCcmNo());
|
|
|
- shift = oConvertUtils.getString(redisTemplate.opsForValue().get(classShift), "");
|
|
|
- shiftGroup = oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup), "");
|
|
|
-
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo())
|
|
|
- .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
- .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
-
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (billetHotsendChangeShift == null) {
|
|
|
- log.info("查询班次信息失败,交班记录为空!失败时间:{}", new Date());
|
|
|
- return Result.OK(Collections.emptyList());
|
|
|
- }
|
|
|
- } else {
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getId, queryDTO.getChangeShiftId())
|
|
|
- .eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo());
|
|
|
-
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (billetHotsendChangeShift == null) {
|
|
|
- log.info("查询班次信息失败,交班记录为空!失败时间:{}", new Date());
|
|
|
- return Result.OK(Collections.emptyList());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endTime = billetHotsendChangeShift.getChangeShiftTime() != null
|
|
|
- ? billetHotsendChangeShift.getChangeShiftTime()
|
|
|
- : new Date();
|
|
|
-
|
|
|
- QueryWrapper<BilletOriginalProductRecord> queryWrapperB = new QueryWrapper<>();
|
|
|
- queryWrapperB.eq("ccm_no", queryDTO.getCcmNo())
|
|
|
- .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
- .eq("shift_group", billetHotsendChangeShift.getShiftGroup())
|
|
|
- .ge("create_time", startTime)
|
|
|
- .le("create_time", endTime)
|
|
|
- .orderByAsc("create_time");
|
|
|
-
|
|
|
- List<BilletOriginalProductRecord> records = billetOriginalProductRecordService.list(queryWrapperB);
|
|
|
-
|
|
|
- List<LengthCountVO> resultList = new ArrayList<>();
|
|
|
- Set<String> allLengths = new TreeSet<>();
|
|
|
- ObjectMapper objectMapper = new ObjectMapper();
|
|
|
-
|
|
|
- for (BilletOriginalProductRecord record : records) {
|
|
|
- LengthCountVO vo = new LengthCountVO();
|
|
|
- vo.setHeatNo(record.getHeatNo());
|
|
|
-
|
|
|
- String brandNum = Optional.ofNullable(record.getGrade())
|
|
|
- .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
- .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
- vo.setBrandNum(brandNum);
|
|
|
-
|
|
|
- Map<String, Integer> mergedLengthCount = new HashMap<>();
|
|
|
-
|
|
|
- // 解析 rollClubOneDetails 的 lengthGroupCount
|
|
|
- String rollClubOneDetailsJson = record.getRollClubOneDetails();
|
|
|
- if (StringUtils.isNotBlank(rollClubOneDetailsJson)) {
|
|
|
- try {
|
|
|
- JsonNode rollDetails = objectMapper.readTree(rollClubOneDetailsJson);
|
|
|
- JsonNode lengthGroupCount = rollDetails.path("lengthGroupCount");
|
|
|
- if (lengthGroupCount.isObject()) {
|
|
|
- for (Iterator<Map.Entry<String, JsonNode>> it = lengthGroupCount.fields(); it.hasNext(); ) {
|
|
|
- Map.Entry<String, JsonNode> entry = it.next();
|
|
|
- String mm = entry.getKey();
|
|
|
- int count = entry.getValue().asInt(0);
|
|
|
- mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("解析 rollClubOneDetails 失败: {}, 内容: {}", record.getHeatNo(), rollClubOneDetailsJson, e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 解析 hotChargeLength 数组
|
|
|
- String hotChargeLengthJson = record.getHotChargeLength();
|
|
|
- if (StringUtils.isNotBlank(hotChargeLengthJson)) {
|
|
|
- try {
|
|
|
- JsonNode hotArray = objectMapper.readTree(hotChargeLengthJson);
|
|
|
- if (hotArray.isArray()) {
|
|
|
- for (JsonNode node : hotArray) {
|
|
|
- String mm = node.path("hotChargeLength").asText();
|
|
|
- int count = node.path("totalCount").asInt(0);
|
|
|
- mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("解析 hotChargeLength 失败: {}, 内容: {}", record.getHeatNo(), hotChargeLengthJson, e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 解析 stackLength 数组
|
|
|
- String stackLengthJson = record.getStackLength();
|
|
|
- if (StringUtils.isNotBlank(stackLengthJson)) {
|
|
|
- try {
|
|
|
- JsonNode stackArray = objectMapper.readTree(stackLengthJson);
|
|
|
- if (stackArray.isArray()) {
|
|
|
- for (JsonNode node : stackArray) {
|
|
|
- String mm = node.path("stackingLength").asText();
|
|
|
- int count = node.path("stackingCount").asInt(0);
|
|
|
- mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("解析 stackLength 失败: {}, 内容: {}", record.getHeatNo(), stackLengthJson, e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 转换 mm 为 m(两位小数),组装 vo
|
|
|
- for (Map.Entry<String, Integer> entry : mergedLengthCount.entrySet()) {
|
|
|
- String mmStr = entry.getKey();
|
|
|
- int count = entry.getValue();
|
|
|
- String mStr;
|
|
|
- try {
|
|
|
- BigDecimal mm = new BigDecimal(mmStr);
|
|
|
- mStr = mm.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP).toString();
|
|
|
- } catch (Exception e) {
|
|
|
- mStr = mmStr;
|
|
|
- }
|
|
|
- vo.getLengthCountMap().put(mStr, count);
|
|
|
- allLengths.add(mStr);
|
|
|
- }
|
|
|
-
|
|
|
- resultList.add(vo);
|
|
|
- }
|
|
|
-
|
|
|
- // 补齐所有定尺列(不存在的补0)
|
|
|
- for (LengthCountVO vo : resultList) {
|
|
|
- for (String length : allLengths) {
|
|
|
- vo.getLengthCountMap().putIfAbsent(length, 0);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return Result.OK(resultList);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ApiOperation("质检记录定尺明细(用于菜单)")
|
|
|
- @GetMapping("/qualityInspectionMenu")
|
|
|
- public Result<Map<String, Object>> getQualityInspectionMenu(QualityInspectionQueryDTO queryDTO) {
|
|
|
-
|
|
|
- Map<String, Object> result = billetOriginalProductRecordService.getQualityInspectionMenu(queryDTO);
|
|
|
- return Result.OK(result);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 修改部分质检信息
|
|
|
- *
|
|
|
- * @param
|
|
|
- * @return
|
|
|
- */
|
|
|
- @AutoLog(value = "修改部分质检信息")
|
|
|
- @ApiOperation(value="修改部分质检信息", notes="修改部分质检信息")
|
|
|
- @PutMapping(value = "/updateInfo")
|
|
|
- public Result<String> updateInfo(@RequestBody BilletOriginalProductRecordEditDTO editDTO) {
|
|
|
- BilletOriginalProductRecord byId = billetOriginalProductRecordService.getById(editDTO.getOriginalProductRecordId());
|
|
|
- if (byId == null) {
|
|
|
- return Result.error("未找到对应数据,编辑失败!");
|
|
|
- }
|
|
|
-
|
|
|
- if (oConvertUtils.isEmpty(editDTO.getOriginalProductRecordId())) {
|
|
|
- return Result.error("原始记录id不能为空!");
|
|
|
- }
|
|
|
-
|
|
|
- // 使用 UpdateWrapper 只更新指定字段
|
|
|
- UpdateWrapper<BilletOriginalProductRecord> updateWrapper = new UpdateWrapper<>();
|
|
|
- updateWrapper.eq("id", editDTO.getOriginalProductRecordId());
|
|
|
-
|
|
|
- if (StringUtils.isNotBlank(editDTO.getBrandNum())) {
|
|
|
- updateWrapper.set("brand_num", editDTO.getBrandNum());
|
|
|
- }
|
|
|
- if (editDTO.getDeliveryTime() != null) {
|
|
|
- updateWrapper.set("delivery_time", editDTO.getDeliveryTime());
|
|
|
- }
|
|
|
- if (StringUtils.isNotBlank(editDTO.getNotes())) {
|
|
|
- updateWrapper.set("notes", editDTO.getNotes());
|
|
|
- }
|
|
|
-
|
|
|
- billetOriginalProductRecordService.update(updateWrapper);
|
|
|
-
|
|
|
- return Result.OK("编辑成功!");
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取当前班次下所有炉次浇筑数据
|
|
|
- * @param ccmNo
|
|
|
- * @param shift
|
|
|
- * @param shiftGroup
|
|
|
- * @return
|
|
|
- */
|
|
|
- private List<HeatsActualsInfo> queryCurrentHeatsActualsInfo(String ccmNo, String shift, String shiftGroup, Date shiftStartTime, Date shiftEndTime, String queryType) {
|
|
|
- List<HeatsActualsInfo> heatsActualsInfoList = new ArrayList<>();
|
|
|
- //根据ccmNo、shift、shiftGroup、大于billetHotsendChangeShift的创建时间 查询所有炉次传递单BilletHotsend
|
|
|
- LambdaQueryWrapper<BilletHotsend> queryWrapper1 = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper1.eq(BilletHotsend::getCcmNo, ccmNo)
|
|
|
- .eq(BilletHotsend::getShift, shift)
|
|
|
- .eq(BilletHotsend::getShiftGroup, shiftGroup);
|
|
|
- if ("1".equals(queryType)){
|
|
|
- queryWrapper1.between(BilletHotsend::getCreateTime, shiftStartTime, new Date());
|
|
|
- }else {
|
|
|
- queryWrapper1.between(BilletHotsend::getCreateTime, shiftStartTime, shiftEndTime);
|
|
|
- }
|
|
|
- queryWrapper1.orderByDesc(BilletHotsend::getCreateTime);
|
|
|
- List<BilletHotsend> billetHotsendList = billetHotsendBaseService.list(queryWrapper1);
|
|
|
- if (oConvertUtils.listIsEmpty(billetHotsendList)){
|
|
|
- log.info("{}{}", "钢坯原始生产记录查询失败,炉次传递单为空!", ccmNo + "失败时间:" + new Date());
|
|
|
- return heatsActualsInfoList;
|
|
|
- }
|
|
|
- List<String> distinctHeatNoList = billetHotsendList.stream()
|
|
|
- .map(BilletHotsend::getHeatNo) // 提取炉号
|
|
|
- .filter(Objects::nonNull) // 过滤可能的 null 值
|
|
|
- .distinct() // 去重
|
|
|
- .collect(Collectors.toList()); // 转为列表
|
|
|
- List<BilletHotsend> filteredBilletHotsendList = new ArrayList<>();
|
|
|
- // 根据铸机号、班别、班别、炉号查询钢坯原始生产记录
|
|
|
- QueryWrapper<BilletOriginalProductRecord> queryWrapper8 = new QueryWrapper<>();
|
|
|
- queryWrapper8.eq("ccm_no", ccmNo)
|
|
|
- .eq("shift", shift)
|
|
|
- .eq("shift_group", shiftGroup)
|
|
|
- .in("heat_no", distinctHeatNoList)
|
|
|
- .orderByDesc("create_time");
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper8);
|
|
|
- if (oConvertUtils.listIsNotEmpty(billetOriginalProductRecordList)){
|
|
|
- List<String> distinctOriginalProductRecordHeatNoList = billetOriginalProductRecordList.stream()
|
|
|
- .map(BilletOriginalProductRecord::getHeatNo) // 提取炉号
|
|
|
- .filter(Objects::nonNull) // 过滤可能的 null 值
|
|
|
- .distinct() // 去重
|
|
|
- .collect(Collectors.toList()); // 转为列表
|
|
|
- // 2. 将炉号列表转换为 Set 以提高查询效率
|
|
|
- Set<String> excludeHeatNos = new HashSet<>(distinctOriginalProductRecordHeatNoList);
|
|
|
- // 3. 过滤 billetHotsendList,保留炉号不在 excludeHeatNos 中的记录
|
|
|
- filteredBilletHotsendList = billetHotsendList.stream()
|
|
|
- .filter(item -> {
|
|
|
- String heatNo = item.getHeatNo();
|
|
|
- // 保留 heatNo 为空或不在 excludeHeatNos 中的记录
|
|
|
- return heatNo == null || !excludeHeatNos.contains(heatNo);
|
|
|
- }).collect(Collectors.toList());
|
|
|
- // 4. 同步原始钢坯生产记录表中存在的炉号信息(热装hotChargeLength字段)
|
|
|
- billetOriginalProductRecordList.forEach(x -> {
|
|
|
- // 查询装运单打印表最新的数据,获取热装定尺
|
|
|
- String shiftAndShiftGroup = x.getShift() + "/" + x.getShiftGroup();
|
|
|
- String heatNo = x.getHeatNo();
|
|
|
- // 构建安全的 JSON 路径表达式
|
|
|
- String jsonPath = "$.\"" + heatNo + "\"";
|
|
|
- List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(
|
|
|
- new QueryWrapper<StorageBillPrint>()
|
|
|
- .lambda()
|
|
|
- .eq(StorageBillPrint::getCcmNo, x.getCcmNo())
|
|
|
- .eq(StorageBillPrint::getClasses, shiftAndShiftGroup) // 新增的条件
|
|
|
- .apply("JSON_EXTRACT(heat_no, '" + jsonPath + "') IS NOT NULL")
|
|
|
- );
|
|
|
- // 如果装运单打印表数据不为空,并且热装字段已经被编辑过,就不在实时读取装运打印表的实时热装数据
|
|
|
- if (oConvertUtils.listIsNotEmpty(storageBillPrintList) && "1".equals(x.getIsEditCharge())){
|
|
|
- List<Map<String, Object>> finalResult = handleStorageBillPrintHotCharge(storageBillPrintList, heatNo);
|
|
|
- x.setHotChargeLength(JSON.toJSONString(finalResult));
|
|
|
- billetOriginalProductRecordService.updateById(x);
|
|
|
- }
|
|
|
- });
|
|
|
- }else {
|
|
|
- filteredBilletHotsendList = billetHotsendList;
|
|
|
- }
|
|
|
- // 查询当班炉次浇筑时,增量查询
|
|
|
- filteredBilletHotsendList.forEach(x -> {
|
|
|
- HeatsActualsInfo heatsActualsInfo = new HeatsActualsInfo();
|
|
|
- heatsActualsInfo.setCreateTime(DateUtils.date2Str(x.getCreateTime(), DateUtils.datetimeFormat.get()));
|
|
|
- heatsActualsInfo.setShiftGroup(x.getShiftGroup());
|
|
|
- heatsActualsInfo.setShift(x.getShift());
|
|
|
- heatsActualsInfo.setHeatNo(x.getHeatNo());
|
|
|
- heatsActualsInfo.setBrandNum(x.getBrandNum());// 牌号 钢种
|
|
|
- // 根据铸机号、炉号查询钢坯实绩信息BilletBasicInfo
|
|
|
- LambdaQueryWrapper<BilletBasicInfo> queryWrapper2 = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper2.eq(BilletBasicInfo::getCcmNo, x.getCcmNo())
|
|
|
- .eq(BilletBasicInfo::getHeatNo, x.getHeatNo())
|
|
|
- .eq(BilletBasicInfo::getShift, x.getShift())
|
|
|
- .eq(BilletBasicInfo::getShiftGroup, x.getShiftGroup());
|
|
|
- List<BilletBasicInfo> billetBasicInfoList = billetBasicInfoService.list(queryWrapper2);
|
|
|
- if (oConvertUtils.listIsEmpty(billetBasicInfoList)){
|
|
|
- log.info("{}{}", "钢坯原始生产记录,该炉对应的钢坯实绩不存在:", x.getHeatNo());
|
|
|
- return;
|
|
|
- }
|
|
|
- // 统计各流号的数量
|
|
|
- Map<Integer, Long> strandCountMap = billetBasicInfoList.stream()
|
|
|
- .filter(info -> info.getStrandNo() != null && info.getStrandNo() >= 1 && info.getStrandNo() <= 8)
|
|
|
- .collect(Collectors.groupingBy(BilletBasicInfo::getStrandNo, Collectors.counting()));
|
|
|
-
|
|
|
- // 获取StrandNo等于1的所有定尺length,并去重后用逗号连接
|
|
|
- heatsActualsInfo.setOneStrandNo(Math.toIntExact(strandCountMap.getOrDefault(1, 0L)));
|
|
|
- List<BilletBasicInfo> strandOneData = filterByStrandNo(billetBasicInfoList,1);
|
|
|
- heatsActualsInfo.setOneLength(JSON.toJSONString(groupByLength(strandOneData)));
|
|
|
- heatsActualsInfo.setOneSum(strandOneData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setTwoStrandNo(Math.toIntExact(strandCountMap.getOrDefault(2, 0L)));
|
|
|
- List<BilletBasicInfo> strandTwoData = filterByStrandNo(billetBasicInfoList,2);
|
|
|
- heatsActualsInfo.setTwoLength(JSON.toJSONString(groupByLength(strandTwoData)));
|
|
|
- heatsActualsInfo.setTwoSum(strandTwoData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setThreeStrandNo(Math.toIntExact(strandCountMap.getOrDefault(3, 0L)));
|
|
|
- List<BilletBasicInfo> strandThreeData = filterByStrandNo(billetBasicInfoList,3);
|
|
|
- heatsActualsInfo.setThreeLength(JSON.toJSONString(groupByLength(strandThreeData)));
|
|
|
- heatsActualsInfo.setThreeSum(strandThreeData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setFourStrandNo(Math.toIntExact(strandCountMap.getOrDefault(4, 0L)));
|
|
|
- List<BilletBasicInfo> strandFourData = filterByStrandNo(billetBasicInfoList,4);
|
|
|
- heatsActualsInfo.setFourLength(JSON.toJSONString(groupByLength(strandFourData)));
|
|
|
- heatsActualsInfo.setFourSum(strandFourData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setFiveStrandNo(Math.toIntExact(strandCountMap.getOrDefault(5, 0L)));
|
|
|
- List<BilletBasicInfo> strandFiveData = filterByStrandNo(billetBasicInfoList,5);
|
|
|
- heatsActualsInfo.setFiveLength(JSON.toJSONString(groupByLength(strandFiveData)));
|
|
|
- heatsActualsInfo.setFiveSum(strandFiveData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setSixStrandNo(Math.toIntExact(strandCountMap.getOrDefault(6, 0L)));
|
|
|
- List<BilletBasicInfo> strandSixData = filterByStrandNo(billetBasicInfoList,6);
|
|
|
- heatsActualsInfo.setSixLength(JSON.toJSONString(groupByLength(strandSixData)));
|
|
|
- heatsActualsInfo.setSixSum(strandSixData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setSevenStrandNo(Math.toIntExact(strandCountMap.getOrDefault(7, 0L)));
|
|
|
- List<BilletBasicInfo> strandSevenData = filterByStrandNo(billetBasicInfoList,7);
|
|
|
- heatsActualsInfo.setSevenLength(JSON.toJSONString(groupByLength(strandSevenData)));
|
|
|
- heatsActualsInfo.setSevenSum(strandSevenData.size());
|
|
|
-
|
|
|
- heatsActualsInfo.setEightStrandNo(Math.toIntExact(strandCountMap.getOrDefault(8, 0L)));
|
|
|
- List<BilletBasicInfo> strandEightData = filterByStrandNo(billetBasicInfoList,8);
|
|
|
- heatsActualsInfo.setEightLength(JSON.toJSONString(groupByLength(strandEightData)));
|
|
|
- heatsActualsInfo.setEightSum(strandEightData.size());
|
|
|
-
|
|
|
- // 5#直轧棒一、6#热送高线 过滤并计算
|
|
|
- List<BilletBasicInfo> filterDirectRollingList = billetBasicInfoList.stream()
|
|
|
- .filter(info -> "roll_club_one".equals(info.getBelongTable()) || "roll_height".equals(info.getBelongTable()))
|
|
|
- .collect(Collectors.toList());
|
|
|
- if (oConvertUtils.listIsNotEmpty(filterDirectRollingList)){
|
|
|
- // 计算总重(保留4位小数)
|
|
|
- double totalWeight = filterDirectRollingList.stream()
|
|
|
- .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
- .sum();
|
|
|
- totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
-
|
|
|
- // 统计总数
|
|
|
- int totalCount = filterDirectRollingList.size();
|
|
|
-
|
|
|
- // 按定尺 length 分组统计每组数量(Long 类型)
|
|
|
- Map<Integer, Long> lengthCountMapRaw = filterDirectRollingList.stream()
|
|
|
- .filter(info -> info.getLength() != null)
|
|
|
- .collect(Collectors.groupingBy(BilletBasicInfo::getLength, Collectors.counting()));
|
|
|
-
|
|
|
- // 转换为 Map<String, Long>,确保 JSON key 是字符串
|
|
|
- Map<String, Long> lengthCountMap = lengthCountMapRaw.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- e -> String.valueOf(e.getKey()), // key 转字符串
|
|
|
- Map.Entry::getValue
|
|
|
- ));
|
|
|
-
|
|
|
- // 转为JSON字符串
|
|
|
- Map<String, Object> directRollingMap = new HashMap<>();
|
|
|
- directRollingMap.put("directRollingTotalWeight", totalWeight);
|
|
|
- directRollingMap.put("directRollingTotalCount", totalCount);
|
|
|
- directRollingMap.put("lengthGroupCount", lengthCountMap); // 定尺统计结果
|
|
|
- String jsonResult = JSON.toJSONString(directRollingMap); // 使用FastJSON转换.
|
|
|
- heatsActualsInfo.setDirectRolling(jsonResult);
|
|
|
- }
|
|
|
-
|
|
|
- // 堆垛过滤并计算
|
|
|
- List<BilletBasicInfo> filterStackList = billetBasicInfoList.stream()
|
|
|
- .filter(info -> "stacking_and_loading_vehicles".equals(info.getBelongTable()))
|
|
|
- .collect(Collectors.toList());
|
|
|
- if (oConvertUtils.listIsNotEmpty(filterStackList)){
|
|
|
- // 按定尺长度分组
|
|
|
- Map<Integer, List<BilletBasicInfo>> lengthGroupMap = filterStackList.stream()
|
|
|
- .filter(info -> info.getLength() != null)
|
|
|
- .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
|
|
|
-
|
|
|
- // 构建分组统计结果列表
|
|
|
- List<Map<String, Object>> lengthGroupList = new ArrayList<>();
|
|
|
-
|
|
|
- for (Map.Entry<Integer, List<BilletBasicInfo>> entry : lengthGroupMap.entrySet()) {
|
|
|
- Integer length = entry.getKey();
|
|
|
- List<BilletBasicInfo> billets = entry.getValue();
|
|
|
-
|
|
|
- // 计算该定尺长度的总重(保留4位小数)
|
|
|
- double lengthWeight = billets.stream()
|
|
|
- .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
- .sum();
|
|
|
- lengthWeight = Math.round(lengthWeight * 10000) / 10000.0;
|
|
|
-
|
|
|
- // 统计该定尺长度的数量
|
|
|
- int lengthCount = billets.size();
|
|
|
-
|
|
|
- // 构建该定尺长度的统计结果
|
|
|
- Map<String, Object> lengthStat = new HashMap<>();
|
|
|
- lengthStat.put("stackingWeight", lengthWeight);
|
|
|
- lengthStat.put("stackingCount", lengthCount);
|
|
|
- lengthStat.put("stackingLength", length);
|
|
|
- // 添加到结果列表
|
|
|
- lengthGroupList.add(lengthStat);
|
|
|
- }
|
|
|
- // 直接将列表转换为JSON
|
|
|
- String jsonResult = JSON.toJSONString(lengthGroupList);
|
|
|
- heatsActualsInfo.setStacking(jsonResult);
|
|
|
- }
|
|
|
-
|
|
|
- // 根据铸机号、炉号、班组、班别查询装运单打印表
|
|
|
- String shiftAndShiftGroup = x.getShift() + "/" + x.getShiftGroup();
|
|
|
- String heatNo = x.getHeatNo();
|
|
|
- // 构建安全的 JSON 路径表达式
|
|
|
- String jsonPath = "$.\"" + heatNo + "\"";
|
|
|
- List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(
|
|
|
- new QueryWrapper<StorageBillPrint>()
|
|
|
- .lambda()
|
|
|
- .eq(StorageBillPrint::getCcmNo, x.getCcmNo())
|
|
|
- .eq(StorageBillPrint::getClasses, shiftAndShiftGroup) // 新增的条件
|
|
|
- .apply("JSON_EXTRACT(heat_no, '" + jsonPath + "') IS NOT NULL")
|
|
|
- );
|
|
|
- if (oConvertUtils.listIsNotEmpty(storageBillPrintList)){
|
|
|
- List<Map<String, Object>> finalResult = handleStorageBillPrintHotCharge(storageBillPrintList, heatNo);
|
|
|
- // 使用结果...
|
|
|
- log.info("钢坯原始记录,热装打印表分组统计结果: {}", JSON.toJSONString(finalResult));
|
|
|
- heatsActualsInfo.setHotCharge(JSON.toJSONString(finalResult));
|
|
|
- }
|
|
|
-
|
|
|
- // 按length字段分组,并统计每组的总数和总重
|
|
|
- Map<Integer, Map<String, Object>> lengthResultMap = billetBasicInfoList.stream()
|
|
|
- .filter(info -> info.getLength() != null) // 过滤掉length为null的记录
|
|
|
- .collect(Collectors.groupingBy(
|
|
|
- BilletBasicInfo::getLength, // 按length分组
|
|
|
- Collectors.collectingAndThen(
|
|
|
- Collectors.toList(),
|
|
|
- list -> {
|
|
|
- // 计算每组的总重(保留4位小数)
|
|
|
- double totalWeight = list.stream()
|
|
|
- .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
- .sum();
|
|
|
- totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
- // 统计每组的总数
|
|
|
- int totalCount = list.size();
|
|
|
- // 创建每组的结果Map
|
|
|
- Map<String, Object> groupResult = new HashMap<>();
|
|
|
- groupResult.put("lengthTotalWeight", totalWeight);
|
|
|
- groupResult.put("lengthTotalCount", totalCount);
|
|
|
- //棒一统计
|
|
|
- long rollClubOneCount = list.stream()
|
|
|
- .filter(billet -> "roll_club_one".equals(billet.getBelongTable()))
|
|
|
- .count();
|
|
|
- groupResult.put("rollClubOneCount", (int) rollClubOneCount);
|
|
|
- // 棒二统计
|
|
|
- long rollClubTwoCount = list.stream()
|
|
|
- .filter(billet -> "roll_club_two".equals(billet.getBelongTable()))
|
|
|
- .count();
|
|
|
- groupResult.put("rollClubTwoCount", (int) rollClubTwoCount);
|
|
|
- // 棒三统计
|
|
|
- long rollClubThreeCount = list.stream()
|
|
|
- .filter(billet -> "roll_club_three".equals(billet.getBelongTable()))
|
|
|
- .count();
|
|
|
- groupResult.put("rollClubThreeCount", (int) rollClubThreeCount);
|
|
|
- // 高线统计
|
|
|
- long rollHeightCount = list.stream()
|
|
|
- .filter(billet -> "roll_height".equals(billet.getBelongTable()))
|
|
|
- .count();
|
|
|
- groupResult.put("rollHeightCount", (int) rollHeightCount);
|
|
|
- // 堆垛统计
|
|
|
- long stackingAndLoadingVehiclesCount = list.stream()
|
|
|
- .filter(billet -> "stacking_and_loading_vehicles".equals(billet.getBelongTable()))
|
|
|
- .count();
|
|
|
- groupResult.put("stackingAndLoadingVehiclesCount", (int) stackingAndLoadingVehiclesCount);
|
|
|
- return groupResult;
|
|
|
- }
|
|
|
- )
|
|
|
- ));
|
|
|
- // 将Integer键转换为String键
|
|
|
- Map<String, Map<String, Object>> stringKeyMap = lengthResultMap.entrySet().stream()
|
|
|
- .collect(Collectors.toMap(
|
|
|
- e -> String.valueOf(e.getKey()),
|
|
|
- Map.Entry::getValue
|
|
|
- ));
|
|
|
-
|
|
|
- // 转换为JSON字符串
|
|
|
- String jsonResult = JSON.toJSONString(stringKeyMap);
|
|
|
- heatsActualsInfo.setLength(jsonResult);
|
|
|
-
|
|
|
- // 统计总数
|
|
|
- long totalCount = billetBasicInfoList.size();
|
|
|
-
|
|
|
- // 计算总重(保留4位小数)
|
|
|
- double totalWeight = billetBasicInfoList.stream()
|
|
|
- .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
- .sum();
|
|
|
- totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
-
|
|
|
- // 转为JSON字符串
|
|
|
- Map<String, Object> resultMap = new HashMap<>();
|
|
|
- resultMap.put("totalCount", totalCount);
|
|
|
- resultMap.put("totalWeight", totalWeight);
|
|
|
- String sumJsonResult = JSON.toJSONString(resultMap); // 使用FastJSON转换
|
|
|
- heatsActualsInfo.setTotalInfo(sumJsonResult);
|
|
|
-
|
|
|
- heatsActualsInfoList.add(heatsActualsInfo);
|
|
|
- });
|
|
|
- return heatsActualsInfoList;
|
|
|
- }
|
|
|
-
|
|
|
- @ApiOperation(value="钢坯堆垛原始生产记录查询", notes="钢坯原始堆垛生产记录查询")
|
|
|
- @GetMapping(value = "/queryBilletStackRecordByCcmNo")
|
|
|
- public Result<List<BilletOriginalHeatNoDetail>> queryBilletStackRecordByCcmNo(@RequestParam(name="ccmNo", required = false) String ccmNo,
|
|
|
- @RequestParam(name="changeShiftId", required = false) String changeShiftId,
|
|
|
- @RequestParam(name="queryType") String queryType) {
|
|
|
- List<BilletOriginalHeatNoDetail> billetOriginalHeatNoDetailList = new ArrayList<>();
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
- if ("1".equals(queryType)){
|
|
|
- String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
- String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
- String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
- String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
-
|
|
|
- if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
- return Result.error("班组班别获取为空,钢坯堆垛原始生产记录查询失败!");
|
|
|
- }
|
|
|
- // 根据ccmNo、shift、shiftGroup查询最新的交班记录
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
- .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
- .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
- .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (billetHotsendChangeShift == null){
|
|
|
- log.info("{}{}", "钢坯堆垛原始生产记录,交班记录为空!", ccmNo + "失败时间:" + new Date());
|
|
|
- return Result.error("交班信息为空,钢坯堆垛原始生产记录查询失败!");
|
|
|
- }
|
|
|
- }else {
|
|
|
- billetHotsendChangeShift = billetHotsendChangeShiftService.getById(changeShiftId);
|
|
|
- }
|
|
|
-
|
|
|
- QueryWrapper<BilletOriginalProductRecord> queryWrapper3 = new QueryWrapper<>();
|
|
|
- queryWrapper3.eq("ccm_no", ccmNo)
|
|
|
- .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
- .eq("shift_group", billetHotsendChangeShift.getShiftGroup());
|
|
|
- if ("1".equals(queryType)){
|
|
|
- queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), new Date());
|
|
|
- }else {
|
|
|
- queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime());
|
|
|
- }
|
|
|
- // 通过铸机号、班组、班别、交班开始时间 查询钢坯堆垛生产原始记录
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper3);
|
|
|
- if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
- return Result.OK(billetOriginalHeatNoDetailList);
|
|
|
- }
|
|
|
- billetOriginalProductRecordList.forEach(x -> {
|
|
|
- BilletOriginalHeatNoDetail billetOriginalHeatNoDetail = new BilletOriginalHeatNoDetail();
|
|
|
- billetOriginalHeatNoDetail.setCcmNo(x.getCcmNo());
|
|
|
- billetOriginalHeatNoDetail.setHeatNo(x.getHeatNo());
|
|
|
- billetOriginalHeatNoDetail.setBrandNum(x.getGrade());
|
|
|
- billetOriginalHeatNoDetail.setShiftGroup(x.getShiftGroup());
|
|
|
- billetOriginalHeatNoDetail.setShift(x.getShift());
|
|
|
- if (oConvertUtils.isNotEmpty(x.getStackLength())){
|
|
|
- billetOriginalHeatNoDetail.setStackLength(x.getStackLength());
|
|
|
- String stackLengthJson = x.getStackLength();
|
|
|
- JSONArray jsonArray = JSON.parseArray(stackLengthJson);
|
|
|
- // 初始化总数和总重
|
|
|
- int totalCount = 0;
|
|
|
- double totalWeight = 0.0d;
|
|
|
- // 遍历 JSON 数组计算总数和总重
|
|
|
- for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
- JSONObject item = jsonArray.getJSONObject(i);
|
|
|
- // 获取 stackingCount 字段并累加到总数
|
|
|
- int count = item.getIntValue("stackingCount");
|
|
|
- // 如果 stackingCount 为 0,跳过该项
|
|
|
- if (count == 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- totalCount += count;
|
|
|
- // 获取 stackingWeight 字段并累加到总重
|
|
|
- double weight = item.getDoubleValue("stackingWeight");
|
|
|
- totalWeight += weight;
|
|
|
- }
|
|
|
- // 使用 DecimalFormat 四舍五入 保留四位小数
|
|
|
- DecimalFormat df = new DecimalFormat("#.####");
|
|
|
- String formattedWeight = df.format(totalWeight);
|
|
|
- double roundedWeight = Double.parseDouble(formattedWeight);
|
|
|
- billetOriginalHeatNoDetail.setAmountTotal(totalCount);
|
|
|
- billetOriginalHeatNoDetail.setBlankOutput(roundedWeight);
|
|
|
- }
|
|
|
- billetOriginalHeatNoDetailList.add(billetOriginalHeatNoDetail);
|
|
|
- });
|
|
|
-
|
|
|
- return Result.OK(billetOriginalHeatNoDetailList);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @ApiOperation(value="所有钢坯堆垛信息查询", notes="所有钢坯堆垛信息查询")
|
|
|
- @GetMapping(value = "/queryBilletStackInfoByCcmNo")
|
|
|
- public Result<List<Map<String, Object>>> queryBilletStackInfoByCcmNo(@RequestParam(name="ccmNo", required = true) String ccmNo,
|
|
|
+ /**
|
|
|
+ * 导出excel
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param billetOriginalProductRecord
|
|
|
+ */
|
|
|
+ @RequiresPermissions("billetOriginalProductRecord:billet_original_product_record:exportXls")
|
|
|
+ @RequestMapping(value = "/exportXls")
|
|
|
+ public ModelAndView exportXls(HttpServletRequest request, BilletOriginalProductRecord billetOriginalProductRecord) {
|
|
|
+ return super.exportXls(request, billetOriginalProductRecord, BilletOriginalProductRecord.class, "钢坯生成原始记录");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 通过excel导入数据
|
|
|
+ *
|
|
|
+ * @param request
|
|
|
+ * @param response
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ @RequiresPermissions("billetOriginalProductRecord:billet_original_product_record:importExcel")
|
|
|
+ @RequestMapping(value = "/importExcel", method = RequestMethod.POST)
|
|
|
+ public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
|
|
|
+ return super.importExcel(request, response, BilletOriginalProductRecord.class);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation(value="钢坯原始生产记录查询", notes="钢坯原始生产记录查询")
|
|
|
+ @GetMapping(value = "/queryBilletRecordByCcmNo")
|
|
|
+ public Result<BilletOriginalProductRecordDetail> queryHeatsActualsByCcmNo(@RequestParam(name="ccmNo", required = false) String ccmNo,
|
|
|
+ @RequestParam(name="changeShiftId", required = false) String changeShiftId,
|
|
|
+ @RequestParam(name="queryType") String queryType) {
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecords = new ArrayList<>();
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
+ if ("1".equals(queryType)){
|
|
|
+ String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
+ String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
+ String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
+ String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
+
|
|
|
+ if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
+ return Result.error("班组班别获取为空,钢坯原始生产记录查询失败!");
|
|
|
+ }
|
|
|
+ // 根据ccmNo、shift、shiftGroup查询最新的交班记录
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
+ .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
+ .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null){
|
|
|
+ log.info("{}{}", "钢坯原始生产记录,交班记录为空!", ccmNo + "失败时间:" + new Date());
|
|
|
+ return Result.error("交班信息为空,钢坯原始生产记录查询失败!");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getById(changeShiftId);
|
|
|
+ }
|
|
|
+ if (billetHotsendChangeShift == null) {
|
|
|
+ log.error("未查询到有效的交班记录,无法继续处理");
|
|
|
+ return Result.error("未找到对应的交班信息,原始生产记录获取失败!");
|
|
|
+ }
|
|
|
+ //1、 获取当班浇筑炉次详细信息
|
|
|
+ List<HeatsActualsInfo> heatsActualsInfoList = queryCurrentHeatsActualsInfo(ccmNo, billetHotsendChangeShift.getShift(), billetHotsendChangeShift.getShiftGroup(), billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime(), queryType);
|
|
|
+ if (oConvertUtils.listIsNotEmpty(heatsActualsInfoList)){
|
|
|
+ log.info("原始生产记录,当班浇筑炉次数据信息: " + JSON.toJSON(heatsActualsInfoList));
|
|
|
+ //2、把获取到的当班浇筑炉次信息heatsActualsInfoList保存到原始生产记录表
|
|
|
+ heatsActualsInfoList.forEach(x -> {
|
|
|
+ BilletOriginalProductRecord billetOriginalProductRecord = new BilletOriginalProductRecord();
|
|
|
+ billetOriginalProductRecord.setId(String.valueOf(IdWorker.getId()));
|
|
|
+ billetOriginalProductRecord.setCcmNo(ccmNo);
|
|
|
+ billetOriginalProductRecord.setHeatNo(x.getHeatNo());
|
|
|
+ billetOriginalProductRecord.setShift(x.getShift());
|
|
|
+ billetOriginalProductRecord.setShiftGroup(x.getShiftGroup());
|
|
|
+ billetOriginalProductRecord.setGrade(x.getBrandNum());
|
|
|
+ billetOriginalProductRecord.setOneStrandSum(x.getOneSum());
|
|
|
+ billetOriginalProductRecord.setTwoStrandSum(x.getTwoSum());
|
|
|
+ billetOriginalProductRecord.setThreeStrandSum(x.getThreeSum());
|
|
|
+ billetOriginalProductRecord.setFourStrandSum(x.getFourSum());
|
|
|
+ billetOriginalProductRecord.setFiveStrandSum(x.getFiveSum());
|
|
|
+ billetOriginalProductRecord.setSixStrandSum(x.getSixSum());
|
|
|
+ billetOriginalProductRecord.setSevenStrandSum(x.getSevenSum());
|
|
|
+ billetOriginalProductRecord.setEightStrandSum(x.getEightSum());
|
|
|
+ String totalInfoJson = x.getTotalInfo();
|
|
|
+ if (oConvertUtils.isEmpty(totalInfoJson)){
|
|
|
+ billetOriginalProductRecord.setAmount(0);// 合计
|
|
|
+ }else {
|
|
|
+ JSONObject json = JSON.parseObject(totalInfoJson);
|
|
|
+ Integer totalCount = json.getInteger("totalCount");
|
|
|
+ billetOriginalProductRecord.setAmount(totalCount);// 合计
|
|
|
+ }
|
|
|
+ billetOriginalProductRecord.setRollClubOneDetails(x.getDirectRolling());// 直轧热送棒一
|
|
|
+ billetOriginalProductRecord.setHotChargeLength(x.getHotCharge());
|
|
|
+ billetOriginalProductRecord.setStackLength(x.getStacking());
|
|
|
+ billetOriginalProductRecord.setLengthDetails(x.getLength());
|
|
|
+ billetOriginalProductRecord.setCreateTime(DateUtils.str2Date(x.getCreateTime(), DateUtils.datetimeFormat.get()));
|
|
|
+ billetOriginalProductRecord.setIsEditCharge("1");
|
|
|
+ billetOriginalProductRecords.add(billetOriginalProductRecord);
|
|
|
+ });
|
|
|
+ log.info("钢坯原始生产记录信息: " + JSON.toJSON(billetOriginalProductRecords));
|
|
|
+
|
|
|
+ // 在批量保存前,过滤掉已存在的炉号记录
|
|
|
+ List<BilletOriginalProductRecord> finalRecords = billetOriginalProductRecords.stream()
|
|
|
+ .filter(record -> {
|
|
|
+ // 使用 getOne 方法检查是否存在相同记录(铸机号、炉号、班次、班组均相同)
|
|
|
+ LambdaQueryWrapper<BilletOriginalProductRecord> checkWrapper = new LambdaQueryWrapper<>();
|
|
|
+ checkWrapper.eq(BilletOriginalProductRecord::getCcmNo, record.getCcmNo())
|
|
|
+ .eq(BilletOriginalProductRecord::getHeatNo, record.getHeatNo())
|
|
|
+ .eq(BilletOriginalProductRecord::getShift, record.getShift())
|
|
|
+ .eq(BilletOriginalProductRecord::getShiftGroup, record.getShiftGroup())
|
|
|
+ .last("LIMIT 1"); // 只查询一条记录,提高性能
|
|
|
+ // 如果 getOne 结果为 null,表示记录不存在,保留该记录
|
|
|
+ return billetOriginalProductRecordService.getOne(checkWrapper, false) == null;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ if(oConvertUtils.listIsNotEmpty(finalRecords)){
|
|
|
+ try {
|
|
|
+ // 批量保存
|
|
|
+ billetOriginalProductRecordService.saveBatch(finalRecords);
|
|
|
+ } catch (DuplicateKeyException e) {
|
|
|
+ log.error("炉号重复插入:{}", JSON.toJSONString(billetOriginalProductRecords), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ QueryWrapper<BilletOriginalProductRecord> queryWrapper3 = new QueryWrapper<>();
|
|
|
+ queryWrapper3.eq("ccm_no", ccmNo)
|
|
|
+ .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
+ .eq("shift_group", billetHotsendChangeShift.getShiftGroup());
|
|
|
+ if ("1".equals(queryType)){
|
|
|
+ queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), new Date());
|
|
|
+ }else {
|
|
|
+ queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime());
|
|
|
+ }
|
|
|
+ // 通过铸机号、班组、班别、交班开始时间 查询钢坯生产原始记录
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper3);
|
|
|
+ BilletOriginalProductRecordDetail billetOriginalProductRecordDetails = new BilletOriginalProductRecordDetail();
|
|
|
+ billetOriginalProductRecordDetails.setBilletOriginalProductRecordList(billetOriginalProductRecordList);
|
|
|
+ billetOriginalProductRecordDetails.setSizeInfo(billetHotsendChangeShift.getSizeInfo());
|
|
|
+ billetOriginalProductRecordDetails.setContent(billetHotsendChangeShift.getContent());
|
|
|
+ billetOriginalProductRecordDetails.setConfirmStatus(billetHotsendChangeShift.getConfirmStatus());
|
|
|
+ return Result.OK(billetOriginalProductRecordDetails);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("送样卡获取定尺支数明细表")
|
|
|
+ @GetMapping("/lengthDetailsTable")
|
|
|
+ public Result<List<LengthCountVO>> getLengthDetailsTable(LengthCountQueryDTO queryDTO) {
|
|
|
+ if (queryDTO == null || StringUtils.isBlank(queryDTO.getCcmNo())) {
|
|
|
+ return Result.error("参数不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ String shift = "";
|
|
|
+ String shiftGroup = "";
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
+
|
|
|
+ if (oConvertUtils.isEmpty(queryDTO.getChangeShiftId())) {
|
|
|
+ String classShiftGroup = String.format("class:shift:group:%s", queryDTO.getCcmNo());
|
|
|
+ String classShift = String.format("class:shift:%s", queryDTO.getCcmNo());
|
|
|
+ shift = oConvertUtils.getString(redisTemplate.opsForValue().get(classShift), "");
|
|
|
+ shiftGroup = oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup), "");
|
|
|
+
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo())
|
|
|
+ .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
+ .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null) {
|
|
|
+ log.info("查询班次信息失败,交班记录为空!失败时间:{}", new Date());
|
|
|
+ return Result.OK(Collections.emptyList());
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getId, queryDTO.getChangeShiftId())
|
|
|
+ .eq(BilletHotsendChangeShift::getCcmNo, queryDTO.getCcmNo());
|
|
|
+
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null) {
|
|
|
+ log.info("查询班次信息失败,交班记录为空!失败时间:{}", new Date());
|
|
|
+ return Result.OK(Collections.emptyList());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
+ Date endTime = billetHotsendChangeShift.getChangeShiftTime() != null
|
|
|
+ ? billetHotsendChangeShift.getChangeShiftTime()
|
|
|
+ : new Date();
|
|
|
+
|
|
|
+ QueryWrapper<BilletOriginalProductRecord> queryWrapperB = new QueryWrapper<>();
|
|
|
+ queryWrapperB.eq("ccm_no", queryDTO.getCcmNo())
|
|
|
+ .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
+ .eq("shift_group", billetHotsendChangeShift.getShiftGroup())
|
|
|
+ .ge("create_time", startTime)
|
|
|
+ .le("create_time", endTime)
|
|
|
+ .orderByAsc("create_time");
|
|
|
+
|
|
|
+ List<BilletOriginalProductRecord> records = billetOriginalProductRecordService.list(queryWrapperB);
|
|
|
+
|
|
|
+ List<LengthCountVO> resultList = new ArrayList<>();
|
|
|
+ Set<String> allLengths = new TreeSet<>();
|
|
|
+ ObjectMapper objectMapper = new ObjectMapper();
|
|
|
+
|
|
|
+ for (BilletOriginalProductRecord record : records) {
|
|
|
+ LengthCountVO vo = new LengthCountVO();
|
|
|
+ vo.setHeatNo(record.getHeatNo());
|
|
|
+
|
|
|
+ String brandNum = Optional.ofNullable(record.getGrade())
|
|
|
+ .map(bn -> sysDictService.queryDictTextByKey("billet_spec", bn))
|
|
|
+ .orElseGet(() -> sysDictService.queryDictTextByKey("billet_spec", "5"));
|
|
|
+ vo.setBrandNum(brandNum);
|
|
|
+
|
|
|
+ Map<String, Integer> mergedLengthCount = new HashMap<>();
|
|
|
+
|
|
|
+ // 解析 rollClubOneDetails 的 lengthGroupCount
|
|
|
+ String rollClubOneDetailsJson = record.getRollClubOneDetails();
|
|
|
+ if (StringUtils.isNotBlank(rollClubOneDetailsJson)) {
|
|
|
+ try {
|
|
|
+ JsonNode rollDetails = objectMapper.readTree(rollClubOneDetailsJson);
|
|
|
+ JsonNode lengthGroupCount = rollDetails.path("lengthGroupCount");
|
|
|
+ if (lengthGroupCount.isObject()) {
|
|
|
+ for (Iterator<Map.Entry<String, JsonNode>> it = lengthGroupCount.fields(); it.hasNext(); ) {
|
|
|
+ Map.Entry<String, JsonNode> entry = it.next();
|
|
|
+ String mm = entry.getKey();
|
|
|
+ int count = entry.getValue().asInt(0);
|
|
|
+ mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("解析 rollClubOneDetails 失败: {}, 内容: {}", record.getHeatNo(), rollClubOneDetailsJson, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 hotChargeLength 数组
|
|
|
+ String hotChargeLengthJson = record.getHotChargeLength();
|
|
|
+ if (StringUtils.isNotBlank(hotChargeLengthJson)) {
|
|
|
+ try {
|
|
|
+ JsonNode hotArray = objectMapper.readTree(hotChargeLengthJson);
|
|
|
+ if (hotArray.isArray()) {
|
|
|
+ for (JsonNode node : hotArray) {
|
|
|
+ String mm = node.path("hotChargeLength").asText();
|
|
|
+ int count = node.path("totalCount").asInt(0);
|
|
|
+ mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("解析 hotChargeLength 失败: {}, 内容: {}", record.getHeatNo(), hotChargeLengthJson, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 stackLength 数组
|
|
|
+ String stackLengthJson = record.getStackLength();
|
|
|
+ if (StringUtils.isNotBlank(stackLengthJson)) {
|
|
|
+ try {
|
|
|
+ JsonNode stackArray = objectMapper.readTree(stackLengthJson);
|
|
|
+ if (stackArray.isArray()) {
|
|
|
+ for (JsonNode node : stackArray) {
|
|
|
+ String mm = node.path("stackingLength").asText();
|
|
|
+ int count = node.path("stackingCount").asInt(0);
|
|
|
+ mergedLengthCount.merge(mm, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("解析 stackLength 失败: {}, 内容: {}", record.getHeatNo(), stackLengthJson, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转换 mm 为 m(两位小数),组装 vo
|
|
|
+ for (Map.Entry<String, Integer> entry : mergedLengthCount.entrySet()) {
|
|
|
+ String mmStr = entry.getKey();
|
|
|
+ int count = entry.getValue();
|
|
|
+ String mStr;
|
|
|
+ try {
|
|
|
+ BigDecimal mm = new BigDecimal(mmStr);
|
|
|
+ mStr = mm.divide(BigDecimal.valueOf(1000), 2, RoundingMode.HALF_UP).toString();
|
|
|
+ } catch (Exception e) {
|
|
|
+ mStr = mmStr;
|
|
|
+ }
|
|
|
+ vo.getLengthCountMap().put(mStr, count);
|
|
|
+ allLengths.add(mStr);
|
|
|
+ }
|
|
|
+
|
|
|
+ resultList.add(vo);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 补齐所有定尺列(不存在的补0)
|
|
|
+ for (LengthCountVO vo : resultList) {
|
|
|
+ for (String length : allLengths) {
|
|
|
+ vo.getLengthCountMap().putIfAbsent(length, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return Result.OK(resultList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation("质检记录定尺明细(用于菜单)")
|
|
|
+ @GetMapping("/qualityInspectionMenu")
|
|
|
+ public Result<Map<String, Object>> getQualityInspectionMenu(QualityInspectionQueryDTO queryDTO) {
|
|
|
+
|
|
|
+ Map<String, Object> result = billetOriginalProductRecordService.getQualityInspectionMenu(queryDTO);
|
|
|
+ return Result.OK(result);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取当前班次下所有炉次浇筑数据
|
|
|
+ * @param ccmNo
|
|
|
+ * @param shift
|
|
|
+ * @param shiftGroup
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<HeatsActualsInfo> queryCurrentHeatsActualsInfo(String ccmNo, String shift, String shiftGroup, Date shiftStartTime, Date shiftEndTime, String queryType) {
|
|
|
+ List<HeatsActualsInfo> heatsActualsInfoList = new ArrayList<>();
|
|
|
+ //根据ccmNo、shift、shiftGroup、大于billetHotsendChangeShift的创建时间 查询所有炉次传递单BilletHotsend
|
|
|
+ LambdaQueryWrapper<BilletHotsend> queryWrapper1 = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper1.eq(BilletHotsend::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletHotsend::getShift, shift)
|
|
|
+ .eq(BilletHotsend::getShiftGroup, shiftGroup);
|
|
|
+ if ("1".equals(queryType)){
|
|
|
+ queryWrapper1.between(BilletHotsend::getCreateTime, shiftStartTime, new Date());
|
|
|
+ }else {
|
|
|
+ queryWrapper1.between(BilletHotsend::getCreateTime, shiftStartTime, shiftEndTime);
|
|
|
+ }
|
|
|
+ queryWrapper1.orderByDesc(BilletHotsend::getCreateTime);
|
|
|
+ List<BilletHotsend> billetHotsendList = billetHotsendBaseService.list(queryWrapper1);
|
|
|
+ if (oConvertUtils.listIsEmpty(billetHotsendList)){
|
|
|
+ log.info("{}{}", "钢坯原始生产记录查询失败,炉次传递单为空!", ccmNo + "失败时间:" + new Date());
|
|
|
+ return heatsActualsInfoList;
|
|
|
+ }
|
|
|
+ List<String> distinctHeatNoList = billetHotsendList.stream()
|
|
|
+ .map(BilletHotsend::getHeatNo) // 提取炉号
|
|
|
+ .filter(Objects::nonNull) // 过滤可能的 null 值
|
|
|
+ .distinct() // 去重
|
|
|
+ .collect(Collectors.toList()); // 转为列表
|
|
|
+ List<BilletHotsend> filteredBilletHotsendList = new ArrayList<>();
|
|
|
+ // 根据铸机号、班别、班别、炉号查询钢坯原始生产记录
|
|
|
+ QueryWrapper<BilletOriginalProductRecord> queryWrapper8 = new QueryWrapper<>();
|
|
|
+ queryWrapper8.eq("ccm_no", ccmNo)
|
|
|
+ .eq("shift", shift)
|
|
|
+ .eq("shift_group", shiftGroup)
|
|
|
+ .in("heat_no", distinctHeatNoList)
|
|
|
+ .orderByDesc("create_time");
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper8);
|
|
|
+ if (oConvertUtils.listIsNotEmpty(billetOriginalProductRecordList)){
|
|
|
+ List<String> distinctOriginalProductRecordHeatNoList = billetOriginalProductRecordList.stream()
|
|
|
+ .map(BilletOriginalProductRecord::getHeatNo) // 提取炉号
|
|
|
+ .filter(Objects::nonNull) // 过滤可能的 null 值
|
|
|
+ .distinct() // 去重
|
|
|
+ .collect(Collectors.toList()); // 转为列表
|
|
|
+ // 2. 将炉号列表转换为 Set 以提高查询效率
|
|
|
+ Set<String> excludeHeatNos = new HashSet<>(distinctOriginalProductRecordHeatNoList);
|
|
|
+ // 3. 过滤 billetHotsendList,保留炉号不在 excludeHeatNos 中的记录
|
|
|
+ filteredBilletHotsendList = billetHotsendList.stream()
|
|
|
+ .filter(item -> {
|
|
|
+ String heatNo = item.getHeatNo();
|
|
|
+ // 保留 heatNo 为空或不在 excludeHeatNos 中的记录
|
|
|
+ return heatNo == null || !excludeHeatNos.contains(heatNo);
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ // 4. 同步原始钢坯生产记录表中存在的炉号信息(热装hotChargeLength字段)
|
|
|
+ billetOriginalProductRecordList.forEach(x -> {
|
|
|
+ // 查询装运单打印表最新的数据,获取热装定尺
|
|
|
+ String shiftAndShiftGroup = x.getShift() + "/" + x.getShiftGroup();
|
|
|
+ String heatNo = x.getHeatNo();
|
|
|
+ // 构建安全的 JSON 路径表达式
|
|
|
+ String jsonPath = "$.\"" + heatNo + "\"";
|
|
|
+ List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(
|
|
|
+ new QueryWrapper<StorageBillPrint>()
|
|
|
+ .lambda()
|
|
|
+ .eq(StorageBillPrint::getCcmNo, x.getCcmNo())
|
|
|
+ .eq(StorageBillPrint::getClasses, shiftAndShiftGroup) // 新增的条件
|
|
|
+ .apply("JSON_EXTRACT(heat_no, '" + jsonPath + "') IS NOT NULL")
|
|
|
+ );
|
|
|
+ // 如果装运单打印表数据不为空,并且热装字段已经被编辑过,就不在实时读取装运打印表的实时热装数据
|
|
|
+ if (oConvertUtils.listIsNotEmpty(storageBillPrintList) && "1".equals(x.getIsEditCharge())){
|
|
|
+ List<Map<String, Object>> finalResult = handleStorageBillPrintHotCharge(storageBillPrintList, heatNo);
|
|
|
+ x.setHotChargeLength(JSON.toJSONString(finalResult));
|
|
|
+ billetOriginalProductRecordService.updateById(x);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }else {
|
|
|
+ filteredBilletHotsendList = billetHotsendList;
|
|
|
+ }
|
|
|
+ // 查询当班炉次浇筑时,增量查询
|
|
|
+ filteredBilletHotsendList.forEach(x -> {
|
|
|
+ HeatsActualsInfo heatsActualsInfo = new HeatsActualsInfo();
|
|
|
+ heatsActualsInfo.setCreateTime(DateUtils.date2Str(x.getCreateTime(), DateUtils.datetimeFormat.get()));
|
|
|
+ heatsActualsInfo.setShiftGroup(x.getShiftGroup());
|
|
|
+ heatsActualsInfo.setShift(x.getShift());
|
|
|
+ heatsActualsInfo.setHeatNo(x.getHeatNo());
|
|
|
+ heatsActualsInfo.setBrandNum(x.getBrandNum());// 牌号 钢种
|
|
|
+ // 根据铸机号、炉号查询钢坯实绩信息BilletBasicInfo
|
|
|
+ LambdaQueryWrapper<BilletBasicInfo> queryWrapper2 = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper2.eq(BilletBasicInfo::getCcmNo, x.getCcmNo())
|
|
|
+ .eq(BilletBasicInfo::getHeatNo, x.getHeatNo())
|
|
|
+ .eq(BilletBasicInfo::getShift, x.getShift())
|
|
|
+ .eq(BilletBasicInfo::getShiftGroup, x.getShiftGroup());
|
|
|
+ List<BilletBasicInfo> billetBasicInfoList = billetBasicInfoService.list(queryWrapper2);
|
|
|
+ if (oConvertUtils.listIsEmpty(billetBasicInfoList)){
|
|
|
+ log.info("{}{}", "钢坯原始生产记录,该炉对应的钢坯实绩不存在:", x.getHeatNo());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 统计各流号的数量
|
|
|
+ Map<Integer, Long> strandCountMap = billetBasicInfoList.stream()
|
|
|
+ .filter(info -> info.getStrandNo() != null && info.getStrandNo() >= 1 && info.getStrandNo() <= 8)
|
|
|
+ .collect(Collectors.groupingBy(BilletBasicInfo::getStrandNo, Collectors.counting()));
|
|
|
+
|
|
|
+ // 获取StrandNo等于1的所有定尺length,并去重后用逗号连接
|
|
|
+ heatsActualsInfo.setOneStrandNo(Math.toIntExact(strandCountMap.getOrDefault(1, 0L)));
|
|
|
+ List<BilletBasicInfo> strandOneData = filterByStrandNo(billetBasicInfoList,1);
|
|
|
+ heatsActualsInfo.setOneLength(JSON.toJSONString(groupByLength(strandOneData)));
|
|
|
+ heatsActualsInfo.setOneSum(strandOneData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setTwoStrandNo(Math.toIntExact(strandCountMap.getOrDefault(2, 0L)));
|
|
|
+ List<BilletBasicInfo> strandTwoData = filterByStrandNo(billetBasicInfoList,2);
|
|
|
+ heatsActualsInfo.setTwoLength(JSON.toJSONString(groupByLength(strandTwoData)));
|
|
|
+ heatsActualsInfo.setTwoSum(strandTwoData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setThreeStrandNo(Math.toIntExact(strandCountMap.getOrDefault(3, 0L)));
|
|
|
+ List<BilletBasicInfo> strandThreeData = filterByStrandNo(billetBasicInfoList,3);
|
|
|
+ heatsActualsInfo.setThreeLength(JSON.toJSONString(groupByLength(strandThreeData)));
|
|
|
+ heatsActualsInfo.setThreeSum(strandThreeData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setFourStrandNo(Math.toIntExact(strandCountMap.getOrDefault(4, 0L)));
|
|
|
+ List<BilletBasicInfo> strandFourData = filterByStrandNo(billetBasicInfoList,4);
|
|
|
+ heatsActualsInfo.setFourLength(JSON.toJSONString(groupByLength(strandFourData)));
|
|
|
+ heatsActualsInfo.setFourSum(strandFourData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setFiveStrandNo(Math.toIntExact(strandCountMap.getOrDefault(5, 0L)));
|
|
|
+ List<BilletBasicInfo> strandFiveData = filterByStrandNo(billetBasicInfoList,5);
|
|
|
+ heatsActualsInfo.setFiveLength(JSON.toJSONString(groupByLength(strandFiveData)));
|
|
|
+ heatsActualsInfo.setFiveSum(strandFiveData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setSixStrandNo(Math.toIntExact(strandCountMap.getOrDefault(6, 0L)));
|
|
|
+ List<BilletBasicInfo> strandSixData = filterByStrandNo(billetBasicInfoList,6);
|
|
|
+ heatsActualsInfo.setSixLength(JSON.toJSONString(groupByLength(strandSixData)));
|
|
|
+ heatsActualsInfo.setSixSum(strandSixData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setSevenStrandNo(Math.toIntExact(strandCountMap.getOrDefault(7, 0L)));
|
|
|
+ List<BilletBasicInfo> strandSevenData = filterByStrandNo(billetBasicInfoList,7);
|
|
|
+ heatsActualsInfo.setSevenLength(JSON.toJSONString(groupByLength(strandSevenData)));
|
|
|
+ heatsActualsInfo.setSevenSum(strandSevenData.size());
|
|
|
+
|
|
|
+ heatsActualsInfo.setEightStrandNo(Math.toIntExact(strandCountMap.getOrDefault(8, 0L)));
|
|
|
+ List<BilletBasicInfo> strandEightData = filterByStrandNo(billetBasicInfoList,8);
|
|
|
+ heatsActualsInfo.setEightLength(JSON.toJSONString(groupByLength(strandEightData)));
|
|
|
+ heatsActualsInfo.setEightSum(strandEightData.size());
|
|
|
+
|
|
|
+ // 5#直轧棒一、6#热送高线 过滤并计算
|
|
|
+ List<BilletBasicInfo> filterDirectRollingList = billetBasicInfoList.stream()
|
|
|
+ .filter(info -> "roll_club_one".equals(info.getBelongTable()) || "roll_height".equals(info.getBelongTable()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (oConvertUtils.listIsNotEmpty(filterDirectRollingList)){
|
|
|
+ // 计算总重(保留4位小数)
|
|
|
+ double totalWeight = filterDirectRollingList.stream()
|
|
|
+ .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
+ .sum();
|
|
|
+ totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
+
|
|
|
+ // 统计总数
|
|
|
+ int totalCount = filterDirectRollingList.size();
|
|
|
+
|
|
|
+ // 按定尺 length 分组统计每组数量(Long 类型)
|
|
|
+ Map<Integer, Long> lengthCountMapRaw = filterDirectRollingList.stream()
|
|
|
+ .filter(info -> info.getLength() != null)
|
|
|
+ .collect(Collectors.groupingBy(BilletBasicInfo::getLength, Collectors.counting()));
|
|
|
+
|
|
|
+ // 转换为 Map<String, Long>,确保 JSON key 是字符串
|
|
|
+ Map<String, Long> lengthCountMap = lengthCountMapRaw.entrySet().stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ e -> String.valueOf(e.getKey()), // key 转字符串
|
|
|
+ Map.Entry::getValue
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 转为JSON字符串
|
|
|
+ Map<String, Object> directRollingMap = new HashMap<>();
|
|
|
+ directRollingMap.put("directRollingTotalWeight", totalWeight);
|
|
|
+ directRollingMap.put("directRollingTotalCount", totalCount);
|
|
|
+ directRollingMap.put("lengthGroupCount", lengthCountMap); // 定尺统计结果
|
|
|
+ String jsonResult = JSON.toJSONString(directRollingMap); // 使用FastJSON转换.
|
|
|
+ heatsActualsInfo.setDirectRolling(jsonResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 堆垛过滤并计算
|
|
|
+ List<BilletBasicInfo> filterStackList = billetBasicInfoList.stream()
|
|
|
+ .filter(info -> "stacking_and_loading_vehicles".equals(info.getBelongTable()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ if (oConvertUtils.listIsNotEmpty(filterStackList)){
|
|
|
+ // 按定尺长度分组
|
|
|
+ Map<Integer, List<BilletBasicInfo>> lengthGroupMap = filterStackList.stream()
|
|
|
+ .filter(info -> info.getLength() != null)
|
|
|
+ .collect(Collectors.groupingBy(BilletBasicInfo::getLength));
|
|
|
+
|
|
|
+ // 构建分组统计结果列表
|
|
|
+ List<Map<String, Object>> lengthGroupList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (Map.Entry<Integer, List<BilletBasicInfo>> entry : lengthGroupMap.entrySet()) {
|
|
|
+ Integer length = entry.getKey();
|
|
|
+ List<BilletBasicInfo> billets = entry.getValue();
|
|
|
+
|
|
|
+ // 计算该定尺长度的总重(保留4位小数)
|
|
|
+ double lengthWeight = billets.stream()
|
|
|
+ .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
+ .sum();
|
|
|
+ lengthWeight = Math.round(lengthWeight * 10000) / 10000.0;
|
|
|
+
|
|
|
+ // 统计该定尺长度的数量
|
|
|
+ int lengthCount = billets.size();
|
|
|
+
|
|
|
+ // 构建该定尺长度的统计结果
|
|
|
+ Map<String, Object> lengthStat = new HashMap<>();
|
|
|
+ lengthStat.put("stackingWeight", lengthWeight);
|
|
|
+ lengthStat.put("stackingCount", lengthCount);
|
|
|
+ lengthStat.put("stackingLength", length);
|
|
|
+ // 添加到结果列表
|
|
|
+ lengthGroupList.add(lengthStat);
|
|
|
+ }
|
|
|
+ // 直接将列表转换为JSON
|
|
|
+ String jsonResult = JSON.toJSONString(lengthGroupList);
|
|
|
+ heatsActualsInfo.setStacking(jsonResult);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据铸机号、炉号、班组、班别查询装运单打印表
|
|
|
+ String shiftAndShiftGroup = x.getShift() + "/" + x.getShiftGroup();
|
|
|
+ String heatNo = x.getHeatNo();
|
|
|
+ // 构建安全的 JSON 路径表达式
|
|
|
+ String jsonPath = "$.\"" + heatNo + "\"";
|
|
|
+ List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(
|
|
|
+ new QueryWrapper<StorageBillPrint>()
|
|
|
+ .lambda()
|
|
|
+ .eq(StorageBillPrint::getCcmNo, x.getCcmNo())
|
|
|
+ .eq(StorageBillPrint::getClasses, shiftAndShiftGroup) // 新增的条件
|
|
|
+ .apply("JSON_EXTRACT(heat_no, '" + jsonPath + "') IS NOT NULL")
|
|
|
+ );
|
|
|
+ if (oConvertUtils.listIsNotEmpty(storageBillPrintList)){
|
|
|
+ List<Map<String, Object>> finalResult = handleStorageBillPrintHotCharge(storageBillPrintList, heatNo);
|
|
|
+ // 使用结果...
|
|
|
+ log.info("钢坯原始记录,热装打印表分组统计结果: {}", JSON.toJSONString(finalResult));
|
|
|
+ heatsActualsInfo.setHotCharge(JSON.toJSONString(finalResult));
|
|
|
+ }
|
|
|
+
|
|
|
+ // 按length字段分组,并统计每组的总数和总重
|
|
|
+ Map<Integer, Map<String, Object>> lengthResultMap = billetBasicInfoList.stream()
|
|
|
+ .filter(info -> info.getLength() != null) // 过滤掉length为null的记录
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ BilletBasicInfo::getLength, // 按length分组
|
|
|
+ Collectors.collectingAndThen(
|
|
|
+ Collectors.toList(),
|
|
|
+ list -> {
|
|
|
+ // 计算每组的总重(保留4位小数)
|
|
|
+ double totalWeight = list.stream()
|
|
|
+ .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
+ .sum();
|
|
|
+ totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
+ // 统计每组的总数
|
|
|
+ int totalCount = list.size();
|
|
|
+ // 创建每组的结果Map
|
|
|
+ Map<String, Object> groupResult = new HashMap<>();
|
|
|
+ groupResult.put("lengthTotalWeight", totalWeight);
|
|
|
+ groupResult.put("lengthTotalCount", totalCount);
|
|
|
+ //棒一统计
|
|
|
+ long rollClubOneCount = list.stream()
|
|
|
+ .filter(billet -> "roll_club_one".equals(billet.getBelongTable()))
|
|
|
+ .count();
|
|
|
+ groupResult.put("rollClubOneCount", (int) rollClubOneCount);
|
|
|
+ // 棒二统计
|
|
|
+ long rollClubTwoCount = list.stream()
|
|
|
+ .filter(billet -> "roll_club_two".equals(billet.getBelongTable()))
|
|
|
+ .count();
|
|
|
+ groupResult.put("rollClubTwoCount", (int) rollClubTwoCount);
|
|
|
+ // 棒三统计
|
|
|
+ long rollClubThreeCount = list.stream()
|
|
|
+ .filter(billet -> "roll_club_three".equals(billet.getBelongTable()))
|
|
|
+ .count();
|
|
|
+ groupResult.put("rollClubThreeCount", (int) rollClubThreeCount);
|
|
|
+ // 高线统计
|
|
|
+ long rollHeightCount = list.stream()
|
|
|
+ .filter(billet -> "roll_height".equals(billet.getBelongTable()))
|
|
|
+ .count();
|
|
|
+ groupResult.put("rollHeightCount", (int) rollHeightCount);
|
|
|
+ // 堆垛统计
|
|
|
+ long stackingAndLoadingVehiclesCount = list.stream()
|
|
|
+ .filter(billet -> "stacking_and_loading_vehicles".equals(billet.getBelongTable()))
|
|
|
+ .count();
|
|
|
+ groupResult.put("stackingAndLoadingVehiclesCount", (int) stackingAndLoadingVehiclesCount);
|
|
|
+ return groupResult;
|
|
|
+ }
|
|
|
+ )
|
|
|
+ ));
|
|
|
+ // 将Integer键转换为String键
|
|
|
+ Map<String, Map<String, Object>> stringKeyMap = lengthResultMap.entrySet().stream()
|
|
|
+ .collect(Collectors.toMap(
|
|
|
+ e -> String.valueOf(e.getKey()),
|
|
|
+ Map.Entry::getValue
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 转换为JSON字符串
|
|
|
+ String jsonResult = JSON.toJSONString(stringKeyMap);
|
|
|
+ heatsActualsInfo.setLength(jsonResult);
|
|
|
+
|
|
|
+ // 统计总数
|
|
|
+ long totalCount = billetBasicInfoList.size();
|
|
|
+
|
|
|
+ // 计算总重(保留4位小数)
|
|
|
+ double totalWeight = billetBasicInfoList.stream()
|
|
|
+ .mapToDouble(BilletBasicInfo::getBilletWeight)
|
|
|
+ .sum();
|
|
|
+ totalWeight = Math.round(totalWeight * 10000) / 10000.0;
|
|
|
+
|
|
|
+ // 转为JSON字符串
|
|
|
+ Map<String, Object> resultMap = new HashMap<>();
|
|
|
+ resultMap.put("totalCount", totalCount);
|
|
|
+ resultMap.put("totalWeight", totalWeight);
|
|
|
+ String sumJsonResult = JSON.toJSONString(resultMap); // 使用FastJSON转换
|
|
|
+ heatsActualsInfo.setTotalInfo(sumJsonResult);
|
|
|
+
|
|
|
+ heatsActualsInfoList.add(heatsActualsInfo);
|
|
|
+ });
|
|
|
+ return heatsActualsInfoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value="钢坯堆垛原始生产记录查询", notes="钢坯原始堆垛生产记录查询")
|
|
|
+ @GetMapping(value = "/queryBilletStackRecordByCcmNo")
|
|
|
+ public Result<List<BilletOriginalHeatNoDetail>> queryBilletStackRecordByCcmNo(@RequestParam(name="ccmNo", required = false) String ccmNo,
|
|
|
+ @RequestParam(name="changeShiftId", required = false) String changeShiftId,
|
|
|
+ @RequestParam(name="queryType") String queryType) {
|
|
|
+ List<BilletOriginalHeatNoDetail> billetOriginalHeatNoDetailList = new ArrayList<>();
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift;
|
|
|
+ if ("1".equals(queryType)){
|
|
|
+ String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
+ String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
+ String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
+ String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
+
|
|
|
+ if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
+ return Result.error("班组班别获取为空,钢坯堆垛原始生产记录查询失败!");
|
|
|
+ }
|
|
|
+ // 根据ccmNo、shift、shiftGroup查询最新的交班记录
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
+ .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
+ .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null){
|
|
|
+ log.info("{}{}", "钢坯堆垛原始生产记录,交班记录为空!", ccmNo + "失败时间:" + new Date());
|
|
|
+ return Result.error("交班信息为空,钢坯堆垛原始生产记录查询失败!");
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ billetHotsendChangeShift = billetHotsendChangeShiftService.getById(changeShiftId);
|
|
|
+ }
|
|
|
+
|
|
|
+ QueryWrapper<BilletOriginalProductRecord> queryWrapper3 = new QueryWrapper<>();
|
|
|
+ queryWrapper3.eq("ccm_no", ccmNo)
|
|
|
+ .eq("shift", billetHotsendChangeShift.getShift())
|
|
|
+ .eq("shift_group", billetHotsendChangeShift.getShiftGroup());
|
|
|
+ if ("1".equals(queryType)){
|
|
|
+ queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), new Date());
|
|
|
+ }else {
|
|
|
+ queryWrapper3.between("create_time", billetHotsendChangeShift.getCreateTime(), billetHotsendChangeShift.getChangeShiftTime());
|
|
|
+ }
|
|
|
+ // 通过铸机号、班组、班别、交班开始时间 查询钢坯堆垛生产原始记录
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper3);
|
|
|
+ if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
+ return Result.OK(billetOriginalHeatNoDetailList);
|
|
|
+ }
|
|
|
+ billetOriginalProductRecordList.forEach(x -> {
|
|
|
+ BilletOriginalHeatNoDetail billetOriginalHeatNoDetail = new BilletOriginalHeatNoDetail();
|
|
|
+ billetOriginalHeatNoDetail.setCcmNo(x.getCcmNo());
|
|
|
+ billetOriginalHeatNoDetail.setHeatNo(x.getHeatNo());
|
|
|
+ billetOriginalHeatNoDetail.setBrandNum(x.getGrade());
|
|
|
+ billetOriginalHeatNoDetail.setShiftGroup(x.getShiftGroup());
|
|
|
+ billetOriginalHeatNoDetail.setShift(x.getShift());
|
|
|
+ if (oConvertUtils.isNotEmpty(x.getStackLength())){
|
|
|
+ billetOriginalHeatNoDetail.setStackLength(x.getStackLength());
|
|
|
+ String stackLengthJson = x.getStackLength();
|
|
|
+ JSONArray jsonArray = JSON.parseArray(stackLengthJson);
|
|
|
+ // 初始化总数和总重
|
|
|
+ int totalCount = 0;
|
|
|
+ double totalWeight = 0.0d;
|
|
|
+ // 遍历 JSON 数组计算总数和总重
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ JSONObject item = jsonArray.getJSONObject(i);
|
|
|
+ // 获取 stackingCount 字段并累加到总数
|
|
|
+ int count = item.getIntValue("stackingCount");
|
|
|
+ // 如果 stackingCount 为 0,跳过该项
|
|
|
+ if (count == 0) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ totalCount += count;
|
|
|
+ // 获取 stackingWeight 字段并累加到总重
|
|
|
+ double weight = item.getDoubleValue("stackingWeight");
|
|
|
+ totalWeight += weight;
|
|
|
+ }
|
|
|
+ // 使用 DecimalFormat 四舍五入 保留四位小数
|
|
|
+ DecimalFormat df = new DecimalFormat("#.####");
|
|
|
+ String formattedWeight = df.format(totalWeight);
|
|
|
+ double roundedWeight = Double.parseDouble(formattedWeight);
|
|
|
+ billetOriginalHeatNoDetail.setAmountTotal(totalCount);
|
|
|
+ billetOriginalHeatNoDetail.setBlankOutput(roundedWeight);
|
|
|
+ }
|
|
|
+ billetOriginalHeatNoDetailList.add(billetOriginalHeatNoDetail);
|
|
|
+ });
|
|
|
+
|
|
|
+ return Result.OK(billetOriginalHeatNoDetailList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @ApiOperation(value="所有钢坯堆垛信息查询", notes="所有钢坯堆垛信息查询")
|
|
|
+ @GetMapping(value = "/queryBilletStackInfoByCcmNo")
|
|
|
+ public Result<List<Map<String, Object>>> queryBilletStackInfoByCcmNo(@RequestParam(name="ccmNo", required = true) String ccmNo,
|
|
|
@RequestParam(name="typeConfigId", required = true) String typeConfigId) {
|
|
|
- List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
-
|
|
|
- // 查询所有可能的位置,并按layer和address排序(低layer优先,address从1到9)
|
|
|
- List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList = stackingAndLoadingVehiclesMapper.selectList(
|
|
|
- new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
- .eq("ccm_no", ccmNo)
|
|
|
- .eq("type_config_id", typeConfigId)
|
|
|
- .isNotNull("heat_no") // 添加 heatNo 不为 null 的条件
|
|
|
- .isNotNull("size") // 添加 size 不为 null 的条件
|
|
|
- .isNotNull("billet_nos")); // 添加 billetNos 不为 null 的条件
|
|
|
- if (oConvertUtils.listIsEmpty(stackingAndLoadingVehiclesList)){
|
|
|
- return Result.OK(resultList);
|
|
|
- }
|
|
|
- // 根据 heatNo 分组
|
|
|
- Map<String, List<StackingAndLoadingVehicles>> heatNoGroupMap = stackingAndLoadingVehiclesList.stream()
|
|
|
- .collect(Collectors.groupingBy(StackingAndLoadingVehicles::getHeatNo));
|
|
|
-
|
|
|
- // 处理每个炉号分组
|
|
|
- for (Map.Entry<String, List<StackingAndLoadingVehicles>> heatNoEntry : heatNoGroupMap.entrySet()) {
|
|
|
- String heatNo = heatNoEntry.getKey();
|
|
|
- List<StackingAndLoadingVehicles> heatNoItems = heatNoEntry.getValue();
|
|
|
-
|
|
|
- // 根据 size 进一步分组
|
|
|
- Map<String, List<StackingAndLoadingVehicles>> sizeGroupMap = heatNoItems.stream()
|
|
|
- .collect(Collectors.groupingBy(StackingAndLoadingVehicles::getSize));
|
|
|
-
|
|
|
- // 初始化炉号总数量和总重量
|
|
|
- int totalCount = 0;
|
|
|
- BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
-
|
|
|
- // 构建明细列表
|
|
|
- JSONArray detailsArray = new JSONArray();
|
|
|
-
|
|
|
- // 处理每个 size 分组
|
|
|
- for (Map.Entry<String, List<StackingAndLoadingVehicles>> sizeEntry : sizeGroupMap.entrySet()) {
|
|
|
- String size = sizeEntry.getKey();
|
|
|
- List<StackingAndLoadingVehicles> sizeItems = sizeEntry.getValue();
|
|
|
-
|
|
|
- // 计算该 size 的数量(记录数)
|
|
|
- int sizeCount = sizeItems.size();
|
|
|
-
|
|
|
- // 计算单根重量:size/1000 * 4 * 0.2265
|
|
|
- BigDecimal sizeValue = new BigDecimal(size);
|
|
|
- BigDecimal singleWeight = sizeValue.divide(BigDecimal.valueOf(1000), 10, RoundingMode.HALF_UP)
|
|
|
- .multiply(BigDecimal.valueOf(4))
|
|
|
- .multiply(BigDecimal.valueOf(0.2265));
|
|
|
-
|
|
|
- // 计算该 size 的总重量
|
|
|
- BigDecimal sizeTotalWeight = singleWeight.multiply(BigDecimal.valueOf(sizeCount))
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
- // 更新炉号总数量和总重量
|
|
|
- totalCount += sizeCount;
|
|
|
- totalWeight = totalWeight.add(sizeTotalWeight);
|
|
|
-
|
|
|
- // 添加明细项
|
|
|
- JSONObject detail = new JSONObject();
|
|
|
- detail.put("stackingCount", sizeCount * 4);
|
|
|
- detail.put("stackingLength", size);
|
|
|
- detail.put("stackingWeight", sizeTotalWeight.toString());
|
|
|
- detailsArray.add(detail);
|
|
|
- }
|
|
|
-
|
|
|
- // 构建结果项
|
|
|
- Map<String, Object> resultItem = new LinkedHashMap<>();
|
|
|
- resultItem.put("heatNo", heatNo);
|
|
|
- resultItem.put("totalCount", totalCount * 4);
|
|
|
- resultItem.put("totalWeight", totalWeight.setScale(4, RoundingMode.HALF_UP).toString());
|
|
|
- resultItem.put("details", detailsArray);
|
|
|
-
|
|
|
- resultList.add(resultItem);
|
|
|
- }
|
|
|
- return Result.OK(resultList);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- private List<Map<String, Object>> handleStorageBillPrintHotCharge(List<StorageBillPrint> storageBillPrintList, String heatNo) {
|
|
|
- List<Map<String, Object>> hotChargeList = new ArrayList<>();
|
|
|
- List<Map<String, Object>> finalResult = new ArrayList<>();
|
|
|
- // 遍历列表,解析每个 heatNo JSON 并累加数量
|
|
|
- for (StorageBillPrint print : storageBillPrintList) {
|
|
|
- Map<String, Object> hotChargeMap = new HashMap<>();
|
|
|
- String jsonHeatNo = print.getHeatNo();
|
|
|
-
|
|
|
- // 初始化当前记录的数量和重量
|
|
|
- Integer currentCount = 0;
|
|
|
- BigDecimal currentWeight = BigDecimal.ZERO;
|
|
|
- // 处理可能包含逗号的定尺值
|
|
|
- String sizeValue = print.getSize();
|
|
|
- String lengthValue = "0"; // 默认值
|
|
|
-
|
|
|
- if (oConvertUtils.isNotEmpty(sizeValue)) {
|
|
|
- lengthValue = sizeValue.contains(",")
|
|
|
- ? sizeValue.split(",")[0] // 提取第一个值
|
|
|
- : sizeValue; // 否则使用原值
|
|
|
- }
|
|
|
-
|
|
|
- if (oConvertUtils.isNotEmpty(jsonHeatNo)) {
|
|
|
- try {
|
|
|
- // 解析 JSON 对象
|
|
|
- JSONObject heatNoJson = JSON.parseObject(jsonHeatNo);
|
|
|
-
|
|
|
- // 获取指定炉号对应的数量(如果存在)
|
|
|
- if (heatNoJson.containsKey(heatNo)) {
|
|
|
- Integer count = heatNoJson.getInteger(heatNo);
|
|
|
- if (count != null) {
|
|
|
- currentCount = count;
|
|
|
- // 使用 BigDecimal 计算重量,避免精度丢失
|
|
|
- BigDecimal size = new BigDecimal(lengthValue);
|
|
|
- BigDecimal factor = new BigDecimal("0.2265");
|
|
|
- currentWeight = size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
- .multiply(factor)
|
|
|
- .multiply(new BigDecimal(count))
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析 heatNo JSON 失败: {}", jsonHeatNo, e);
|
|
|
- continue; // 跳过当前记录
|
|
|
- }
|
|
|
- }
|
|
|
- String btype = print.getBtype();
|
|
|
- // 设置热装信息
|
|
|
- hotChargeMap.put("hotChargeBtype", btype);
|
|
|
- hotChargeMap.put("hotChargeLength", lengthValue);
|
|
|
- hotChargeMap.put("hotChargeTotalCount", currentCount);
|
|
|
- hotChargeMap.put("hotChargeTotalWeight", currentWeight.toPlainString());
|
|
|
-
|
|
|
- // 设置目的地简称(添加默认值)
|
|
|
- String destination = "未知";
|
|
|
- if ("棒二".equals(print.getDestination())) {
|
|
|
- destination = "roll_club_two";
|
|
|
- } else if ("棒三".equals(print.getDestination())) {
|
|
|
- destination = "roll_club_three";
|
|
|
- } else if ("上若".equals(print.getDestination())) {
|
|
|
- destination = "roll_out_shipp";
|
|
|
- }
|
|
|
- hotChargeMap.put("hotChargeDestination", destination);
|
|
|
- // 将当前记录的热装信息添加到列表
|
|
|
- hotChargeList.add(hotChargeMap);
|
|
|
- }
|
|
|
- // 按 hotChargeLength 和 hotChargeDestination 分组统计
|
|
|
- Map<String, Map<String, Object>> groupedResult = new HashMap<>();
|
|
|
-
|
|
|
- if (oConvertUtils.listIsNotEmpty(hotChargeList)) {
|
|
|
- for (Map<String, Object> item : hotChargeList) {
|
|
|
- // 使用 getOrDefault 避免空指针
|
|
|
- String length = (String) item.getOrDefault("hotChargeLength", "未知");
|
|
|
- String destination = (String) item.getOrDefault("hotChargeDestination", "未知");
|
|
|
- String btype = (String) item.getOrDefault("hotChargeBtype", "未知");
|
|
|
- Integer count = (Integer) item.getOrDefault("hotChargeTotalCount", 0);
|
|
|
- BigDecimal weight = new BigDecimal(item.getOrDefault("hotChargeTotalWeight", "0").toString());
|
|
|
-
|
|
|
- // **修改分组键:添加 btype**
|
|
|
- String groupKey = length + "_" + destination + "_" + btype;
|
|
|
-
|
|
|
- // 初始化或获取分组统计结果
|
|
|
- groupedResult.computeIfAbsent(groupKey, k -> {
|
|
|
- Map<String, Object> groupData = new HashMap<>();
|
|
|
- groupData.put("hotChargeLength", length);
|
|
|
- groupData.put("hotChargeDestination", destination);
|
|
|
- groupData.put("hotChargeBtype", btype); // **添加 btype 到分组数据**
|
|
|
- groupData.put("totalCount", 0);
|
|
|
- groupData.put("totalWeight", BigDecimal.ZERO);
|
|
|
- return groupData;
|
|
|
- });
|
|
|
-
|
|
|
- // 累加数量和重量
|
|
|
- Map<String, Object> groupData = groupedResult.get(groupKey);
|
|
|
- Integer totalCount = (Integer) groupData.get("totalCount") + count;
|
|
|
- BigDecimal totalWeight = ((BigDecimal) groupData.get("totalWeight")).add(weight);
|
|
|
-
|
|
|
- groupData.put("totalCount", totalCount);
|
|
|
- groupData.put("totalWeight", totalWeight);
|
|
|
-
|
|
|
- }
|
|
|
- // 转换为列表并格式化重量
|
|
|
- finalResult = groupedResult.values().stream()
|
|
|
- .peek(data -> {
|
|
|
- // 格式化重量为字符串,保留4位小数
|
|
|
- data.put("totalWeight", ((BigDecimal) data.get("totalWeight")).toPlainString());
|
|
|
- }).collect(Collectors.toList());
|
|
|
- }
|
|
|
- return finalResult;
|
|
|
- }
|
|
|
-
|
|
|
- @ApiOperation(value="钢坯棒一棒二棒三上若高线统计明细查询", notes="钢坯棒一棒二棒三上若统计明细查询")
|
|
|
- @GetMapping(value = "/queryBilletStatisticsDetailByCcmNo")
|
|
|
- public Result<List<BilletDetailsInfo>> queryBilletStatisticsDetailByCcmNo(@RequestParam(name="ccmNo") String ccmNo,
|
|
|
- @RequestParam(name="changeShiftId", required = false, defaultValue = "") String changeShiftId,
|
|
|
- @RequestParam(name="queryDate", required = false, defaultValue = "") String queryDate,
|
|
|
- @RequestParam(name="startTime", required = false, defaultValue = "") String startTime,
|
|
|
- @RequestParam(name="endTime", required = false, defaultValue = "") String endTime,
|
|
|
- @RequestParam(name="queryType") String queryType,
|
|
|
- @RequestParam(name="heatNo", required = false, defaultValue = "") String heatNo,
|
|
|
- @RequestParam(name = "size", required = false, defaultValue = "") String size,
|
|
|
- @RequestParam(name = "btype", required = false, defaultValue = "") String btype,
|
|
|
- @RequestParam(name = "brandNum", required = false, defaultValue = "") String brandNum,
|
|
|
- @RequestParam(name="licensePlate", required = false, defaultValue = "") String licensePlate) {
|
|
|
- List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
- if (queryType.equals("1") || queryType.equals("5")){
|
|
|
- // 查询5号机棒一、6号机高线,指定日期的统计明细
|
|
|
- billetDetailsInfoList = queryRollClubOneStatistics(ccmNo, changeShiftId, queryDate, heatNo, startTime, endTime);
|
|
|
- }else if(queryType.equals("2")){ // 查询棒二,指定班次的统计明细
|
|
|
- billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "棒二", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
- }else if(queryType.equals("3")){ // 查询棒三,指定班次的统计明细
|
|
|
- billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "棒三", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
- }else if(queryType.equals("4")){ // 查询上若,指定班次的统计明细
|
|
|
- billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "上若", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
- }
|
|
|
- return Result.OK(billetDetailsInfoList);
|
|
|
- }
|
|
|
-
|
|
|
- @ApiOperation(value="推钢室当班炉次浇筑信息查询", notes="推钢室当班炉次浇筑信息查询")
|
|
|
- @GetMapping(value = "/queryOriginalHeatInfoByCcmNo")
|
|
|
- public Result<BilletOriginalInfo> queryHeatsActualsByCcmNo(@RequestParam(name="ccmNo", required = true) String ccmNo) {
|
|
|
- BilletOriginalInfo billetOriginalInfo = new BilletOriginalInfo();
|
|
|
- String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
- String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
- String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
- String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
-
|
|
|
- if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
- return Result.error("班组班别获取为空,查询失败!");
|
|
|
- }
|
|
|
+ List<Map<String, Object>> resultList = new ArrayList<>();
|
|
|
+
|
|
|
+ // 查询所有可能的位置,并按layer和address排序(低layer优先,address从1到9)
|
|
|
+ List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList = stackingAndLoadingVehiclesMapper.selectList(
|
|
|
+ new QueryWrapper<StackingAndLoadingVehicles>()
|
|
|
+ .eq("ccm_no", ccmNo)
|
|
|
+ .eq("type_config_id", typeConfigId)
|
|
|
+ .isNotNull("heat_no") // 添加 heatNo 不为 null 的条件
|
|
|
+ .isNotNull("size") // 添加 size 不为 null 的条件
|
|
|
+ .isNotNull("billet_nos")); // 添加 billetNos 不为 null 的条件
|
|
|
+ if (oConvertUtils.listIsEmpty(stackingAndLoadingVehiclesList)){
|
|
|
+ return Result.OK(resultList);
|
|
|
+ }
|
|
|
+ // 根据 heatNo 分组
|
|
|
+ Map<String, List<StackingAndLoadingVehicles>> heatNoGroupMap = stackingAndLoadingVehiclesList.stream()
|
|
|
+ .collect(Collectors.groupingBy(StackingAndLoadingVehicles::getHeatNo));
|
|
|
+
|
|
|
+ // 处理每个炉号分组
|
|
|
+ for (Map.Entry<String, List<StackingAndLoadingVehicles>> heatNoEntry : heatNoGroupMap.entrySet()) {
|
|
|
+ String heatNo = heatNoEntry.getKey();
|
|
|
+ List<StackingAndLoadingVehicles> heatNoItems = heatNoEntry.getValue();
|
|
|
+
|
|
|
+ // 根据 size 进一步分组
|
|
|
+ Map<String, List<StackingAndLoadingVehicles>> sizeGroupMap = heatNoItems.stream()
|
|
|
+ .collect(Collectors.groupingBy(StackingAndLoadingVehicles::getSize));
|
|
|
+
|
|
|
+ // 初始化炉号总数量和总重量
|
|
|
+ int totalCount = 0;
|
|
|
+ BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 构建明细列表
|
|
|
+ JSONArray detailsArray = new JSONArray();
|
|
|
+
|
|
|
+ // 处理每个 size 分组
|
|
|
+ for (Map.Entry<String, List<StackingAndLoadingVehicles>> sizeEntry : sizeGroupMap.entrySet()) {
|
|
|
+ String size = sizeEntry.getKey();
|
|
|
+ List<StackingAndLoadingVehicles> sizeItems = sizeEntry.getValue();
|
|
|
+
|
|
|
+ // 计算该 size 的数量(记录数)
|
|
|
+ int sizeCount = sizeItems.size();
|
|
|
+
|
|
|
+ // 计算单根重量:size/1000 * 4 * 0.2265
|
|
|
+ BigDecimal sizeValue = new BigDecimal(size);
|
|
|
+ BigDecimal singleWeight = sizeValue.divide(BigDecimal.valueOf(1000), 10, RoundingMode.HALF_UP)
|
|
|
+ .multiply(BigDecimal.valueOf(4))
|
|
|
+ .multiply(BigDecimal.valueOf(0.2265));
|
|
|
+
|
|
|
+ // 计算该 size 的总重量
|
|
|
+ BigDecimal sizeTotalWeight = singleWeight.multiply(BigDecimal.valueOf(sizeCount))
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 更新炉号总数量和总重量
|
|
|
+ totalCount += sizeCount;
|
|
|
+ totalWeight = totalWeight.add(sizeTotalWeight);
|
|
|
+
|
|
|
+ // 添加明细项
|
|
|
+ JSONObject detail = new JSONObject();
|
|
|
+ detail.put("stackingCount", sizeCount * 4);
|
|
|
+ detail.put("stackingLength", size);
|
|
|
+ detail.put("stackingWeight", sizeTotalWeight.toString());
|
|
|
+ detailsArray.add(detail);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建结果项
|
|
|
+ Map<String, Object> resultItem = new LinkedHashMap<>();
|
|
|
+ resultItem.put("heatNo", heatNo);
|
|
|
+ resultItem.put("totalCount", totalCount * 4);
|
|
|
+ resultItem.put("totalWeight", totalWeight.setScale(4, RoundingMode.HALF_UP).toString());
|
|
|
+ resultItem.put("details", detailsArray);
|
|
|
+
|
|
|
+ resultList.add(resultItem);
|
|
|
+ }
|
|
|
+ return Result.OK(resultList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private List<Map<String, Object>> handleStorageBillPrintHotCharge(List<StorageBillPrint> storageBillPrintList, String heatNo) {
|
|
|
+ List<Map<String, Object>> hotChargeList = new ArrayList<>();
|
|
|
+ List<Map<String, Object>> finalResult = new ArrayList<>();
|
|
|
+ // 遍历列表,解析每个 heatNo JSON 并累加数量
|
|
|
+ for (StorageBillPrint print : storageBillPrintList) {
|
|
|
+ Map<String, Object> hotChargeMap = new HashMap<>();
|
|
|
+ String jsonHeatNo = print.getHeatNo();
|
|
|
+
|
|
|
+ // 初始化当前记录的数量和重量
|
|
|
+ Integer currentCount = 0;
|
|
|
+ BigDecimal currentWeight = BigDecimal.ZERO;
|
|
|
+ // 处理可能包含逗号的定尺值
|
|
|
+ String sizeValue = print.getSize();
|
|
|
+ String lengthValue = "0"; // 默认值
|
|
|
+
|
|
|
+ if (oConvertUtils.isNotEmpty(sizeValue)) {
|
|
|
+ lengthValue = sizeValue.contains(",")
|
|
|
+ ? sizeValue.split(",")[0] // 提取第一个值
|
|
|
+ : sizeValue; // 否则使用原值
|
|
|
+ }
|
|
|
+
|
|
|
+ if (oConvertUtils.isNotEmpty(jsonHeatNo)) {
|
|
|
+ try {
|
|
|
+ // 解析 JSON 对象
|
|
|
+ JSONObject heatNoJson = JSON.parseObject(jsonHeatNo);
|
|
|
+
|
|
|
+ // 获取指定炉号对应的数量(如果存在)
|
|
|
+ if (heatNoJson.containsKey(heatNo)) {
|
|
|
+ Integer count = heatNoJson.getInteger(heatNo);
|
|
|
+ if (count != null) {
|
|
|
+ currentCount = count;
|
|
|
+ // 使用 BigDecimal 计算重量,避免精度丢失
|
|
|
+ BigDecimal size = new BigDecimal(lengthValue);
|
|
|
+ BigDecimal factor = new BigDecimal("0.2265");
|
|
|
+ currentWeight = size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
+ .multiply(factor)
|
|
|
+ .multiply(new BigDecimal(count))
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析 heatNo JSON 失败: {}", jsonHeatNo, e);
|
|
|
+ continue; // 跳过当前记录
|
|
|
+ }
|
|
|
+ }
|
|
|
+ String btype = print.getBtype();
|
|
|
+ // 设置热装信息
|
|
|
+ hotChargeMap.put("hotChargeBtype", btype);
|
|
|
+ hotChargeMap.put("hotChargeLength", lengthValue);
|
|
|
+ hotChargeMap.put("hotChargeTotalCount", currentCount);
|
|
|
+ hotChargeMap.put("hotChargeTotalWeight", currentWeight.toPlainString());
|
|
|
+
|
|
|
+ // 设置目的地简称(添加默认值)
|
|
|
+ String destination = "未知";
|
|
|
+ if ("棒二".equals(print.getDestination())) {
|
|
|
+ destination = "roll_club_two";
|
|
|
+ } else if ("棒三".equals(print.getDestination())) {
|
|
|
+ destination = "roll_club_three";
|
|
|
+ } else if ("上若".equals(print.getDestination())) {
|
|
|
+ destination = "roll_out_shipp";
|
|
|
+ }
|
|
|
+ hotChargeMap.put("hotChargeDestination", destination);
|
|
|
+ // 将当前记录的热装信息添加到列表
|
|
|
+ hotChargeList.add(hotChargeMap);
|
|
|
+ }
|
|
|
+ // 按 hotChargeLength 和 hotChargeDestination 分组统计
|
|
|
+ Map<String, Map<String, Object>> groupedResult = new HashMap<>();
|
|
|
+
|
|
|
+ if (oConvertUtils.listIsNotEmpty(hotChargeList)) {
|
|
|
+ for (Map<String, Object> item : hotChargeList) {
|
|
|
+ // 使用 getOrDefault 避免空指针
|
|
|
+ String length = (String) item.getOrDefault("hotChargeLength", "未知");
|
|
|
+ String destination = (String) item.getOrDefault("hotChargeDestination", "未知");
|
|
|
+ String btype = (String) item.getOrDefault("hotChargeBtype", "未知");
|
|
|
+ Integer count = (Integer) item.getOrDefault("hotChargeTotalCount", 0);
|
|
|
+ BigDecimal weight = new BigDecimal(item.getOrDefault("hotChargeTotalWeight", "0").toString());
|
|
|
+
|
|
|
+ // **修改分组键:添加 btype**
|
|
|
+ String groupKey = length + "_" + destination + "_" + btype;
|
|
|
+
|
|
|
+ // 初始化或获取分组统计结果
|
|
|
+ groupedResult.computeIfAbsent(groupKey, k -> {
|
|
|
+ Map<String, Object> groupData = new HashMap<>();
|
|
|
+ groupData.put("hotChargeLength", length);
|
|
|
+ groupData.put("hotChargeDestination", destination);
|
|
|
+ groupData.put("hotChargeBtype", btype); // **添加 btype 到分组数据**
|
|
|
+ groupData.put("totalCount", 0);
|
|
|
+ groupData.put("totalWeight", BigDecimal.ZERO);
|
|
|
+ return groupData;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 累加数量和重量
|
|
|
+ Map<String, Object> groupData = groupedResult.get(groupKey);
|
|
|
+ Integer totalCount = (Integer) groupData.get("totalCount") + count;
|
|
|
+ BigDecimal totalWeight = ((BigDecimal) groupData.get("totalWeight")).add(weight);
|
|
|
+
|
|
|
+ groupData.put("totalCount", totalCount);
|
|
|
+ groupData.put("totalWeight", totalWeight);
|
|
|
+
|
|
|
+ }
|
|
|
+ // 转换为列表并格式化重量
|
|
|
+ finalResult = groupedResult.values().stream()
|
|
|
+ .peek(data -> {
|
|
|
+ // 格式化重量为字符串,保留4位小数
|
|
|
+ data.put("totalWeight", ((BigDecimal) data.get("totalWeight")).toPlainString());
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ return finalResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value="钢坯棒一棒二棒三上若高线统计明细查询", notes="钢坯棒一棒二棒三上若统计明细查询")
|
|
|
+ @GetMapping(value = "/queryBilletStatisticsDetailByCcmNo")
|
|
|
+ public Result<List<BilletDetailsInfo>> queryBilletStatisticsDetailByCcmNo(@RequestParam(name="ccmNo") String ccmNo,
|
|
|
+ @RequestParam(name="changeShiftId", required = false, defaultValue = "") String changeShiftId,
|
|
|
+ @RequestParam(name="queryDate", required = false, defaultValue = "") String queryDate,
|
|
|
+ @RequestParam(name="startTime", required = false, defaultValue = "") String startTime,
|
|
|
+ @RequestParam(name="endTime", required = false, defaultValue = "") String endTime,
|
|
|
+ @RequestParam(name="queryType") String queryType,
|
|
|
+ @RequestParam(name="heatNo", required = false, defaultValue = "") String heatNo,
|
|
|
+ @RequestParam(name = "size", required = false, defaultValue = "") String size,
|
|
|
+ @RequestParam(name = "btype", required = false, defaultValue = "") String btype,
|
|
|
+ @RequestParam(name = "brandNum", required = false, defaultValue = "") String brandNum,
|
|
|
+ @RequestParam(name="licensePlate", required = false, defaultValue = "") String licensePlate) {
|
|
|
+ List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
+ if (queryType.equals("1") || queryType.equals("5")){
|
|
|
+ // 查询5号机棒一、6号机高线,指定日期的统计明细
|
|
|
+ billetDetailsInfoList = queryRollClubOneStatistics(ccmNo, changeShiftId, queryDate, heatNo, startTime, endTime);
|
|
|
+ }else if(queryType.equals("2")){ // 查询棒二,指定班次的统计明细
|
|
|
+ billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "棒二", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
+ }else if(queryType.equals("3")){ // 查询棒三,指定班次的统计明细
|
|
|
+ billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "棒三", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
+ }else if(queryType.equals("4")){ // 查询上若,指定班次的统计明细
|
|
|
+ billetDetailsInfoList = querSstorageBillPrintStatistics(ccmNo, "上若", queryDate, changeShiftId, heatNo, licensePlate, startTime, endTime, size, btype, brandNum);
|
|
|
+ }
|
|
|
+ return Result.OK(billetDetailsInfoList);
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value="推钢室当班炉次浇筑信息查询", notes="推钢室当班炉次浇筑信息查询")
|
|
|
+ @GetMapping(value = "/queryOriginalHeatInfoByCcmNo")
|
|
|
+ public Result<BilletOriginalInfo> queryHeatsActualsByCcmNo(@RequestParam(name="ccmNo", required = true) String ccmNo) {
|
|
|
+ BilletOriginalInfo billetOriginalInfo = new BilletOriginalInfo();
|
|
|
+ String classShiftGroup = String.format("class:shift:group:%s", ccmNo); // 班组
|
|
|
+ String classShift = String.format("class:shift:%s",ccmNo); // 班别
|
|
|
+ String shift = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShift)) : "";
|
|
|
+ String shiftGroup = !oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(classShiftGroup)) : "";
|
|
|
+
|
|
|
+ if (oConvertUtils.isEmpty(shiftGroup) || oConvertUtils.isEmpty(shift)){
|
|
|
+ return Result.error("班组班别获取为空,查询失败!");
|
|
|
+ }
|
|
|
// 根据ccmNo、shift、shiftGroup查询最新的交班记录
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
- .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
- .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
- .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (billetHotsendChangeShift == null){
|
|
|
- return Result.error("交班记录为空,查询失败!");
|
|
|
- }
|
|
|
-
|
|
|
- Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endTime = new Date();
|
|
|
-
|
|
|
- // 通过铸机号、开始时间、结束时间查询 钢坯原始生产记录
|
|
|
- QueryWrapper<BilletOriginalProductRecord> queryWrapper1 = new QueryWrapper<>();
|
|
|
- queryWrapper1.eq("ccm_no", ccmNo);
|
|
|
- queryWrapper1.eq("shift", shift);
|
|
|
- queryWrapper1.eq("shift_group", shiftGroup);
|
|
|
- queryWrapper1.between("create_time", startTime, endTime);
|
|
|
- queryWrapper1.orderByDesc("create_time");
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper1);
|
|
|
- if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
- return Result.OK(billetOriginalInfo);
|
|
|
- }
|
|
|
- String directRollingJson = calculateDirectRollingStatistics(billetOriginalProductRecordList);
|
|
|
- // 统计5#直轧棒一、6#热送高线
|
|
|
- billetOriginalInfo.setDirectRolling(directRollingJson);
|
|
|
-
|
|
|
- // 根据铸机号、开始时间、结束时间查询查询装运单打印表
|
|
|
- String hotChargeJson = "";
|
|
|
- String shiftAndShiftGroup = shift + "/" + shiftGroup;
|
|
|
- LambdaQueryWrapper<StorageBillPrint> querySbWrapper = new LambdaQueryWrapper<>();
|
|
|
- querySbWrapper.eq(StorageBillPrint::getCcmNo, ccmNo)
|
|
|
- .eq(StorageBillPrint::getClasses, shiftAndShiftGroup)
|
|
|
- .between(StorageBillPrint::getCreateTime, startTime, endTime)
|
|
|
- .orderByDesc(StorageBillPrint::getCreateTime);
|
|
|
- List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(querySbWrapper);
|
|
|
- if (oConvertUtils.listIsNotEmpty(storageBillPrintList)) {
|
|
|
- hotChargeJson = calculateHotChargeStatistics(storageBillPrintList);
|
|
|
- // 统计热装
|
|
|
- billetOriginalInfo.setHotCharge(hotChargeJson);
|
|
|
- }
|
|
|
- String stackingJson = calculateStackingStatistics(billetOriginalProductRecordList);
|
|
|
- // 统计堆垛
|
|
|
- billetOriginalInfo.setStacking(stackingJson);
|
|
|
-
|
|
|
- // 计算总重量
|
|
|
- double totalWeight = calculateTotalWeight(directRollingJson, hotChargeJson, stackingJson);
|
|
|
- billetOriginalInfo.setBlankOutputs(totalWeight);
|
|
|
-
|
|
|
- String brandNum = String.format("billet:basic:info:brand:num:%s", ccmNo); // 牌号
|
|
|
- String brandNumStr = !oConvertUtils.getString(redisTemplate.opsForValue().get(brandNum)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(brandNum)) : "";
|
|
|
- billetOriginalInfo.setBrandNum(brandNumStr);
|
|
|
-
|
|
|
- billetOriginalInfo.setShift(shift);
|
|
|
- billetOriginalInfo.setShiftGroup(shiftGroup);
|
|
|
-
|
|
|
- // 遍历billetOriginalProductRecordList,获取BilletOriginalProductRecord中的三个json字段, hotChargeLength、stackLength、rollClubOneDetails,对所有定尺进行统计,统计出定尺、和对应的数量
|
|
|
- billetOriginalProductRecordList.forEach(y ->{
|
|
|
- Map<String, Integer> lengthCountMap = new HashMap<>();
|
|
|
- // 处理热装所有定尺字段
|
|
|
- processHotChargeLength(y.getHotChargeLength(), lengthCountMap);
|
|
|
-
|
|
|
- // 处理堆垛所有定尺字段
|
|
|
- processStackLength(y.getStackLength(), lengthCountMap);
|
|
|
-
|
|
|
- // 处理5#棒一、6#热送高线 所有定尺字段
|
|
|
- processRollClubOneDetails(y.getRollClubOneDetails(), lengthCountMap);
|
|
|
-
|
|
|
- y.setLengthDetails(JSON.toJSONString(lengthCountMap));
|
|
|
- });
|
|
|
-
|
|
|
- billetOriginalInfo.setBilletOriginalProductRecordList(billetOriginalProductRecordList);
|
|
|
- billetOriginalInfo.setTotalInfo(billetOriginalProductRecordList.stream().filter(x -> x.getAmount() != null)
|
|
|
- .mapToInt(BilletOriginalProductRecord::getAmount)
|
|
|
- .sum());
|
|
|
- return Result.OK(billetOriginalInfo);
|
|
|
- }
|
|
|
- /**
|
|
|
- * 计算5#直轧棒一、6#高线的统计信息
|
|
|
- */
|
|
|
- private String calculateDirectRollingStatistics(List<BilletOriginalProductRecord> records) {
|
|
|
- // 用于存储统计结果的Map,键为定尺,值为数量和重量
|
|
|
- Map<String, LengthStatistics> lengthStatsMap = new HashMap<>();
|
|
|
-
|
|
|
- // 遍历所有记录
|
|
|
- for (BilletOriginalProductRecord record : records) {
|
|
|
- String rollClubOneDetails = record.getRollClubOneDetails();
|
|
|
- if (oConvertUtils.isNotEmpty(rollClubOneDetails)) {
|
|
|
- try {
|
|
|
- // 解析JSON字符串
|
|
|
- JSONObject detailsJson = JSON.parseObject(rollClubOneDetails);
|
|
|
- // 获取lengthGroupCount对象
|
|
|
- JSONObject lengthGroupCount = detailsJson.getJSONObject("lengthGroupCount");
|
|
|
- if (lengthGroupCount != null) {
|
|
|
- // 遍历每个定尺及其数量
|
|
|
- for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
- String length = entry.getKey();
|
|
|
- Integer count = Integer.valueOf(entry.getValue().toString());
|
|
|
- // 累加到统计结果中
|
|
|
- lengthStatsMap.computeIfAbsent(length, k -> new LengthStatistics()).addCount(count);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析rollClubOneDetails、rollHeightDetails失败: {}", rollClubOneDetails, e);
|
|
|
- // 忽略解析失败的记录,继续处理其他记录
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 计算总重量并构建结果
|
|
|
- JSONObject resultJson = new JSONObject();
|
|
|
- JSONObject lengthGroupCountJson = new JSONObject();
|
|
|
- BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
- int totalCount = 0;
|
|
|
-
|
|
|
- // 计算每个定尺的重量并累加总重量
|
|
|
- for (Map.Entry<String, LengthStatistics> entry : lengthStatsMap.entrySet()) {
|
|
|
- String length = entry.getKey();
|
|
|
- LengthStatistics stats = entry.getValue();
|
|
|
-
|
|
|
- // 计算当前定尺的总重量
|
|
|
- BigDecimal size = new BigDecimal(length);
|
|
|
- BigDecimal weight = size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
- .multiply(new BigDecimal(stats.getCount()))
|
|
|
- .multiply(new BigDecimal("0.2265"))
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
-
|
|
|
- // 更新统计信息
|
|
|
- stats.setWeight(weight);
|
|
|
- totalWeight = totalWeight.add(weight);
|
|
|
- totalCount += stats.getCount();
|
|
|
-
|
|
|
- // 构建定尺统计JSON
|
|
|
- JSONObject lengthStatsJson = new JSONObject();
|
|
|
- lengthStatsJson.put("count", stats.getCount());
|
|
|
- lengthStatsJson.put("weight", weight.toPlainString());
|
|
|
- lengthGroupCountJson.put(length, lengthStatsJson);
|
|
|
- }
|
|
|
-
|
|
|
- // 设置最终结果
|
|
|
- resultJson.put("lengthGroupCount", lengthGroupCountJson);
|
|
|
- resultJson.put("directRollingTotalCount", totalCount);
|
|
|
- resultJson.put("directRollingTotalWeight", totalWeight.toPlainString());
|
|
|
-
|
|
|
- return resultJson.toJSONString();
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算热装的统计信息
|
|
|
- */
|
|
|
- private String calculateHotChargeStatistics(List<StorageBillPrint> storageBillPrintList) {
|
|
|
- // 用于存储统计结果的Map,键为size,值为统计信息
|
|
|
- Map<String, SizeStatistics> sizeStatsMap = new HashMap<>();
|
|
|
-
|
|
|
- // 遍历所有记录
|
|
|
- for (StorageBillPrint print : storageBillPrintList) {
|
|
|
- String size = print.getSize();
|
|
|
- if (oConvertUtils.isNotEmpty(size)) {
|
|
|
- try {
|
|
|
- // 转换为数值并验证
|
|
|
- BigDecimal sizeDecimal = new BigDecimal(size.trim());
|
|
|
-
|
|
|
- // 累加数量和计算重量
|
|
|
- sizeStatsMap.computeIfAbsent(size, k -> new SizeStatistics())
|
|
|
- .addData(1, calculateWeight(sizeDecimal, 1));
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- log.error("无效的size值: {}", size, e);
|
|
|
- // 忽略无效的size值,继续处理其他值
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 构建结果JSON (保持原有逻辑不变)
|
|
|
- JSONObject resultJson = new JSONObject();
|
|
|
- JSONObject sizeGroupJson = new JSONObject();
|
|
|
- int totalCount = 0;
|
|
|
- BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
-
|
|
|
- // 处理统计结果
|
|
|
- for (Map.Entry<String, SizeStatistics> entry : sizeStatsMap.entrySet()) {
|
|
|
- String size = entry.getKey();
|
|
|
- SizeStatistics stats = entry.getValue();
|
|
|
-
|
|
|
- // 构建单个size的统计JSON
|
|
|
- JSONObject sizeStatsJson = new JSONObject();
|
|
|
- sizeStatsJson.put("count", stats.getCount());
|
|
|
- sizeStatsJson.put("weight", stats.getWeight().toPlainString());
|
|
|
-
|
|
|
- // 添加到结果中
|
|
|
- sizeGroupJson.put(size, sizeStatsJson);
|
|
|
- totalCount += stats.getCount();
|
|
|
- totalWeight = totalWeight.add(stats.getWeight());
|
|
|
- }
|
|
|
-
|
|
|
- // 设置最终结果
|
|
|
- resultJson.put("sizeGroupCount", sizeGroupJson);
|
|
|
- resultJson.put("totalCount", totalCount);
|
|
|
- resultJson.put("totalWeight", totalWeight.toPlainString());
|
|
|
- return resultJson.toJSONString();
|
|
|
- }
|
|
|
- /**
|
|
|
- * 计算堆垛信息的统计
|
|
|
- */
|
|
|
- private String calculateStackingStatistics(List<BilletOriginalProductRecord> records) {
|
|
|
- // 用于存储统计结果的Map,键为定尺,值为统计信息
|
|
|
- Map<String, SizeStatistics> stackingStatsMap = new HashMap<>();
|
|
|
-
|
|
|
- // 遍历所有记录
|
|
|
- for (BilletOriginalProductRecord record : records) {
|
|
|
- String stackLengthJson = record.getStackLength();
|
|
|
- if (oConvertUtils.isNotEmpty(stackLengthJson)) {
|
|
|
- try {
|
|
|
- // 解析JSON数组
|
|
|
- JSONArray stackLengthArray = JSON.parseArray(stackLengthJson);
|
|
|
-
|
|
|
- // 遍历每个堆垛信息
|
|
|
- for (int i = 0; i < stackLengthArray.size(); i++) {
|
|
|
- JSONObject stackItem = stackLengthArray.getJSONObject(i);
|
|
|
-
|
|
|
- // 获取堆垛长度和数量
|
|
|
- String length = stackItem.getString("stackingLength");
|
|
|
- Integer count = stackItem.getInteger("stackingCount");
|
|
|
- BigDecimal weight = stackItem.getBigDecimal("stackingWeight");
|
|
|
-
|
|
|
- if (length != null && count != null && weight != null) {
|
|
|
- // 累加到统计结果中
|
|
|
- stackingStatsMap.computeIfAbsent(length, k -> new SizeStatistics()).addData(count, weight);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析stackLength失败: {}", stackLengthJson, e);
|
|
|
- // 忽略解析失败的记录,继续处理其他记录
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 构建结果JSON
|
|
|
- JSONObject resultJson = new JSONObject();
|
|
|
- JSONObject lengthGroupJson = new JSONObject();
|
|
|
- int totalCount = 0;
|
|
|
- BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
-
|
|
|
- // 处理统计结果
|
|
|
- for (Map.Entry<String, SizeStatistics> entry : stackingStatsMap.entrySet()) {
|
|
|
- String length = entry.getKey();
|
|
|
- SizeStatistics stats = entry.getValue();
|
|
|
-
|
|
|
- // 构建单个定尺的统计JSON
|
|
|
- JSONObject lengthStatsJson = new JSONObject();
|
|
|
- lengthStatsJson.put("count", stats.getCount());
|
|
|
- lengthStatsJson.put("weight", stats.getWeight().toPlainString());
|
|
|
-
|
|
|
- // 添加到结果中
|
|
|
- lengthGroupJson.put(length, lengthStatsJson);
|
|
|
- totalCount += stats.getCount();
|
|
|
- totalWeight = totalWeight.add(stats.getWeight());
|
|
|
- }
|
|
|
-
|
|
|
- // 设置最终结果
|
|
|
- resultJson.put("lengthGroupCount", lengthGroupJson);
|
|
|
- resultJson.put("stackingTotalCount", totalCount);
|
|
|
- resultJson.put("stackingTotalWeight", totalWeight.toPlainString());
|
|
|
-
|
|
|
- return resultJson.toJSONString();
|
|
|
- }
|
|
|
- /**
|
|
|
- * 从三个JSON中提取总重量并计算总和
|
|
|
- */
|
|
|
- private double calculateTotalWeight(String directRollingJson, String hotChargeJson, String stackingJson) {
|
|
|
- BigDecimal total = BigDecimal.ZERO;
|
|
|
- // 从直轧统计中提取总重量
|
|
|
- if (oConvertUtils.isNotEmpty(directRollingJson)) {
|
|
|
- try {
|
|
|
- JSONObject json = JSON.parseObject(directRollingJson);
|
|
|
- String weightStr = json.getString("directRollingTotalWeight");
|
|
|
- if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
- total = total.add(new BigDecimal(weightStr));
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("从directRollingJson提取总重量失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 从热装统计中提取总重量
|
|
|
- if (oConvertUtils.isNotEmpty(hotChargeJson)) {
|
|
|
- try {
|
|
|
- JSONObject json = JSON.parseObject(hotChargeJson);
|
|
|
- String weightStr = json.getString("totalWeight");
|
|
|
- if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
- total = total.add(new BigDecimal(weightStr));
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("从hotChargeJson提取总重量失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 从堆垛统计中提取总重量
|
|
|
- if (oConvertUtils.isNotEmpty(stackingJson)) {
|
|
|
- try {
|
|
|
- JSONObject json = JSON.parseObject(stackingJson);
|
|
|
- String weightStr = json.getString("stackingTotalWeight");
|
|
|
- if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
- total = total.add(new BigDecimal(weightStr));
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("从stackingJson提取总重量失败", e);
|
|
|
- }
|
|
|
- }
|
|
|
- // 转换为double类型,保留4位小数
|
|
|
- return total.setScale(4, RoundingMode.HALF_UP).doubleValue();
|
|
|
- }
|
|
|
- // 保持原有计算方法不变
|
|
|
- private BigDecimal calculateWeight(BigDecimal size, int count) {
|
|
|
- return size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
- .multiply(new BigDecimal(count))
|
|
|
- .multiply(new BigDecimal("0.2265"))
|
|
|
- .setScale(4, RoundingMode.HALF_UP);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理hotChargeLength字段,合并相同定尺
|
|
|
- */
|
|
|
- private void processHotChargeLength(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
- if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
- try {
|
|
|
- JSONArray jsonArray = JSON.parseArray(jsonStr);
|
|
|
- for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
- JSONObject item = jsonArray.getJSONObject(i);
|
|
|
- String length = item.getString("hotChargeLength");
|
|
|
- Integer count = item.getInteger("totalCount");
|
|
|
-
|
|
|
- if (length != null && count != null) {
|
|
|
- // 使用merge方法自动合并相同定尺
|
|
|
- lengthCountMap.merge(length, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析hotChargeLength失败: {}", jsonStr, e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理stackLength字段,合并相同定尺
|
|
|
- */
|
|
|
- private void processStackLength(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
- if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
- try {
|
|
|
- JSONArray jsonArray = JSON.parseArray(jsonStr);
|
|
|
- for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
- JSONObject item = jsonArray.getJSONObject(i);
|
|
|
- String length = item.getString("stackingLength");
|
|
|
- Integer count = item.getInteger("stackingCount");
|
|
|
-
|
|
|
- if (length != null && count != null) {
|
|
|
- // 使用merge方法自动合并相同定尺
|
|
|
- lengthCountMap.merge(length, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析stackLength失败: {}", jsonStr, e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理rollClubOneDetails字段,合并相同定尺
|
|
|
- */
|
|
|
- private void processRollClubOneDetails(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
- if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
- try {
|
|
|
- JSONObject jsonObj = JSON.parseObject(jsonStr);
|
|
|
- JSONObject lengthGroupCount = jsonObj.getJSONObject("lengthGroupCount");
|
|
|
-
|
|
|
- if (lengthGroupCount != null) {
|
|
|
- for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
- String length = entry.getKey();
|
|
|
- Integer count = Integer.valueOf(entry.getValue().toString());
|
|
|
-
|
|
|
- // 使用merge方法自动合并相同定尺
|
|
|
- lengthCountMap.merge(length, count, Integer::sum);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析rollClubOneDetails失败: {}", jsonStr, e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 5#棒一、6#高线统计明细查询
|
|
|
- * @param ccmNo
|
|
|
- * @param changeShiftId
|
|
|
- * @return
|
|
|
- */
|
|
|
- private List<BilletDetailsInfo> queryRollClubOneStatistics(String ccmNo, String changeShiftId, String queryDate, String heatNo, String startTimes, String endTimes) {
|
|
|
- List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
- LambdaQueryWrapper<BilletOriginalProductRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletOriginalProductRecord::getCcmNo, ccmNo);
|
|
|
- Boolean search = true; // 定义未传任何条件
|
|
|
- if(oConvertUtils.isNotEmpty(changeShiftId)) { // 班组为空取班组时间
|
|
|
- // 根据铸机号、交班记录ID,获取交班记录中的班别、班次、创建时间
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getId, changeShiftId).eq(BilletHotsendChangeShift::getCcmNo, ccmNo);
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- if (billetHotsendChangeShift == null){
|
|
|
- log.info("{}{}", "查询指定班次,交班记录为空!", ccmNo + "交班ID:" + changeShiftId);
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
- String shift = billetHotsendChangeShift.getShift();
|
|
|
- String shiftGroup = billetHotsendChangeShift.getShiftGroup();
|
|
|
- Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
- queryWrapper.eq(BilletOriginalProductRecord::getShift, shift);
|
|
|
- queryWrapper.eq(BilletOriginalProductRecord::getShiftGroup, shiftGroup);
|
|
|
- queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
- search = false;
|
|
|
- } else if(oConvertUtils.isNotEmpty(startTimes) && oConvertUtils.isNotEmpty(endTimes)){ // 时间范围
|
|
|
- queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTimes, endTimes);
|
|
|
- search = false;
|
|
|
- }
|
|
|
- if (oConvertUtils.isNotEmpty(queryDate) || search == true) { // 独立时间处理
|
|
|
- // 如果时间给了空
|
|
|
- if(oConvertUtils.isEmpty(queryDate)) { // 查询最后一个班次
|
|
|
- String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
- Date startOneTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
- // 查询最后一次交班记录时间
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- queryWrapper.ge(BilletOriginalProductRecord::getCreateTime, oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startOneTime);
|
|
|
- }else{
|
|
|
- queryDate = oConvertUtils.isNotEmpty(queryDate) ? queryDate : DateUtils.getDate("yyyy-MM-dd");
|
|
|
- Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
- Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
- queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
- }
|
|
|
- }
|
|
|
- // 炉号查询
|
|
|
- if (oConvertUtils.isNotEmpty(heatNo)) {
|
|
|
- queryWrapper.like(BilletOriginalProductRecord::getHeatNo, heatNo);
|
|
|
- }
|
|
|
-
|
|
|
- List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper);
|
|
|
- if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
- log.info("{}{}", "查询数据为空!");
|
|
|
- BilletDetailsInfo info = new BilletDetailsInfo();
|
|
|
- info.setCcmNo(ccmNo);
|
|
|
- info.setCounts(0);
|
|
|
- info.setTotalWeight(0.00);
|
|
|
- List<BilletStatisticsDetail> detailsList = new ArrayList<>();
|
|
|
- info.setBilletStatisticList(detailsList);
|
|
|
- billetDetailsInfoList.add(info);
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
- Map<String, BilletStatisticsDetail> statisticsMap = new HashMap<>();
|
|
|
-
|
|
|
- double grandTotalWeight = 0.0d;
|
|
|
-
|
|
|
- for (BilletOriginalProductRecord record : billetOriginalProductRecordList) {
|
|
|
- String rollClubOneDetails = record.getRollClubOneDetails();
|
|
|
- if (rollClubOneDetails != null && !rollClubOneDetails.isEmpty()) {
|
|
|
- try {
|
|
|
- JSONObject detailsJson = JSON.parseObject(rollClubOneDetails);
|
|
|
- JSONObject lengthGroupCount = detailsJson.getJSONObject("lengthGroupCount");
|
|
|
- if (lengthGroupCount != null) {
|
|
|
- for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
- String size = entry.getKey();
|
|
|
- // 增加类型检查,避免潜在的空指针异常
|
|
|
- int count = Integer.parseInt(entry.getValue().toString());
|
|
|
- double sizeValue = Double.parseDouble(size);
|
|
|
- updateStatistics(statisticsMap, size, count, sizeValue);
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("解析rollClubOneDetails、rollHeightDetails失败: {}", rollClubOneDetails, e);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 计算总数量和总重量
|
|
|
- int grandTotalCount = statisticsMap.values().stream()
|
|
|
- .mapToInt(BilletStatisticsDetail::getAmountTotal) // 修改为 getAmountTotal()
|
|
|
- .sum();
|
|
|
- grandTotalWeight = statisticsMap.values().stream()
|
|
|
- .mapToDouble(BilletStatisticsDetail::getBlankOutput)
|
|
|
- .sum();
|
|
|
-
|
|
|
- if (!statisticsMap.isEmpty()) {
|
|
|
- BilletDetailsInfo info = new BilletDetailsInfo();
|
|
|
- info.setCcmNo(ccmNo);
|
|
|
- info.setCounts(grandTotalCount);
|
|
|
- info.setTotalWeight(grandTotalWeight);
|
|
|
- List<BilletStatisticsDetail> detailsList = new ArrayList<>(statisticsMap.values());
|
|
|
- info.setBilletStatisticList(detailsList);
|
|
|
- billetDetailsInfoList.add(info);
|
|
|
- }
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 装运单统计明细查询
|
|
|
- * @param ccmNo
|
|
|
- * @param queryDate
|
|
|
- * @return
|
|
|
- */
|
|
|
- private List<BilletDetailsInfo> querSstorageBillPrintStatistics(String ccmNo, String destination, String queryDate, String changeShiftId, String heatNo, String licensePlate, String startTimes, String endTimes, String sizes, String btype, String brandNum) {
|
|
|
- List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
- // 根据铸机号、开始时间、结束时间查询查询装运单打印表
|
|
|
- LambdaQueryWrapper<StorageBillPrint> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(StorageBillPrint::getCcmNo, ccmNo)
|
|
|
- .eq(StorageBillPrint::getDestination, destination)
|
|
|
- .orderByDesc(StorageBillPrint::getArrivalTime);
|
|
|
- Boolean search = true; // 定义未传任何条件
|
|
|
- if(oConvertUtils.isNotEmpty(changeShiftId)) { // 班组为空取班组时间
|
|
|
- // 根据铸机号、交班记录ID,获取交班记录中的班别、班次、创建时间
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getId, changeShiftId).eq(BilletHotsendChangeShift::getCcmNo, ccmNo);
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- if (billetHotsendChangeShift == null){
|
|
|
- log.info("{}{}", "查询指定班次,交班记录为空!", ccmNo + "交班ID:" + changeShiftId);
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
- String shift = billetHotsendChangeShift.getShift();
|
|
|
- String shiftGroup = billetHotsendChangeShift.getShiftGroup();
|
|
|
- Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
- Date endTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
- String shiftAndShiftGroup = shift + "/" + shiftGroup;
|
|
|
- queryWrapper.between(StorageBillPrint::getArrivalTime, startTime, endTime).eq(StorageBillPrint::getClasses, shiftAndShiftGroup);
|
|
|
- search = false;
|
|
|
- } else if(oConvertUtils.isNotEmpty(startTimes) && oConvertUtils.isNotEmpty(endTimes)){ // 时间范围
|
|
|
- queryWrapper.between(StorageBillPrint::getArrivalTime, startTimes, endTimes);
|
|
|
- search = false;
|
|
|
- }
|
|
|
- if ((oConvertUtils.isNotEmpty(queryDate)) || search == true) { // 独立时间处理
|
|
|
- // 如果时间给了空
|
|
|
- if(oConvertUtils.isEmpty(queryDate)) { // 查询最后一个班次
|
|
|
- String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
- Date startArrivalTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
- // 查询最后一次交班记录时间
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
- changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
- // 查询确认时间为 null 或者 班次记录
|
|
|
- queryWrapper.and(wrapper ->
|
|
|
- wrapper
|
|
|
- .isNull(StorageBillPrint::getConfirmTime)
|
|
|
- .or(
|
|
|
- wrapper2 -> wrapper2
|
|
|
- .ge(StorageBillPrint::getArrivalTime, oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startArrivalTime)
|
|
|
- )
|
|
|
- );
|
|
|
- }else{
|
|
|
- Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
- Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
- queryWrapper.between(StorageBillPrint::getArrivalTime, startTime, endTime);
|
|
|
- }
|
|
|
- }
|
|
|
- // 炉号查询
|
|
|
- if (oConvertUtils.isNotEmpty(heatNo)) {
|
|
|
- queryWrapper.like(StorageBillPrint::getHeatNo, heatNo);
|
|
|
- }
|
|
|
- // 车牌号查询
|
|
|
- if (oConvertUtils.isNotEmpty(licensePlate)) {
|
|
|
- queryWrapper.eq(StorageBillPrint::getLicensePlate, licensePlate);
|
|
|
- }
|
|
|
- // 定尺
|
|
|
- if (oConvertUtils.isNotEmpty(sizes)) {
|
|
|
- queryWrapper.eq(StorageBillPrint::getSize, sizes);
|
|
|
- }
|
|
|
- // 热凉
|
|
|
- if (oConvertUtils.isNotEmpty(btype)) {
|
|
|
- queryWrapper.eq(StorageBillPrint::getBtype, btype);
|
|
|
- }
|
|
|
- // 牌号
|
|
|
- if (oConvertUtils.isNotEmpty(brandNum)) {
|
|
|
- queryWrapper.eq(StorageBillPrint::getBrandNum, brandNum);
|
|
|
- }
|
|
|
-
|
|
|
- List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(queryWrapper);
|
|
|
- if (oConvertUtils.listIsEmpty(storageBillPrintList)) {
|
|
|
- log.info("{}", "工作台统计明细查询数据为空!");
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
- // 创建并初始化BilletDetailsInfo对象
|
|
|
- BilletDetailsInfo billetDetailsInfo = new BilletDetailsInfo();
|
|
|
- billetDetailsInfo.setCcmNo(ccmNo); // 设置铸机号
|
|
|
-
|
|
|
- // 按定尺(size)分组统计
|
|
|
- Map<String, List<StorageBillPrint>> sizeGroupMap = storageBillPrintList.stream()
|
|
|
- .filter(item -> item.getSize() != null && item.getAmountTotal() != null)
|
|
|
- .collect(Collectors.groupingBy(StorageBillPrint::getSize));
|
|
|
-
|
|
|
- // 计算每个分组的统计结果
|
|
|
- List<BilletStatisticsDetail> statisticsDetails = new ArrayList<>();
|
|
|
- for (Map.Entry<String, List<StorageBillPrint>> entry : sizeGroupMap.entrySet()) {
|
|
|
- String size = entry.getKey();
|
|
|
- List<StorageBillPrint> groupItems = entry.getValue();
|
|
|
-
|
|
|
- // 计算总支数
|
|
|
- Integer totalAmount = groupItems.stream()
|
|
|
- .mapToInt(StorageBillPrint::getAmountTotal)
|
|
|
- .sum();
|
|
|
-
|
|
|
- // 计算总重量: (size/1000) * amountTotal * 0.2265,保留4位小数
|
|
|
- double totalWeight = groupItems.stream()
|
|
|
- .filter(item -> item.getAmountTotal() != null)
|
|
|
- .mapToDouble(item -> {
|
|
|
- try {
|
|
|
- double sizeValue = Double.parseDouble(size);
|
|
|
- return (sizeValue / 1000) * item.getAmountTotal() * 0.2265;
|
|
|
- } catch (NumberFormatException e) {
|
|
|
- return 0.0;
|
|
|
- }
|
|
|
- }).sum();
|
|
|
-
|
|
|
- // 保留4位小数
|
|
|
- totalWeight = Math.round(totalWeight * 10000.0) / 10000.0;
|
|
|
-
|
|
|
- // 创建统计明细对象并添加到结果列表
|
|
|
- BilletStatisticsDetail detail = new BilletStatisticsDetail(totalAmount, totalWeight, size);
|
|
|
- statisticsDetails.add(detail);
|
|
|
- }
|
|
|
-
|
|
|
- // 设置统计结果到BilletDetailsInfo对象
|
|
|
- billetDetailsInfo.setBilletStatisticList(statisticsDetails);
|
|
|
-
|
|
|
- // 计算并设置总车次、总支数和总重量
|
|
|
- billetDetailsInfo.setAllCarNum(storageBillPrintList.size()); // 总车次为记录数
|
|
|
- billetDetailsInfo.setCounts(statisticsDetails.stream().mapToInt(BilletStatisticsDetail::getAmountTotal).sum());
|
|
|
- billetDetailsInfo.setTotalWeight(statisticsDetails.stream().mapToDouble(BilletStatisticsDetail::getBlankOutput).sum());
|
|
|
-
|
|
|
- // 添加到结果列表
|
|
|
- billetDetailsInfoList.add(billetDetailsInfo);
|
|
|
-
|
|
|
- return billetDetailsInfoList;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 筛选指定流号的数据
|
|
|
- * @param billetList 钢坯信息列表
|
|
|
- * @param strandNo 流号
|
|
|
- * @return 指定流号的钢坯信息列表
|
|
|
- */
|
|
|
- private List<BilletBasicInfo> filterByStrandNo(List<BilletBasicInfo> billetList, Integer strandNo) {
|
|
|
- if (CollectionUtils.isEmpty(billetList) || strandNo == null) {
|
|
|
- return Collections.emptyList();
|
|
|
- }
|
|
|
-
|
|
|
- return billetList.stream()
|
|
|
- .filter(info -> info.getStrandNo() != null && info.getStrandNo().equals(strandNo))
|
|
|
- .collect(Collectors.toList());
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 按定尺长度分组并统计数量
|
|
|
- * @param billetList 钢坯信息列表
|
|
|
- * @return 定尺长度到数量的映射
|
|
|
- */
|
|
|
- private Map<String, Long> groupByLength(List<BilletBasicInfo> billetList) {
|
|
|
- if (CollectionUtils.isEmpty(billetList)) {
|
|
|
- return Collections.emptyMap();
|
|
|
- }
|
|
|
-
|
|
|
- return billetList.stream()
|
|
|
- .filter(info -> info.getLength() != null)
|
|
|
- .collect(Collectors.groupingBy(
|
|
|
- info -> String.valueOf(info.getLength()),
|
|
|
- Collectors.counting()
|
|
|
- ));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 将总数按顺序循环分配到指定数量的流中
|
|
|
- * @param total 总数
|
|
|
- * @param numStrands 流的数量
|
|
|
- * @return 分配结果映射(键为流的名称,值为分配的数量)
|
|
|
- */
|
|
|
- private Map<String, Integer> allocateRandomly(int total, int numStrands) {
|
|
|
- // 初始化每个流分配0个
|
|
|
- List<Integer> allocation = new ArrayList<>(Collections.nCopies(numStrands, 0));
|
|
|
-
|
|
|
- // 按顺序循环分配所有数量
|
|
|
- for (int i = 0; i < total; i++) {
|
|
|
- // 计算当前应该分配的流索引(循环使用)
|
|
|
- int index = i % numStrands;
|
|
|
- allocation.set(index, allocation.get(index) + 1);
|
|
|
- }
|
|
|
-
|
|
|
- // 构建结果映射
|
|
|
- Map<String, Integer> result = new HashMap<>();
|
|
|
- result.put("oneStrandSum", numStrands > 0 ? allocation.get(0) : 0);
|
|
|
- result.put("twoStrandSum", numStrands > 1 ? allocation.get(1) : 0);
|
|
|
- result.put("threeStrandSum", numStrands > 2 ? allocation.get(2) : 0);
|
|
|
- result.put("fourStrandSum", numStrands > 3 ? allocation.get(3) : 0);
|
|
|
- result.put("fiveStrandSum", numStrands > 4 ? allocation.get(4) : 0);
|
|
|
- result.put("sixStrandSum", numStrands > 5 ? allocation.get(5) : 0);
|
|
|
- result.put("sevenStrandSum", numStrands > 6 ? allocation.get(6) : 0);
|
|
|
- result.put("eightStrandSum", numStrands > 7 ? allocation.get(7) : 0);
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
-
|
|
|
- private void applyConfirmInfo(BilletOriginalProductRecord record, LoginUser user) {
|
|
|
- if (oConvertUtils.isNotEmpty(record.getConfirmTime())) {
|
|
|
- record.setConfirmBy(user.getRealname());
|
|
|
- record.setConfirmTime(new Date());
|
|
|
- record.setRemark(record.getRemark());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 提取的计算方法
|
|
|
- private void updateStatistics(Map<String, BilletStatisticsDetail> statisticsMap,
|
|
|
- String size, int count, double sizeValue) {
|
|
|
- statisticsMap.compute(size, (k, v) -> {
|
|
|
- // 计算weight
|
|
|
- double localWeight = (sizeValue / 1000) * count * 0.2265;
|
|
|
- localWeight = BigDecimal.valueOf(localWeight)
|
|
|
- .setScale(4, RoundingMode.HALF_UP)
|
|
|
- .doubleValue();
|
|
|
-
|
|
|
- BilletStatisticsDetail detail = v != null ? v : new BilletStatisticsDetail(count, localWeight, size);
|
|
|
-
|
|
|
- if (v != null) {
|
|
|
- detail.setAmountTotal(detail.getAmountTotal() + count);
|
|
|
- detail.setBlankOutput(detail.getBlankOutput() + localWeight);
|
|
|
- }
|
|
|
- return detail;
|
|
|
- });
|
|
|
- }
|
|
|
-
|
|
|
- private StackingAndLoadingVehicles getHighestOccupiedLayer(List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList) {
|
|
|
- return Optional.ofNullable(stackingAndLoadingVehiclesList)
|
|
|
- .filter(list -> !list.isEmpty())
|
|
|
- .map(list -> list.stream()
|
|
|
- .filter(item -> item.getBilletNos() != null && !item.getBilletNos().trim().isEmpty())
|
|
|
- .max(Comparator.comparingInt((StackingAndLoadingVehicles item) -> Integer.parseInt(item.getLayer()))
|
|
|
- .thenComparingInt(item -> Integer.parseInt(item.getAddress())))
|
|
|
- .orElseGet(() -> {
|
|
|
- // 如果没有找到已占用的位置,创建并返回第一层第一个位置的对象
|
|
|
- StackingAndLoadingVehicles defaultPosition = new StackingAndLoadingVehicles();
|
|
|
- defaultPosition.setLayer("1");
|
|
|
- defaultPosition.setAddress("1");
|
|
|
- // 设置其他必要的属性
|
|
|
- if (!stackingAndLoadingVehiclesList.isEmpty()) {
|
|
|
- StackingAndLoadingVehicles firstItem = stackingAndLoadingVehiclesList.get(0);
|
|
|
- defaultPosition.setCcmNo(firstItem.getCcmNo());
|
|
|
- defaultPosition.setTypeConfigId(firstItem.getTypeConfigId());
|
|
|
- defaultPosition.setStackAddr(firstItem.getStackAddr());
|
|
|
- }
|
|
|
- return defaultPosition;
|
|
|
- }))
|
|
|
- .orElse(null);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算下一组可用的堆垛位置
|
|
|
- * @param highAddressSALV 当前最高占用位置的对象
|
|
|
- * @param count 需要计算的位置数量
|
|
|
- * @return 包含可用位置的对象列表
|
|
|
- */
|
|
|
- private List<StackingAndLoadingVehicles> calculateNextPositions(
|
|
|
- StackingAndLoadingVehicles highAddressSALV,
|
|
|
- int count,
|
|
|
- String ccmNo,
|
|
|
- String typeConfigId) {
|
|
|
-
|
|
|
- List<StackingAndLoadingVehicles> nextPositions = new ArrayList<>();
|
|
|
-
|
|
|
- // 获取参考位置的address和layer
|
|
|
- int currentAddress = Integer.valueOf(highAddressSALV.getAddress());
|
|
|
- int currentLayer = Integer.valueOf(highAddressSALV.getLayer());
|
|
|
-
|
|
|
- // 如果参考位置为空(首次起垛),从1.1开始
|
|
|
- if (currentAddress == 0 && currentLayer == 0) {
|
|
|
- currentAddress = 1;
|
|
|
- currentLayer = 1;
|
|
|
- } else {
|
|
|
- // 从参考位置的下一个位置开始计算
|
|
|
- if (currentAddress == 9) {
|
|
|
- currentAddress = 1;
|
|
|
- currentLayer++;
|
|
|
- } else {
|
|
|
- currentAddress++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 生成指定数量的位置
|
|
|
- for (int i = 0; i < count; i++) {
|
|
|
- // 检查是否超出最大层数
|
|
|
- if (currentLayer > 20) {
|
|
|
- log.warn("已超出最大层数(20),无法生成更多位置");
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- // 创建新位置
|
|
|
- StackingAndLoadingVehicles newPosition = new StackingAndLoadingVehicles();
|
|
|
- newPosition.setCcmNo(ccmNo);
|
|
|
- newPosition.setAddress(String.valueOf(currentAddress));
|
|
|
- newPosition.setLayer(String.valueOf(currentLayer));
|
|
|
- newPosition.setTypeConfigId(typeConfigId);
|
|
|
-
|
|
|
- nextPositions.add(newPosition);
|
|
|
-
|
|
|
- // 更新下一个位置的address和layer
|
|
|
- if (currentAddress == 9) {
|
|
|
- currentAddress = 1;
|
|
|
- currentLayer++;
|
|
|
- } else {
|
|
|
- currentAddress++;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return nextPositions;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成短格式唯一坯号(炉号+铸机号+3位)
|
|
|
- * @param heatNo 炉号
|
|
|
- * @param ccmNo 连铸机号
|
|
|
- * @return 逗号分隔的四个短格式坯号
|
|
|
- */
|
|
|
- private String generateBilletNos(String heatNo, String ccmNo) {
|
|
|
- // 移除非数字字符并截取固定长度
|
|
|
- String cleanHeatNo = heatNo.replaceAll("\\D", "").substring(0, Math.min(6, heatNo.length()));
|
|
|
- String cleanCcmNo = ccmNo.replaceAll("\\D", "").substring(0, Math.min(2, ccmNo.length()));
|
|
|
-
|
|
|
- // 补零处理:炉号固定6位,铸机号固定2位
|
|
|
- cleanHeatNo = String.format("%6s", cleanHeatNo).replace(' ', '0').substring(0, 6);
|
|
|
- cleanCcmNo = String.format("%2s", cleanCcmNo).replace(' ', '0').substring(0, 2);
|
|
|
-
|
|
|
- // 生成全局唯一计数器(确保多线程安全)
|
|
|
- long counter = System.nanoTime() % 1000; // 纳秒级时间戳,精度更高
|
|
|
-
|
|
|
- // 生成四个不同的坯号
|
|
|
- List<String> billetNosList = new ArrayList<>();
|
|
|
- for (int i = 0; i < 4; i++) {
|
|
|
- // 组合因子:炉号6位+铸机号2位+3位唯一码(000-999)
|
|
|
- int uniqueCode = (int) ((counter + i) % 10000);
|
|
|
- String billetNo = cleanHeatNo + cleanCcmNo + String.format("%04d", uniqueCode);
|
|
|
- billetNosList.add(billetNo);
|
|
|
- }
|
|
|
-
|
|
|
- return String.join(",", billetNosList);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成综合唯一编码
|
|
|
- * @param date
|
|
|
- * @param ccmNo
|
|
|
- * @param shift
|
|
|
- * @param shiftGroup
|
|
|
- * @return uniqueCode
|
|
|
- */
|
|
|
- public String generateUniqueCode(Date date, String ccmNo, String shift, String shiftGroup) {
|
|
|
- // 将日期转换为指定格式的字符串
|
|
|
- String dateStr = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmss.get());
|
|
|
- // 将 shift 转换为 ShiftEnum 的名称
|
|
|
- String shiftName = ShiftEnum.fromCode(shift).name();
|
|
|
- // 将 shiftGroup 转换为 ShiftGroupEnum 的名称
|
|
|
- String shiftGroupName = ShiftGroupEnum.fromCode(shiftGroup).name();
|
|
|
- // 组合生成唯一代码
|
|
|
- String uniqueCode = dateStr + "-" + ccmNo + "#" + shiftName + "-" + shiftGroupName;
|
|
|
- return uniqueCode;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 从Redis中获取班组班别
|
|
|
- * @param ccmNo
|
|
|
- * @param keyFormat
|
|
|
- * @return
|
|
|
- */
|
|
|
- private String getShiftInfo(String ccmNo, String keyFormat) {
|
|
|
- String key = String.format(keyFormat, ccmNo);
|
|
|
- return oConvertUtils.getString(redisTemplate.opsForValue().get(key));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新交班记录
|
|
|
- * @param ccmNo
|
|
|
- * @param shiftGroup
|
|
|
- * @param shift
|
|
|
- */
|
|
|
- private void updateBilletHotsendChangeShift(String ccmNo, String shiftGroup, String shift) {
|
|
|
- LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
- queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
- .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
- .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
- .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
- .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
- .last("limit 1");
|
|
|
- BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
- if (oConvertUtils.isEmpty(billetHotsendChangeShift)) {
|
|
|
- log.info("推钢室界面创建装运单交班记录不存在,车次数维护失败:{}", ccmNo+shiftGroup+shift);
|
|
|
- return;
|
|
|
- }
|
|
|
- billetHotsendChangeShift.setOutCarNum(billetHotsendChangeShift.getOutCarNum() + 1);
|
|
|
- billetHotsendChangeShiftService.updateById(billetHotsendChangeShift);
|
|
|
- }
|
|
|
- }
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
+ .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
+ .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null){
|
|
|
+ return Result.error("交班记录为空,查询失败!");
|
|
|
+ }
|
|
|
+
|
|
|
+ Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
+ Date endTime = new Date();
|
|
|
+
|
|
|
+ // 通过铸机号、开始时间、结束时间查询 钢坯原始生产记录
|
|
|
+ QueryWrapper<BilletOriginalProductRecord> queryWrapper1 = new QueryWrapper<>();
|
|
|
+ queryWrapper1.eq("ccm_no", ccmNo);
|
|
|
+ queryWrapper1.eq("shift", shift);
|
|
|
+ queryWrapper1.eq("shift_group", shiftGroup);
|
|
|
+ queryWrapper1.between("create_time", startTime, endTime);
|
|
|
+ queryWrapper1.orderByDesc("create_time");
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper1);
|
|
|
+ if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
+ return Result.OK(billetOriginalInfo);
|
|
|
+ }
|
|
|
+ String directRollingJson = calculateDirectRollingStatistics(billetOriginalProductRecordList);
|
|
|
+ // 统计5#直轧棒一、6#热送高线
|
|
|
+ billetOriginalInfo.setDirectRolling(directRollingJson);
|
|
|
+
|
|
|
+ // 根据铸机号、开始时间、结束时间查询查询装运单打印表
|
|
|
+ String hotChargeJson = "";
|
|
|
+ String shiftAndShiftGroup = shift + "/" + shiftGroup;
|
|
|
+ LambdaQueryWrapper<StorageBillPrint> querySbWrapper = new LambdaQueryWrapper<>();
|
|
|
+ querySbWrapper.eq(StorageBillPrint::getCcmNo, ccmNo)
|
|
|
+ .eq(StorageBillPrint::getClasses, shiftAndShiftGroup)
|
|
|
+ .between(StorageBillPrint::getCreateTime, startTime, endTime)
|
|
|
+ .orderByDesc(StorageBillPrint::getCreateTime);
|
|
|
+ List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(querySbWrapper);
|
|
|
+ if (oConvertUtils.listIsNotEmpty(storageBillPrintList)) {
|
|
|
+ hotChargeJson = calculateHotChargeStatistics(storageBillPrintList);
|
|
|
+ // 统计热装
|
|
|
+ billetOriginalInfo.setHotCharge(hotChargeJson);
|
|
|
+ }
|
|
|
+ String stackingJson = calculateStackingStatistics(billetOriginalProductRecordList);
|
|
|
+ // 统计堆垛
|
|
|
+ billetOriginalInfo.setStacking(stackingJson);
|
|
|
+
|
|
|
+ // 计算总重量
|
|
|
+ double totalWeight = calculateTotalWeight(directRollingJson, hotChargeJson, stackingJson);
|
|
|
+ billetOriginalInfo.setBlankOutputs(totalWeight);
|
|
|
+
|
|
|
+ String brandNum = String.format("billet:basic:info:brand:num:%s", ccmNo); // 牌号
|
|
|
+ String brandNumStr = !oConvertUtils.getString(redisTemplate.opsForValue().get(brandNum)).isEmpty() ? oConvertUtils.getString(redisTemplate.opsForValue().get(brandNum)) : "";
|
|
|
+ billetOriginalInfo.setBrandNum(brandNumStr);
|
|
|
+
|
|
|
+ billetOriginalInfo.setShift(shift);
|
|
|
+ billetOriginalInfo.setShiftGroup(shiftGroup);
|
|
|
+
|
|
|
+ // 遍历billetOriginalProductRecordList,获取BilletOriginalProductRecord中的三个json字段, hotChargeLength、stackLength、rollClubOneDetails,对所有定尺进行统计,统计出定尺、和对应的数量
|
|
|
+ billetOriginalProductRecordList.forEach(y ->{
|
|
|
+ Map<String, Integer> lengthCountMap = new HashMap<>();
|
|
|
+ // 处理热装所有定尺字段
|
|
|
+ processHotChargeLength(y.getHotChargeLength(), lengthCountMap);
|
|
|
+
|
|
|
+ // 处理堆垛所有定尺字段
|
|
|
+ processStackLength(y.getStackLength(), lengthCountMap);
|
|
|
+
|
|
|
+ // 处理5#棒一、6#热送高线 所有定尺字段
|
|
|
+ processRollClubOneDetails(y.getRollClubOneDetails(), lengthCountMap);
|
|
|
+
|
|
|
+ y.setLengthDetails(JSON.toJSONString(lengthCountMap));
|
|
|
+ });
|
|
|
+
|
|
|
+ billetOriginalInfo.setBilletOriginalProductRecordList(billetOriginalProductRecordList);
|
|
|
+ billetOriginalInfo.setTotalInfo(billetOriginalProductRecordList.stream().filter(x -> x.getAmount() != null)
|
|
|
+ .mapToInt(BilletOriginalProductRecord::getAmount)
|
|
|
+ .sum());
|
|
|
+ return Result.OK(billetOriginalInfo);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 计算5#直轧棒一、6#高线的统计信息
|
|
|
+ */
|
|
|
+ private String calculateDirectRollingStatistics(List<BilletOriginalProductRecord> records) {
|
|
|
+ // 用于存储统计结果的Map,键为定尺,值为数量和重量
|
|
|
+ Map<String, LengthStatistics> lengthStatsMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 遍历所有记录
|
|
|
+ for (BilletOriginalProductRecord record : records) {
|
|
|
+ String rollClubOneDetails = record.getRollClubOneDetails();
|
|
|
+ if (oConvertUtils.isNotEmpty(rollClubOneDetails)) {
|
|
|
+ try {
|
|
|
+ // 解析JSON字符串
|
|
|
+ JSONObject detailsJson = JSON.parseObject(rollClubOneDetails);
|
|
|
+ // 获取lengthGroupCount对象
|
|
|
+ JSONObject lengthGroupCount = detailsJson.getJSONObject("lengthGroupCount");
|
|
|
+ if (lengthGroupCount != null) {
|
|
|
+ // 遍历每个定尺及其数量
|
|
|
+ for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
+ String length = entry.getKey();
|
|
|
+ Integer count = Integer.valueOf(entry.getValue().toString());
|
|
|
+ // 累加到统计结果中
|
|
|
+ lengthStatsMap.computeIfAbsent(length, k -> new LengthStatistics()).addCount(count);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析rollClubOneDetails、rollHeightDetails失败: {}", rollClubOneDetails, e);
|
|
|
+ // 忽略解析失败的记录,继续处理其他记录
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算总重量并构建结果
|
|
|
+ JSONObject resultJson = new JSONObject();
|
|
|
+ JSONObject lengthGroupCountJson = new JSONObject();
|
|
|
+ BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
+ int totalCount = 0;
|
|
|
+
|
|
|
+ // 计算每个定尺的重量并累加总重量
|
|
|
+ for (Map.Entry<String, LengthStatistics> entry : lengthStatsMap.entrySet()) {
|
|
|
+ String length = entry.getKey();
|
|
|
+ LengthStatistics stats = entry.getValue();
|
|
|
+
|
|
|
+ // 计算当前定尺的总重量
|
|
|
+ BigDecimal size = new BigDecimal(length);
|
|
|
+ BigDecimal weight = size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
+ .multiply(new BigDecimal(stats.getCount()))
|
|
|
+ .multiply(new BigDecimal("0.2265"))
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
+
|
|
|
+ // 更新统计信息
|
|
|
+ stats.setWeight(weight);
|
|
|
+ totalWeight = totalWeight.add(weight);
|
|
|
+ totalCount += stats.getCount();
|
|
|
+
|
|
|
+ // 构建定尺统计JSON
|
|
|
+ JSONObject lengthStatsJson = new JSONObject();
|
|
|
+ lengthStatsJson.put("count", stats.getCount());
|
|
|
+ lengthStatsJson.put("weight", weight.toPlainString());
|
|
|
+ lengthGroupCountJson.put(length, lengthStatsJson);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置最终结果
|
|
|
+ resultJson.put("lengthGroupCount", lengthGroupCountJson);
|
|
|
+ resultJson.put("directRollingTotalCount", totalCount);
|
|
|
+ resultJson.put("directRollingTotalWeight", totalWeight.toPlainString());
|
|
|
+
|
|
|
+ return resultJson.toJSONString();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算热装的统计信息
|
|
|
+ */
|
|
|
+ private String calculateHotChargeStatistics(List<StorageBillPrint> storageBillPrintList) {
|
|
|
+ // 用于存储统计结果的Map,键为size,值为统计信息
|
|
|
+ Map<String, SizeStatistics> sizeStatsMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 遍历所有记录
|
|
|
+ for (StorageBillPrint print : storageBillPrintList) {
|
|
|
+ String size = print.getSize();
|
|
|
+ if (oConvertUtils.isNotEmpty(size)) {
|
|
|
+ try {
|
|
|
+ // 转换为数值并验证
|
|
|
+ BigDecimal sizeDecimal = new BigDecimal(size.trim());
|
|
|
+
|
|
|
+ // 累加数量和计算重量
|
|
|
+ sizeStatsMap.computeIfAbsent(size, k -> new SizeStatistics())
|
|
|
+ .addData(1, calculateWeight(sizeDecimal, 1));
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.error("无效的size值: {}", size, e);
|
|
|
+ // 忽略无效的size值,继续处理其他值
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建结果JSON (保持原有逻辑不变)
|
|
|
+ JSONObject resultJson = new JSONObject();
|
|
|
+ JSONObject sizeGroupJson = new JSONObject();
|
|
|
+ int totalCount = 0;
|
|
|
+ BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 处理统计结果
|
|
|
+ for (Map.Entry<String, SizeStatistics> entry : sizeStatsMap.entrySet()) {
|
|
|
+ String size = entry.getKey();
|
|
|
+ SizeStatistics stats = entry.getValue();
|
|
|
+
|
|
|
+ // 构建单个size的统计JSON
|
|
|
+ JSONObject sizeStatsJson = new JSONObject();
|
|
|
+ sizeStatsJson.put("count", stats.getCount());
|
|
|
+ sizeStatsJson.put("weight", stats.getWeight().toPlainString());
|
|
|
+
|
|
|
+ // 添加到结果中
|
|
|
+ sizeGroupJson.put(size, sizeStatsJson);
|
|
|
+ totalCount += stats.getCount();
|
|
|
+ totalWeight = totalWeight.add(stats.getWeight());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置最终结果
|
|
|
+ resultJson.put("sizeGroupCount", sizeGroupJson);
|
|
|
+ resultJson.put("totalCount", totalCount);
|
|
|
+ resultJson.put("totalWeight", totalWeight.toPlainString());
|
|
|
+ return resultJson.toJSONString();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 计算堆垛信息的统计
|
|
|
+ */
|
|
|
+ private String calculateStackingStatistics(List<BilletOriginalProductRecord> records) {
|
|
|
+ // 用于存储统计结果的Map,键为定尺,值为统计信息
|
|
|
+ Map<String, SizeStatistics> stackingStatsMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 遍历所有记录
|
|
|
+ for (BilletOriginalProductRecord record : records) {
|
|
|
+ String stackLengthJson = record.getStackLength();
|
|
|
+ if (oConvertUtils.isNotEmpty(stackLengthJson)) {
|
|
|
+ try {
|
|
|
+ // 解析JSON数组
|
|
|
+ JSONArray stackLengthArray = JSON.parseArray(stackLengthJson);
|
|
|
+
|
|
|
+ // 遍历每个堆垛信息
|
|
|
+ for (int i = 0; i < stackLengthArray.size(); i++) {
|
|
|
+ JSONObject stackItem = stackLengthArray.getJSONObject(i);
|
|
|
+
|
|
|
+ // 获取堆垛长度和数量
|
|
|
+ String length = stackItem.getString("stackingLength");
|
|
|
+ Integer count = stackItem.getInteger("stackingCount");
|
|
|
+ BigDecimal weight = stackItem.getBigDecimal("stackingWeight");
|
|
|
+
|
|
|
+ if (length != null && count != null && weight != null) {
|
|
|
+ // 累加到统计结果中
|
|
|
+ stackingStatsMap.computeIfAbsent(length, k -> new SizeStatistics()).addData(count, weight);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析stackLength失败: {}", stackLengthJson, e);
|
|
|
+ // 忽略解析失败的记录,继续处理其他记录
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建结果JSON
|
|
|
+ JSONObject resultJson = new JSONObject();
|
|
|
+ JSONObject lengthGroupJson = new JSONObject();
|
|
|
+ int totalCount = 0;
|
|
|
+ BigDecimal totalWeight = BigDecimal.ZERO;
|
|
|
+
|
|
|
+ // 处理统计结果
|
|
|
+ for (Map.Entry<String, SizeStatistics> entry : stackingStatsMap.entrySet()) {
|
|
|
+ String length = entry.getKey();
|
|
|
+ SizeStatistics stats = entry.getValue();
|
|
|
+
|
|
|
+ // 构建单个定尺的统计JSON
|
|
|
+ JSONObject lengthStatsJson = new JSONObject();
|
|
|
+ lengthStatsJson.put("count", stats.getCount());
|
|
|
+ lengthStatsJson.put("weight", stats.getWeight().toPlainString());
|
|
|
+
|
|
|
+ // 添加到结果中
|
|
|
+ lengthGroupJson.put(length, lengthStatsJson);
|
|
|
+ totalCount += stats.getCount();
|
|
|
+ totalWeight = totalWeight.add(stats.getWeight());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置最终结果
|
|
|
+ resultJson.put("lengthGroupCount", lengthGroupJson);
|
|
|
+ resultJson.put("stackingTotalCount", totalCount);
|
|
|
+ resultJson.put("stackingTotalWeight", totalWeight.toPlainString());
|
|
|
+
|
|
|
+ return resultJson.toJSONString();
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 从三个JSON中提取总重量并计算总和
|
|
|
+ */
|
|
|
+ private double calculateTotalWeight(String directRollingJson, String hotChargeJson, String stackingJson) {
|
|
|
+ BigDecimal total = BigDecimal.ZERO;
|
|
|
+ // 从直轧统计中提取总重量
|
|
|
+ if (oConvertUtils.isNotEmpty(directRollingJson)) {
|
|
|
+ try {
|
|
|
+ JSONObject json = JSON.parseObject(directRollingJson);
|
|
|
+ String weightStr = json.getString("directRollingTotalWeight");
|
|
|
+ if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
+ total = total.add(new BigDecimal(weightStr));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("从directRollingJson提取总重量失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从热装统计中提取总重量
|
|
|
+ if (oConvertUtils.isNotEmpty(hotChargeJson)) {
|
|
|
+ try {
|
|
|
+ JSONObject json = JSON.parseObject(hotChargeJson);
|
|
|
+ String weightStr = json.getString("totalWeight");
|
|
|
+ if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
+ total = total.add(new BigDecimal(weightStr));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("从hotChargeJson提取总重量失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 从堆垛统计中提取总重量
|
|
|
+ if (oConvertUtils.isNotEmpty(stackingJson)) {
|
|
|
+ try {
|
|
|
+ JSONObject json = JSON.parseObject(stackingJson);
|
|
|
+ String weightStr = json.getString("stackingTotalWeight");
|
|
|
+ if (oConvertUtils.isNotEmpty(weightStr)) {
|
|
|
+ total = total.add(new BigDecimal(weightStr));
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("从stackingJson提取总重量失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 转换为double类型,保留4位小数
|
|
|
+ return total.setScale(4, RoundingMode.HALF_UP).doubleValue();
|
|
|
+ }
|
|
|
+ // 保持原有计算方法不变
|
|
|
+ private BigDecimal calculateWeight(BigDecimal size, int count) {
|
|
|
+ return size.divide(new BigDecimal("1000"), 4, RoundingMode.HALF_UP)
|
|
|
+ .multiply(new BigDecimal(count))
|
|
|
+ .multiply(new BigDecimal("0.2265"))
|
|
|
+ .setScale(4, RoundingMode.HALF_UP);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理hotChargeLength字段,合并相同定尺
|
|
|
+ */
|
|
|
+ private void processHotChargeLength(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
+ if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
+ try {
|
|
|
+ JSONArray jsonArray = JSON.parseArray(jsonStr);
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ JSONObject item = jsonArray.getJSONObject(i);
|
|
|
+ String length = item.getString("hotChargeLength");
|
|
|
+ Integer count = item.getInteger("totalCount");
|
|
|
+
|
|
|
+ if (length != null && count != null) {
|
|
|
+ // 使用merge方法自动合并相同定尺
|
|
|
+ lengthCountMap.merge(length, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析hotChargeLength失败: {}", jsonStr, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理stackLength字段,合并相同定尺
|
|
|
+ */
|
|
|
+ private void processStackLength(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
+ if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
+ try {
|
|
|
+ JSONArray jsonArray = JSON.parseArray(jsonStr);
|
|
|
+ for (int i = 0; i < jsonArray.size(); i++) {
|
|
|
+ JSONObject item = jsonArray.getJSONObject(i);
|
|
|
+ String length = item.getString("stackingLength");
|
|
|
+ Integer count = item.getInteger("stackingCount");
|
|
|
+
|
|
|
+ if (length != null && count != null) {
|
|
|
+ // 使用merge方法自动合并相同定尺
|
|
|
+ lengthCountMap.merge(length, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析stackLength失败: {}", jsonStr, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理rollClubOneDetails字段,合并相同定尺
|
|
|
+ */
|
|
|
+ private void processRollClubOneDetails(String jsonStr, Map<String, Integer> lengthCountMap) {
|
|
|
+ if (oConvertUtils.isNotEmpty(jsonStr)) {
|
|
|
+ try {
|
|
|
+ JSONObject jsonObj = JSON.parseObject(jsonStr);
|
|
|
+ JSONObject lengthGroupCount = jsonObj.getJSONObject("lengthGroupCount");
|
|
|
+
|
|
|
+ if (lengthGroupCount != null) {
|
|
|
+ for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
+ String length = entry.getKey();
|
|
|
+ Integer count = Integer.valueOf(entry.getValue().toString());
|
|
|
+
|
|
|
+ // 使用merge方法自动合并相同定尺
|
|
|
+ lengthCountMap.merge(length, count, Integer::sum);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析rollClubOneDetails失败: {}", jsonStr, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 5#棒一、6#高线统计明细查询
|
|
|
+ * @param ccmNo
|
|
|
+ * @param changeShiftId
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<BilletDetailsInfo> queryRollClubOneStatistics(String ccmNo, String changeShiftId, String queryDate, String heatNo, String startTimes, String endTimes) {
|
|
|
+ List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
+ LambdaQueryWrapper<BilletOriginalProductRecord> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletOriginalProductRecord::getCcmNo, ccmNo);
|
|
|
+ Boolean search = true; // 定义未传任何条件
|
|
|
+ if(oConvertUtils.isNotEmpty(changeShiftId)) { // 班组为空取班组时间
|
|
|
+ // 根据铸机号、交班记录ID,获取交班记录中的班别、班次、创建时间
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ changeQueryWrapper.eq(BilletHotsendChangeShift::getId, changeShiftId).eq(BilletHotsendChangeShift::getCcmNo, ccmNo);
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null){
|
|
|
+ log.info("{}{}", "查询指定班次,交班记录为空!", ccmNo + "交班ID:" + changeShiftId);
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+ String shift = billetHotsendChangeShift.getShift();
|
|
|
+ String shiftGroup = billetHotsendChangeShift.getShiftGroup();
|
|
|
+ Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
+ Date endTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
+ queryWrapper.eq(BilletOriginalProductRecord::getShift, shift);
|
|
|
+ queryWrapper.eq(BilletOriginalProductRecord::getShiftGroup, shiftGroup);
|
|
|
+ queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
+ search = false;
|
|
|
+ } else if(oConvertUtils.isNotEmpty(startTimes) && oConvertUtils.isNotEmpty(endTimes)){ // 时间范围
|
|
|
+ queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTimes, endTimes);
|
|
|
+ search = false;
|
|
|
+ }
|
|
|
+ if (oConvertUtils.isNotEmpty(queryDate) || search == true) { // 独立时间处理
|
|
|
+ // 如果时间给了空
|
|
|
+ if(oConvertUtils.isEmpty(queryDate)) { // 查询最后一个班次
|
|
|
+ String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
+ Date startOneTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
+ // 查询最后一次交班记录时间
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
+ queryWrapper.ge(BilletOriginalProductRecord::getCreateTime, oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startOneTime);
|
|
|
+ }else{
|
|
|
+ queryDate = oConvertUtils.isNotEmpty(queryDate) ? queryDate : DateUtils.getDate("yyyy-MM-dd");
|
|
|
+ Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
+ Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
+ queryWrapper.between(BilletOriginalProductRecord::getCreateTime, startTime, endTime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 炉号查询
|
|
|
+ if (oConvertUtils.isNotEmpty(heatNo)) {
|
|
|
+ queryWrapper.like(BilletOriginalProductRecord::getHeatNo, heatNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<BilletOriginalProductRecord> billetOriginalProductRecordList = billetOriginalProductRecordService.list(queryWrapper);
|
|
|
+ if (oConvertUtils.listIsEmpty(billetOriginalProductRecordList)){
|
|
|
+ log.info("{}{}", "查询数据为空!");
|
|
|
+ BilletDetailsInfo info = new BilletDetailsInfo();
|
|
|
+ info.setCcmNo(ccmNo);
|
|
|
+ info.setCounts(0);
|
|
|
+ info.setTotalWeight(0.00);
|
|
|
+ List<BilletStatisticsDetail> detailsList = new ArrayList<>();
|
|
|
+ info.setBilletStatisticList(detailsList);
|
|
|
+ billetDetailsInfoList.add(info);
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+ Map<String, BilletStatisticsDetail> statisticsMap = new HashMap<>();
|
|
|
+
|
|
|
+ double grandTotalWeight = 0.0d;
|
|
|
+
|
|
|
+ for (BilletOriginalProductRecord record : billetOriginalProductRecordList) {
|
|
|
+ String rollClubOneDetails = record.getRollClubOneDetails();
|
|
|
+ if (rollClubOneDetails != null && !rollClubOneDetails.isEmpty()) {
|
|
|
+ try {
|
|
|
+ JSONObject detailsJson = JSON.parseObject(rollClubOneDetails);
|
|
|
+ JSONObject lengthGroupCount = detailsJson.getJSONObject("lengthGroupCount");
|
|
|
+ if (lengthGroupCount != null) {
|
|
|
+ for (Map.Entry<String, Object> entry : lengthGroupCount.entrySet()) {
|
|
|
+ String size = entry.getKey();
|
|
|
+ // 增加类型检查,避免潜在的空指针异常
|
|
|
+ int count = Integer.parseInt(entry.getValue().toString());
|
|
|
+ double sizeValue = Double.parseDouble(size);
|
|
|
+ updateStatistics(statisticsMap, size, count, sizeValue);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("解析rollClubOneDetails、rollHeightDetails失败: {}", rollClubOneDetails, e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算总数量和总重量
|
|
|
+ int grandTotalCount = statisticsMap.values().stream()
|
|
|
+ .mapToInt(BilletStatisticsDetail::getAmountTotal) // 修改为 getAmountTotal()
|
|
|
+ .sum();
|
|
|
+ grandTotalWeight = statisticsMap.values().stream()
|
|
|
+ .mapToDouble(BilletStatisticsDetail::getBlankOutput)
|
|
|
+ .sum();
|
|
|
+
|
|
|
+ if (!statisticsMap.isEmpty()) {
|
|
|
+ BilletDetailsInfo info = new BilletDetailsInfo();
|
|
|
+ info.setCcmNo(ccmNo);
|
|
|
+ info.setCounts(grandTotalCount);
|
|
|
+ info.setTotalWeight(grandTotalWeight);
|
|
|
+ List<BilletStatisticsDetail> detailsList = new ArrayList<>(statisticsMap.values());
|
|
|
+ info.setBilletStatisticList(detailsList);
|
|
|
+ billetDetailsInfoList.add(info);
|
|
|
+ }
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 装运单统计明细查询
|
|
|
+ * @param ccmNo
|
|
|
+ * @param queryDate
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private List<BilletDetailsInfo> querSstorageBillPrintStatistics(String ccmNo, String destination, String queryDate, String changeShiftId, String heatNo, String licensePlate, String startTimes, String endTimes, String sizes, String btype, String brandNum) {
|
|
|
+ List<BilletDetailsInfo> billetDetailsInfoList = new ArrayList<>();
|
|
|
+ // 根据铸机号、开始时间、结束时间查询查询装运单打印表
|
|
|
+ LambdaQueryWrapper<StorageBillPrint> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(StorageBillPrint::getCcmNo, ccmNo)
|
|
|
+ .eq(StorageBillPrint::getDestination, destination)
|
|
|
+ .orderByDesc(StorageBillPrint::getArrivalTime);
|
|
|
+ Boolean search = true; // 定义未传任何条件
|
|
|
+ if(oConvertUtils.isNotEmpty(changeShiftId)) { // 班组为空取班组时间
|
|
|
+ // 根据铸机号、交班记录ID,获取交班记录中的班别、班次、创建时间
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ changeQueryWrapper.eq(BilletHotsendChangeShift::getId, changeShiftId).eq(BilletHotsendChangeShift::getCcmNo, ccmNo);
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
+ if (billetHotsendChangeShift == null){
|
|
|
+ log.info("{}{}", "查询指定班次,交班记录为空!", ccmNo + "交班ID:" + changeShiftId);
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+ String shift = billetHotsendChangeShift.getShift();
|
|
|
+ String shiftGroup = billetHotsendChangeShift.getShiftGroup();
|
|
|
+ Date startTime = billetHotsendChangeShift.getCreateTime();
|
|
|
+ Date endTime = oConvertUtils.isNotEmpty(billetHotsendChangeShift.getChangeShiftTime()) ? billetHotsendChangeShift.getChangeShiftTime() : new Date();
|
|
|
+ String shiftAndShiftGroup = shift + "/" + shiftGroup;
|
|
|
+ queryWrapper.between(StorageBillPrint::getArrivalTime, startTime, endTime).eq(StorageBillPrint::getClasses, shiftAndShiftGroup);
|
|
|
+ search = false;
|
|
|
+ } else if(oConvertUtils.isNotEmpty(startTimes) && oConvertUtils.isNotEmpty(endTimes)){ // 时间范围
|
|
|
+ queryWrapper.between(StorageBillPrint::getArrivalTime, startTimes, endTimes);
|
|
|
+ search = false;
|
|
|
+ }
|
|
|
+ if ((oConvertUtils.isNotEmpty(queryDate)) || search == true) { // 独立时间处理
|
|
|
+ // 如果时间给了空
|
|
|
+ if(oConvertUtils.isEmpty(queryDate)) { // 查询最后一个班次
|
|
|
+ String nowDate = DateUtils.getDate("yyyy-MM-dd");
|
|
|
+ Date startArrivalTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(nowDate));
|
|
|
+ // 查询最后一次交班记录时间
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> changeQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ changeQueryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo).orderByDesc(BilletHotsendChangeShift::getCreateTime).last("limit 1");
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(changeQueryWrapper);
|
|
|
+ // 查询确认时间为 null 或者 班次记录
|
|
|
+ queryWrapper.and(wrapper ->
|
|
|
+ wrapper
|
|
|
+ .isNull(StorageBillPrint::getConfirmTime)
|
|
|
+ .or(
|
|
|
+ wrapper2 -> wrapper2
|
|
|
+ .ge(StorageBillPrint::getArrivalTime, oConvertUtils.isNotEmpty(billetHotsendChangeShift.getCreateTime()) ? billetHotsendChangeShift.getCreateTime() : startArrivalTime)
|
|
|
+ )
|
|
|
+ );
|
|
|
+ }else{
|
|
|
+ Date startTime = DateUtils.getStartOfDayByDate(DateUtils.getStartOfDay(queryDate));
|
|
|
+ Date endTime = DateUtils.getEndOfDayByDate(startTime);
|
|
|
+ queryWrapper.between(StorageBillPrint::getArrivalTime, startTime, endTime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 炉号查询
|
|
|
+ if (oConvertUtils.isNotEmpty(heatNo)) {
|
|
|
+ queryWrapper.like(StorageBillPrint::getHeatNo, heatNo);
|
|
|
+ }
|
|
|
+ // 车牌号查询
|
|
|
+ if (oConvertUtils.isNotEmpty(licensePlate)) {
|
|
|
+ queryWrapper.eq(StorageBillPrint::getLicensePlate, licensePlate);
|
|
|
+ }
|
|
|
+ // 定尺
|
|
|
+ if (oConvertUtils.isNotEmpty(sizes)) {
|
|
|
+ queryWrapper.eq(StorageBillPrint::getSize, sizes);
|
|
|
+ }
|
|
|
+ // 热凉
|
|
|
+ if (oConvertUtils.isNotEmpty(btype)) {
|
|
|
+ queryWrapper.eq(StorageBillPrint::getBtype, btype);
|
|
|
+ }
|
|
|
+ // 牌号
|
|
|
+ if (oConvertUtils.isNotEmpty(brandNum)) {
|
|
|
+ queryWrapper.eq(StorageBillPrint::getBrandNum, brandNum);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<StorageBillPrint> storageBillPrintList = storageBillPrintService.list(queryWrapper);
|
|
|
+ if (oConvertUtils.listIsEmpty(storageBillPrintList)) {
|
|
|
+ log.info("{}", "工作台统计明细查询数据为空!");
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+ // 创建并初始化BilletDetailsInfo对象
|
|
|
+ BilletDetailsInfo billetDetailsInfo = new BilletDetailsInfo();
|
|
|
+ billetDetailsInfo.setCcmNo(ccmNo); // 设置铸机号
|
|
|
+
|
|
|
+ // 按定尺(size)分组统计
|
|
|
+ Map<String, List<StorageBillPrint>> sizeGroupMap = storageBillPrintList.stream()
|
|
|
+ .filter(item -> item.getSize() != null && item.getAmountTotal() != null)
|
|
|
+ .collect(Collectors.groupingBy(StorageBillPrint::getSize));
|
|
|
+
|
|
|
+ // 计算每个分组的统计结果
|
|
|
+ List<BilletStatisticsDetail> statisticsDetails = new ArrayList<>();
|
|
|
+ for (Map.Entry<String, List<StorageBillPrint>> entry : sizeGroupMap.entrySet()) {
|
|
|
+ String size = entry.getKey();
|
|
|
+ List<StorageBillPrint> groupItems = entry.getValue();
|
|
|
+
|
|
|
+ // 计算总支数
|
|
|
+ Integer totalAmount = groupItems.stream()
|
|
|
+ .mapToInt(StorageBillPrint::getAmountTotal)
|
|
|
+ .sum();
|
|
|
+
|
|
|
+ // 计算总重量: (size/1000) * amountTotal * 0.2265,保留4位小数
|
|
|
+ double totalWeight = groupItems.stream()
|
|
|
+ .filter(item -> item.getAmountTotal() != null)
|
|
|
+ .mapToDouble(item -> {
|
|
|
+ try {
|
|
|
+ double sizeValue = Double.parseDouble(size);
|
|
|
+ return (sizeValue / 1000) * item.getAmountTotal() * 0.2265;
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return 0.0;
|
|
|
+ }
|
|
|
+ }).sum();
|
|
|
+
|
|
|
+ // 保留4位小数
|
|
|
+ totalWeight = Math.round(totalWeight * 10000.0) / 10000.0;
|
|
|
+
|
|
|
+ // 创建统计明细对象并添加到结果列表
|
|
|
+ BilletStatisticsDetail detail = new BilletStatisticsDetail(totalAmount, totalWeight, size);
|
|
|
+ statisticsDetails.add(detail);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置统计结果到BilletDetailsInfo对象
|
|
|
+ billetDetailsInfo.setBilletStatisticList(statisticsDetails);
|
|
|
+
|
|
|
+ // 计算并设置总车次、总支数和总重量
|
|
|
+ billetDetailsInfo.setAllCarNum(storageBillPrintList.size()); // 总车次为记录数
|
|
|
+ billetDetailsInfo.setCounts(statisticsDetails.stream().mapToInt(BilletStatisticsDetail::getAmountTotal).sum());
|
|
|
+ billetDetailsInfo.setTotalWeight(statisticsDetails.stream().mapToDouble(BilletStatisticsDetail::getBlankOutput).sum());
|
|
|
+
|
|
|
+ // 添加到结果列表
|
|
|
+ billetDetailsInfoList.add(billetDetailsInfo);
|
|
|
+
|
|
|
+ return billetDetailsInfoList;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 筛选指定流号的数据
|
|
|
+ * @param billetList 钢坯信息列表
|
|
|
+ * @param strandNo 流号
|
|
|
+ * @return 指定流号的钢坯信息列表
|
|
|
+ */
|
|
|
+ private List<BilletBasicInfo> filterByStrandNo(List<BilletBasicInfo> billetList, Integer strandNo) {
|
|
|
+ if (CollectionUtils.isEmpty(billetList) || strandNo == null) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+
|
|
|
+ return billetList.stream()
|
|
|
+ .filter(info -> info.getStrandNo() != null && info.getStrandNo().equals(strandNo))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 按定尺长度分组并统计数量
|
|
|
+ * @param billetList 钢坯信息列表
|
|
|
+ * @return 定尺长度到数量的映射
|
|
|
+ */
|
|
|
+ private Map<String, Long> groupByLength(List<BilletBasicInfo> billetList) {
|
|
|
+ if (CollectionUtils.isEmpty(billetList)) {
|
|
|
+ return Collections.emptyMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ return billetList.stream()
|
|
|
+ .filter(info -> info.getLength() != null)
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ info -> String.valueOf(info.getLength()),
|
|
|
+ Collectors.counting()
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将总数按顺序循环分配到指定数量的流中
|
|
|
+ * @param total 总数
|
|
|
+ * @param numStrands 流的数量
|
|
|
+ * @return 分配结果映射(键为流的名称,值为分配的数量)
|
|
|
+ */
|
|
|
+ private Map<String, Integer> allocateRandomly(int total, int numStrands) {
|
|
|
+ // 初始化每个流分配0个
|
|
|
+ List<Integer> allocation = new ArrayList<>(Collections.nCopies(numStrands, 0));
|
|
|
+
|
|
|
+ // 按顺序循环分配所有数量
|
|
|
+ for (int i = 0; i < total; i++) {
|
|
|
+ // 计算当前应该分配的流索引(循环使用)
|
|
|
+ int index = i % numStrands;
|
|
|
+ allocation.set(index, allocation.get(index) + 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 构建结果映射
|
|
|
+ Map<String, Integer> result = new HashMap<>();
|
|
|
+ result.put("oneStrandSum", numStrands > 0 ? allocation.get(0) : 0);
|
|
|
+ result.put("twoStrandSum", numStrands > 1 ? allocation.get(1) : 0);
|
|
|
+ result.put("threeStrandSum", numStrands > 2 ? allocation.get(2) : 0);
|
|
|
+ result.put("fourStrandSum", numStrands > 3 ? allocation.get(3) : 0);
|
|
|
+ result.put("fiveStrandSum", numStrands > 4 ? allocation.get(4) : 0);
|
|
|
+ result.put("sixStrandSum", numStrands > 5 ? allocation.get(5) : 0);
|
|
|
+ result.put("sevenStrandSum", numStrands > 6 ? allocation.get(6) : 0);
|
|
|
+ result.put("eightStrandSum", numStrands > 7 ? allocation.get(7) : 0);
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void applyConfirmInfo(BilletOriginalProductRecord record, LoginUser user) {
|
|
|
+ if (oConvertUtils.isNotEmpty(record.getConfirmTime())) {
|
|
|
+ record.setConfirmBy(user.getRealname());
|
|
|
+ record.setConfirmTime(new Date());
|
|
|
+ record.setRemark(record.getRemark());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取的计算方法
|
|
|
+ private void updateStatistics(Map<String, BilletStatisticsDetail> statisticsMap,
|
|
|
+ String size, int count, double sizeValue) {
|
|
|
+ statisticsMap.compute(size, (k, v) -> {
|
|
|
+ // 计算weight
|
|
|
+ double localWeight = (sizeValue / 1000) * count * 0.2265;
|
|
|
+ localWeight = BigDecimal.valueOf(localWeight)
|
|
|
+ .setScale(4, RoundingMode.HALF_UP)
|
|
|
+ .doubleValue();
|
|
|
+
|
|
|
+ BilletStatisticsDetail detail = v != null ? v : new BilletStatisticsDetail(count, localWeight, size);
|
|
|
+
|
|
|
+ if (v != null) {
|
|
|
+ detail.setAmountTotal(detail.getAmountTotal() + count);
|
|
|
+ detail.setBlankOutput(detail.getBlankOutput() + localWeight);
|
|
|
+ }
|
|
|
+ return detail;
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ private StackingAndLoadingVehicles getHighestOccupiedLayer(List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList) {
|
|
|
+ return Optional.ofNullable(stackingAndLoadingVehiclesList)
|
|
|
+ .filter(list -> !list.isEmpty())
|
|
|
+ .map(list -> list.stream()
|
|
|
+ .filter(item -> item.getBilletNos() != null && !item.getBilletNos().trim().isEmpty())
|
|
|
+ .max(Comparator.comparingInt((StackingAndLoadingVehicles item) -> Integer.parseInt(item.getLayer()))
|
|
|
+ .thenComparingInt(item -> Integer.parseInt(item.getAddress())))
|
|
|
+ .orElseGet(() -> {
|
|
|
+ // 如果没有找到已占用的位置,创建并返回第一层第一个位置的对象
|
|
|
+ StackingAndLoadingVehicles defaultPosition = new StackingAndLoadingVehicles();
|
|
|
+ defaultPosition.setLayer("1");
|
|
|
+ defaultPosition.setAddress("1");
|
|
|
+ // 设置其他必要的属性
|
|
|
+ if (!stackingAndLoadingVehiclesList.isEmpty()) {
|
|
|
+ StackingAndLoadingVehicles firstItem = stackingAndLoadingVehiclesList.get(0);
|
|
|
+ defaultPosition.setCcmNo(firstItem.getCcmNo());
|
|
|
+ defaultPosition.setTypeConfigId(firstItem.getTypeConfigId());
|
|
|
+ defaultPosition.setStackAddr(firstItem.getStackAddr());
|
|
|
+ }
|
|
|
+ return defaultPosition;
|
|
|
+ }))
|
|
|
+ .orElse(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算下一组可用的堆垛位置
|
|
|
+ * @param highAddressSALV 当前最高占用位置的对象
|
|
|
+ * @param count 需要计算的位置数量
|
|
|
+ * @return 包含可用位置的对象列表
|
|
|
+ */
|
|
|
+ private List<StackingAndLoadingVehicles> calculateNextPositions(
|
|
|
+ StackingAndLoadingVehicles highAddressSALV,
|
|
|
+ int count,
|
|
|
+ String ccmNo,
|
|
|
+ String typeConfigId) {
|
|
|
+
|
|
|
+ List<StackingAndLoadingVehicles> nextPositions = new ArrayList<>();
|
|
|
+
|
|
|
+ // 获取参考位置的address和layer
|
|
|
+ int currentAddress = Integer.valueOf(highAddressSALV.getAddress());
|
|
|
+ int currentLayer = Integer.valueOf(highAddressSALV.getLayer());
|
|
|
+
|
|
|
+ // 如果参考位置为空(首次起垛),从1.1开始
|
|
|
+ if (currentAddress == 0 && currentLayer == 0) {
|
|
|
+ currentAddress = 1;
|
|
|
+ currentLayer = 1;
|
|
|
+ } else {
|
|
|
+ // 从参考位置的下一个位置开始计算
|
|
|
+ if (currentAddress == 9) {
|
|
|
+ currentAddress = 1;
|
|
|
+ currentLayer++;
|
|
|
+ } else {
|
|
|
+ currentAddress++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成指定数量的位置
|
|
|
+ for (int i = 0; i < count; i++) {
|
|
|
+ // 检查是否超出最大层数
|
|
|
+ if (currentLayer > 20) {
|
|
|
+ log.warn("已超出最大层数(20),无法生成更多位置");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 创建新位置
|
|
|
+ StackingAndLoadingVehicles newPosition = new StackingAndLoadingVehicles();
|
|
|
+ newPosition.setCcmNo(ccmNo);
|
|
|
+ newPosition.setAddress(String.valueOf(currentAddress));
|
|
|
+ newPosition.setLayer(String.valueOf(currentLayer));
|
|
|
+ newPosition.setTypeConfigId(typeConfigId);
|
|
|
+
|
|
|
+ nextPositions.add(newPosition);
|
|
|
+
|
|
|
+ // 更新下一个位置的address和layer
|
|
|
+ if (currentAddress == 9) {
|
|
|
+ currentAddress = 1;
|
|
|
+ currentLayer++;
|
|
|
+ } else {
|
|
|
+ currentAddress++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return nextPositions;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成短格式唯一坯号(炉号+铸机号+3位)
|
|
|
+ * @param heatNo 炉号
|
|
|
+ * @param ccmNo 连铸机号
|
|
|
+ * @return 逗号分隔的四个短格式坯号
|
|
|
+ */
|
|
|
+ private String generateBilletNos(String heatNo, String ccmNo) {
|
|
|
+ // 移除非数字字符并截取固定长度
|
|
|
+ String cleanHeatNo = heatNo.replaceAll("\\D", "").substring(0, Math.min(6, heatNo.length()));
|
|
|
+ String cleanCcmNo = ccmNo.replaceAll("\\D", "").substring(0, Math.min(2, ccmNo.length()));
|
|
|
+
|
|
|
+ // 补零处理:炉号固定6位,铸机号固定2位
|
|
|
+ cleanHeatNo = String.format("%6s", cleanHeatNo).replace(' ', '0').substring(0, 6);
|
|
|
+ cleanCcmNo = String.format("%2s", cleanCcmNo).replace(' ', '0').substring(0, 2);
|
|
|
+
|
|
|
+ // 生成全局唯一计数器(确保多线程安全)
|
|
|
+ long counter = System.nanoTime() % 1000; // 纳秒级时间戳,精度更高
|
|
|
+
|
|
|
+ // 生成四个不同的坯号
|
|
|
+ List<String> billetNosList = new ArrayList<>();
|
|
|
+ for (int i = 0; i < 4; i++) {
|
|
|
+ // 组合因子:炉号6位+铸机号2位+3位唯一码(000-999)
|
|
|
+ int uniqueCode = (int) ((counter + i) % 10000);
|
|
|
+ String billetNo = cleanHeatNo + cleanCcmNo + String.format("%04d", uniqueCode);
|
|
|
+ billetNosList.add(billetNo);
|
|
|
+ }
|
|
|
+
|
|
|
+ return String.join(",", billetNosList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成综合唯一编码
|
|
|
+ * @param date
|
|
|
+ * @param ccmNo
|
|
|
+ * @param shift
|
|
|
+ * @param shiftGroup
|
|
|
+ * @return uniqueCode
|
|
|
+ */
|
|
|
+ public String generateUniqueCode(Date date, String ccmNo, String shift, String shiftGroup) {
|
|
|
+ // 将日期转换为指定格式的字符串
|
|
|
+ String dateStr = DateUtils.date2Str(date, DateUtils.yyyymmddhhmmss.get());
|
|
|
+ // 将 shift 转换为 ShiftEnum 的名称
|
|
|
+ String shiftName = ShiftEnum.fromCode(shift).name();
|
|
|
+ // 将 shiftGroup 转换为 ShiftGroupEnum 的名称
|
|
|
+ String shiftGroupName = ShiftGroupEnum.fromCode(shiftGroup).name();
|
|
|
+ // 组合生成唯一代码
|
|
|
+ String uniqueCode = dateStr + "-" + ccmNo + "#" + shiftName + "-" + shiftGroupName;
|
|
|
+ return uniqueCode;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 从Redis中获取班组班别
|
|
|
+ * @param ccmNo
|
|
|
+ * @param keyFormat
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private String getShiftInfo(String ccmNo, String keyFormat) {
|
|
|
+ String key = String.format(keyFormat, ccmNo);
|
|
|
+ return oConvertUtils.getString(redisTemplate.opsForValue().get(key));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 更新交班记录
|
|
|
+ * @param ccmNo
|
|
|
+ * @param shiftGroup
|
|
|
+ * @param shift
|
|
|
+ */
|
|
|
+ private void updateBilletHotsendChangeShift(String ccmNo, String shiftGroup, String shift) {
|
|
|
+ LambdaQueryWrapper<BilletHotsendChangeShift> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(BilletHotsendChangeShift::getCcmNo, ccmNo)
|
|
|
+ .eq(BilletHotsendChangeShift::getShiftGroup, shiftGroup)
|
|
|
+ .eq(BilletHotsendChangeShift::getShift, shift)
|
|
|
+ .isNull(BilletHotsendChangeShift::getChangeShiftTime)
|
|
|
+ .orderByDesc(BilletHotsendChangeShift::getCreateTime)
|
|
|
+ .last("limit 1");
|
|
|
+ BilletHotsendChangeShift billetHotsendChangeShift = billetHotsendChangeShiftService.getOne(queryWrapper);
|
|
|
+ if (oConvertUtils.isEmpty(billetHotsendChangeShift)) {
|
|
|
+ log.info("推钢室界面创建装运单交班记录不存在,车次数维护失败:{}", ccmNo+shiftGroup+shift);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ billetHotsendChangeShift.setOutCarNum(billetHotsendChangeShift.getOutCarNum() + 1);
|
|
|
+ billetHotsendChangeShiftService.updateById(billetHotsendChangeShift);
|
|
|
+ }
|
|
|
+}
|