qiangxuan 3 weeks ago
parent
commit
33e7b43571

+ 153 - 84
zgztBus/jeecg-module-sbm/src/main/java/org/jeecg/modules/billet/billetOriginalProductRecord/controller/BilletOriginalProductRecordController.java

@@ -211,68 +211,120 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
 	  * @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)) : "";
+		 // 获取班次信息
+		 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;
-		 List<StackingAndLoadingVehicles> stackingAndLoadingVehiclesList = stackingAndLoadingVehiclesMapper.selectList(new QueryWrapper<StackingAndLoadingVehicles>()
-				 .eq("ccm_no", ccmNo)
-				 .eq("type_config_id", typeConfigId));
-		 boolean allBilletNosNonNull = stackingAndLoadingVehiclesList != null &&
-				 stackingAndLoadingVehiclesList.stream()
-						 .allMatch(vehicle -> vehicle.getBilletNos() != null);
-		 if (allBilletNosNonNull) {
-			 log.info("{}{}", "没有可用的堆垛容器位置,起垛失败!", heatNo);
+		 if (demandStackingSum <= 0) {
+			 log.info("起垛数量计算结果为非正数,起垛失败!heatNo={}, stackingSum={}", heatNo, stackingSum);
 			 return;
 		 }
-		 StackingAndLoadingVehicles highAddressSALV = getHighestOccupiedLayer(stackingAndLoadingVehiclesList);
-		 if (highAddressSALV == null) {
-			 log.info("{}{}", "堆垛容器空位置获取为空,起垛失败!", heatNo);
-			 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)));
 		 }
-		 if (oConvertUtils.isEmpty(highAddressSALV.getBilletNos())){
-			 // 根据铸机号、address、layer、typeConfigId查询堆垛容器位置
-			 StackingAndLoadingVehicles nextPosition = stackingAndLoadingVehiclesMapper.selectOne(new QueryWrapper<StackingAndLoadingVehicles>()
-					 .eq("ccm_no", ccmNo)
-					 .eq("address", highAddressSALV.getAddress())
-					 .eq("layer", highAddressSALV.getLayer())
-					 .eq("type_config_id", typeConfigId));
-			 nextPosition.setSize(size);
-			 nextPosition.setShift(shift);
-			 nextPosition.setShiftGroup(shiftGroup);
-			 nextPosition.setHeatNo(heatNo);
-			 nextPosition.setBilletNos(generateBilletNos(heatNo, ccmNo));
-			 stackingAndLoadingVehiclesMapper.updateById(nextPosition);
-			 return;
+
+		 // 获取所有可用的空位置(按排序后的顺序)
+		 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;
+			 }
 		 }
-		 // 以demandStackingSum的值,确定需要计算出几个位置,根据highAddressSALV中address、layer,计算下个坐标位置
-		 List<StackingAndLoadingVehicles> nextPositionsList = calculateNextPositions(highAddressSALV, demandStackingSum, ccmNo, heatNo);
 
-		 // 检查是否成功计算出位置
-		 if (nextPositionsList.isEmpty()) {
-			 log.info("{}{}", "无法计算出可用位置,起垛失败!", 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);
+			 }
 		 }
-		 nextPositionsList.forEach(x -> {
-			 // 根据铸机号、address、layer、typeConfigId查询堆垛容器位置
-			 StackingAndLoadingVehicles nextPosition = stackingAndLoadingVehiclesMapper.selectOne(new QueryWrapper<StackingAndLoadingVehicles>()
-					 .eq("ccm_no", x.getCcmNo())
-					 .eq("address", x.getAddress())
-					 .eq("layer", x.getLayer())
-					 .eq("type_config_id", x.getTypeConfigId()));
-			 x.setId(nextPosition.getId());
-			 x.setSize(size);
-			 x.setShift(shift);
-			 x.setShiftGroup(shiftGroup);
-			 x.setHeatNo(heatNo);
-			 x.setCreateTime(nextPosition.getCreateTime());
-			 x.setUpdateTime(new Date());
-			 x.setSteel("");
-			 x.setSpec("");
-			 stackingAndLoadingVehiclesMapper.updateById(x);
-		 });
 	 }
 	 /**
 	  *  编辑
@@ -1774,45 +1826,62 @@ public class BilletOriginalProductRecordController extends JeecgController<Bille
 	 /**
 	  * 计算下一组可用的堆垛位置
 	  * @param highAddressSALV 当前最高占用位置的对象
-	  * @param demandStackingSum 需要计算的位置数量
+	  * @param count 需要计算的位置数量
 	  * @return 包含可用位置的对象列表
 	  */
-	 private List<StackingAndLoadingVehicles> calculateNextPositions(StackingAndLoadingVehicles highAddressSALV, int demandStackingSum, String ccmNo, String heatNo) {
-
-		 List<StackingAndLoadingVehicles> resultPositions = new ArrayList<>();
-
-		 // 获取当前最高占用位置的坐标
-		 int currentLayer = Integer.parseInt(highAddressSALV.getLayer());
-		 int currentAddress = Integer.parseInt(highAddressSALV.getAddress());
-
-		 // 循环计算需要的位置数量
-		 for (int i = 0; i < demandStackingSum; i++) {
-			 // 计算下一个位置
-			 currentAddress++;
-			 // 如果当前位置超过每层的最大位置(9),则移动到下一层
-			 if (currentAddress > 9) {
+	 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 ++;
-				 // 检查是否超过最大层数限制
-				 if (currentLayer > 20) {
-					 log.warn("已达到最大层数限制(20层),无法继续分配位置");
-					 break;
-				 }
+				 currentLayer++;
+			 } else {
+				 currentAddress++;
 			 }
+		 }
 
-			 // 创建新的位置对象
+		 // 生成指定数量的位置
+		 for (int i = 0; i < count; i++) {
+			 // 检查是否超出最大层数
+			 if (currentLayer > 20) {
+				 log.warn("已超出最大层数(20),无法生成更多位置");
+				 break;
+			 }
+
+			 // 创建新位置
 			 StackingAndLoadingVehicles newPosition = new StackingAndLoadingVehicles();
-			 newPosition.setLayer(String.valueOf(currentLayer));
+			 newPosition.setCcmNo(ccmNo);
 			 newPosition.setAddress(String.valueOf(currentAddress));
-			 newPosition.setCcmNo(highAddressSALV.getCcmNo());
-			 newPosition.setTypeConfigId(highAddressSALV.getTypeConfigId());
-			 newPosition.setStackAddr(highAddressSALV.getStackAddr());
-			 newPosition.setBilletNos(generateBilletNos(heatNo, ccmNo));
-			 // 添加到结果列表
-			 resultPositions.add(newPosition);
+			 newPosition.setLayer(String.valueOf(currentLayer));
+			 newPosition.setTypeConfigId(typeConfigId);
+
+			 nextPositions.add(newPosition);
+
+			 // 更新下一个位置的address和layer
+			 if (currentAddress == 9) {
+				 currentAddress = 1;
+				 currentLayer++;
+			 } else {
+				 currentAddress++;
+			 }
 		 }
 
-		 return resultPositions;
+		 return nextPositions;
 	 }