|
@@ -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;
|
|
|
}
|
|
|
|
|
|
|