fix:出库顺序逻辑优化

This commit is contained in:
zhouz
2025-09-18 10:50:29 +08:00
parent 5f109bded1
commit 91fae3177a

View File

@@ -591,6 +591,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
/**
* 拣选出库新增
*
* @param map 、
* @return 单据标识
*/
@@ -1497,6 +1498,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
/**
* 分拣出库修改
*
* @param whereJson、
*/
private void updatePic(JSONObject whereJson) {
@@ -3220,7 +3222,8 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
public void allSetPointByNoTran(JSONObject whereJson) {
String point_code = whereJson.getString("point_code"); // 终点
JSONObject jsonPoint2 = WQLObject.getWQLObject("SCH_BASE_Point").query("lock_type='1' and (vehicle_code='' or vehicle_code IS NULL) and point_code='" + whereJson.getString("point_code") + "'").uniqueResult(0);
参数校验:{
参数校验:
{
JSONObject jo_mst = WQLObject.getWQLObject("ST_IVT_IOStorInv").query("iostorinv_id = '" + whereJson.getString("iostorinv_id") + "'").uniqueResult(0);
if (ObjectUtil.isEmpty(jo_mst)) {
throw new BadRequestException("未查到相关出库单");
@@ -3272,9 +3275,45 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
StructAllsetDto left = needStructs.get(0);
StructAllsetDto right = needStructs.get(needStructs.size() - 1);
//确认左/右出库并根据出库顺序获取货位集合
List<JSONObject> structs = 左右出库确认(needStructs, left, right,whereJson.getString("iostorinv_id"));
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code,storagevehicle_code
JSONObject jsonObject = 左右出库确认(needStructs, left, right, whereJson.getString("iostorinv_id"));
List<JSONObject> structs = (List<JSONObject>) jsonObject.get("struct_list");
boolean is_all = jsonObject.getBoolean("is_all");
List<String> needStructList = needStructs.stream().map(StructAllsetDto::getStruct_code).collect(Collectors.toList());
if (is_all) {
List<String> all_struct = new ArrayList<>(structs.size());
HashMap<String, JSONObject> struct_map = new HashMap<>(structs.size());
structs.forEach(struct -> {
all_struct.add(struct.getString("struct_code"));
struct_map.put(struct.getString("struct_code"), struct);
});
List<String> move_list = moveBoxes(needStructList, all_struct);
String taskGroup = org.nl.common.utils.IdUtil.getStringId();
for (int i = 0; i < move_list.size(); i++) {
String goal_struct = move_list.get(i);
JSONObject item = struct_map.get(goal_struct);
item.put("task_group_id", taskGroup);
item.put("iostorinv_id", whereJson.getString("iostorinv_id"));
item.put("sort_seq", i);
item.put("point_code", point_code);
item.put("point_id", jsonPoint2.getString("point_id"));
String structCode = item.getString("struct_code");
if (CollectionUtils.isEmpty(needStructList)) {
break;
}
if (needStructList.contains(structCode)) {
//出库
checkOutBillService.createOut(item);
needStructList.remove(structCode);
} else {
//移库:如果当前存在业务锁定则说明存在相关任务,不需要移库,直接跳过
if (!item.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
continue;
}
checkOutBillService.createMove(item);
}
}
} else {
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code,storagevehicle_code
/**
* 1.判断当前仓位:是否有锁定,是否是分配的货位
* 锁定:
@@ -3307,8 +3346,10 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
checkOutBillService.createMove(item);
}
}
};
}
}
}
private void 锁单判断(List<StructAllsetDto> structs, StructAllsetDto left, StructAllsetDto right, String invId) {
HashMap param = MapOf.of("invId", invId, "flag", "51", "sect_id", left.getSect_id(), "block_num", left.getBlock_num(), "row_num", left.getRow_num());
JSONArray allLock = WQL.getWO("ST_OUTIVT04").addParamMap(param).process().getResultJSONArray(0);
@@ -3319,9 +3360,78 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
.collect(Collectors.joining(","));
throw new BadRequestException(error + "被锁定且未下发任务,无法生成任务!");
}
};
}
private List<JSONObject> 左右出库确认(List<StructAllsetDto> structs, StructAllsetDto left, StructAllsetDto right,String invId) {
public static List<String> moveBoxes(List<String> toRemove, List<String> allBoxes) {
// 边界检查:所有箱子列表不能为空
if (allBoxes == null || allBoxes.isEmpty()) {
throw new BadRequestException("所有箱子列表不能为空");
}
// 处理需要搬出的箱子列表为null的情况视为无需要搬出的箱子
List<String> safeToRemove = (toRemove == null) ? new ArrayList<>() : toRemove;
// 用HashSet存储需要搬出的箱子提高查询效率O(1)复杂度)
Set<String> toRemoveSet = new HashSet<>(safeToRemove.size());
toRemoveSet.addAll(safeToRemove);
int totalBoxes = allBoxes.size();
int maxKeepLength = 0; // 最长连续保留序列的长度
int bestKeepStart = 0; // 最长连续保留序列的起始索引
int bestKeepEnd = -1; // 最长连续保留序列的结束索引
int currentKeepStart = 0; // 当前连续保留序列的起始索引
int currentKeepLength = 0; // 当前连续保留序列的长度
// 遍历所有箱子,寻找最长的连续保留序列
for (int i = 0; i < totalBoxes; i++) {
String currentBox = allBoxes.get(i);
// 判断当前箱子是否需要保留(不在需要搬出的集合中)
boolean needKeep = !toRemoveSet.contains(currentBox);
if (needKeep) {
// 若当前是新的连续保留序列起点,记录起始索引
if (currentKeepLength == 0) {
currentKeepStart = i;
}
currentKeepLength++;
} else {
// 遇到需要搬出的箱子,检查当前连续保留序列是否为最长
if (currentKeepLength > maxKeepLength) {
maxKeepLength = currentKeepLength;
bestKeepStart = currentKeepStart;
bestKeepEnd = i - 1;
}
// 重置当前连续保留序列
currentKeepLength = 0;
}
}
// 检查循环结束后是否有未处理的最长连续保留序列(可能在列表末尾)
if (currentKeepLength > maxKeepLength) {
maxKeepLength = currentKeepLength;
bestKeepStart = currentKeepStart;
bestKeepEnd = totalBoxes - 1;
}
// 计算需要搬运的箱子数量并预分配集合容量
int leftMoveCount = bestKeepStart; // 最长保留序列左侧需要搬运的数量
int rightMoveCount = (totalBoxes - 1) - bestKeepEnd; // 右侧需要搬运的数量
List<String> moveOrder = new ArrayList<>(leftMoveCount + rightMoveCount);
// 添加左侧需要搬运的箱子(按原有顺序)
for (int i = 0; i < bestKeepStart; i++) {
moveOrder.add(allBoxes.get(i));
}
// 添加右侧需要搬运的箱子(从右向左,减少移动距离)
for (int i = totalBoxes - 1; i > bestKeepEnd; i--) {
moveOrder.add(allBoxes.get(i));
}
System.out.println("搬运顺序: " + moveOrder);
return moveOrder;
}
private JSONObject 左右出库确认(List<StructAllsetDto> structs, StructAllsetDto left, StructAllsetDto right, String invId) {
/**
* 1.查询当前排被锁住的货位集合
* 2.过滤仓位没有没有被其他单据锁定的货位
@@ -3334,6 +3444,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
* 5.根据哪边出库查询当前排货位出库顺序
*/
String placementType = left.getPlacement_type();
boolean is_all = false;
//查询当前排
//lock_type('2','3','6','7')
// 查询仓位被锁住的货位
@@ -3382,13 +3493,13 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
// throw new BadRequestException(error + "被锁定且未下发任务,无法生成任务!");
// }
}
}
else {
} else {
//如果没有锁定这确认从左边出还是右边出库
if (StringUtils.equals(placementType, "01")) {
//确认那边少出哪边-
//查询当前排最大order
//口回口口回口*口口
is_all = true;
HashMap maxParam = MapOf.of("flag", "52", "sect_id", left.getSect_id(), "block_num", left.getBlock_num(), "row_num", left.getRow_num());
JSONObject result = WQL.getWO("ST_OUTIVT04").addParamMap(maxParam).process().uniqueResult(0);
Integer maxSeq = result.getInteger("maxseq");
@@ -3403,8 +3514,12 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
//option确认了左边出库还是右边出库03右边02左边
String orderBy = "order by out_order_seq " + (option.equals("03") ? "asc" : "desc");
HashMap structParam = MapOf.of("flag", "53", "order_by", orderBy, "sect_id", left.getSect_id(), "block_num", left.getBlock_num(), "row_num", left.getRow_num());
return WQL.getWO("ST_OUTIVT04").addParamMap(structParam).process().getResultJSONArray(0).toJavaList(JSONObject.class);
JSONObject json = new JSONObject();
json.put("is_all", is_all);
json.put("struct_list", WQL.getWO("ST_OUTIVT04").addParamMap(structParam).process().getResultJSONArray(0).toJavaList(JSONObject.class));
return json;
}
@Transactional
public void createMove(JSONObject struct) {
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code
@@ -3487,6 +3602,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
handMoveStorService.insertDtl2(mapParam);
moveStorAcsTask.immediateNotifyAcs(json.getString("task_id"));
}
@Transactional
public void createOut(JSONObject struct) {
List<StIvtIostorinvdis> list = iStIvtIostorinvdisService
@@ -3517,6 +3633,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
.in("iostorinvdis_id", disIds));
outTask.immediateNotifyAcs(create_task_id);
}
public void formeth(Consumer<String> allTransactionConsumer, JSONArray allRowArr, String iostorinv_id, String point_code, boolean checked, String iostorinvdtl_id, JSONObject jsonPoint2) {
for (int i = 0; i < allRowArr.size(); i++) {
// 调用当前排处理方法
@@ -4560,6 +4677,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
}
return result;
}
public List<JSONObject> isNumList(JSONArray arr) {
StringJoiner joiner = new StringJoiner(",", "(", ")");
List<JSONObject> result = new ArrayList<>();