fix:出库顺序逻辑优化
This commit is contained in:
@@ -591,6 +591,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 拣选出库新增
|
* 拣选出库新增
|
||||||
|
*
|
||||||
* @param map 、
|
* @param map 、
|
||||||
* @return 单据标识
|
* @return 单据标识
|
||||||
*/
|
*/
|
||||||
@@ -1497,6 +1498,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 分拣出库修改
|
* 分拣出库修改
|
||||||
|
*
|
||||||
* @param whereJson、
|
* @param whereJson、
|
||||||
*/
|
*/
|
||||||
private void updatePic(JSONObject whereJson) {
|
private void updatePic(JSONObject whereJson) {
|
||||||
@@ -3220,7 +3222,8 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
public void allSetPointByNoTran(JSONObject whereJson) {
|
public void allSetPointByNoTran(JSONObject whereJson) {
|
||||||
String point_code = whereJson.getString("point_code"); // 终点
|
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 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);
|
JSONObject jo_mst = WQLObject.getWQLObject("ST_IVT_IOStorInv").query("iostorinv_id = '" + whereJson.getString("iostorinv_id") + "'").uniqueResult(0);
|
||||||
if (ObjectUtil.isEmpty(jo_mst)) {
|
if (ObjectUtil.isEmpty(jo_mst)) {
|
||||||
throw new BadRequestException("未查到相关出库单");
|
throw new BadRequestException("未查到相关出库单");
|
||||||
@@ -3272,9 +3275,45 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
StructAllsetDto left = needStructs.get(0);
|
StructAllsetDto left = needStructs.get(0);
|
||||||
StructAllsetDto right = needStructs.get(needStructs.size() - 1);
|
StructAllsetDto right = needStructs.get(needStructs.size() - 1);
|
||||||
//确认左/右出库并根据出库顺序获取货位集合
|
//确认左/右出库并根据出库顺序获取货位集合
|
||||||
List<JSONObject> structs = 左右出库确认(needStructs, left, right,whereJson.getString("iostorinv_id"));
|
JSONObject jsonObject = 左右出库确认(needStructs, left, right, whereJson.getString("iostorinv_id"));
|
||||||
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code,storagevehicle_code
|
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());
|
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.判断当前仓位:是否有锁定,是否是分配的货位
|
* 1.判断当前仓位:是否有锁定,是否是分配的货位
|
||||||
* 锁定:
|
* 锁定:
|
||||||
@@ -3307,8 +3346,10 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
checkOutBillService.createMove(item);
|
checkOutBillService.createMove(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void 锁单判断(List<StructAllsetDto> structs, StructAllsetDto left, StructAllsetDto right, String invId) {
|
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());
|
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);
|
JSONArray allLock = WQL.getWO("ST_OUTIVT04").addParamMap(param).process().getResultJSONArray(0);
|
||||||
@@ -3319,9 +3360,78 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
.collect(Collectors.joining(","));
|
.collect(Collectors.joining(","));
|
||||||
throw new BadRequestException(error + "被锁定且未下发任务,无法生成任务!");
|
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.查询当前排被锁住的货位集合
|
* 1.查询当前排被锁住的货位集合
|
||||||
* 2.过滤仓位没有没有被其他单据锁定的货位
|
* 2.过滤仓位没有没有被其他单据锁定的货位
|
||||||
@@ -3334,6 +3444,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
* 5.根据哪边出库查询当前排货位出库顺序
|
* 5.根据哪边出库查询当前排货位出库顺序
|
||||||
*/
|
*/
|
||||||
String placementType = left.getPlacement_type();
|
String placementType = left.getPlacement_type();
|
||||||
|
boolean is_all = false;
|
||||||
//查询当前排
|
//查询当前排
|
||||||
//lock_type('2','3','6','7')
|
//lock_type('2','3','6','7')
|
||||||
// 查询仓位被锁住的货位
|
// 查询仓位被锁住的货位
|
||||||
@@ -3382,13 +3493,13 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
// throw new BadRequestException(error + "被锁定且未下发任务,无法生成任务!");
|
// throw new BadRequestException(error + "被锁定且未下发任务,无法生成任务!");
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
//如果没有锁定这确认从左边出还是右边出库
|
//如果没有锁定这确认从左边出还是右边出库
|
||||||
if (StringUtils.equals(placementType, "01")) {
|
if (StringUtils.equals(placementType, "01")) {
|
||||||
//确认那边少出哪边-
|
//确认那边少出哪边-
|
||||||
//查询当前排最大order
|
//查询当前排最大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());
|
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);
|
JSONObject result = WQL.getWO("ST_OUTIVT04").addParamMap(maxParam).process().uniqueResult(0);
|
||||||
Integer maxSeq = result.getInteger("maxseq");
|
Integer maxSeq = result.getInteger("maxseq");
|
||||||
@@ -3403,8 +3514,12 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
//option确认了左边出库还是右边出库03右边,02左边
|
//option确认了左边出库还是右边出库03右边,02左边
|
||||||
String orderBy = "order by out_order_seq " + (option.equals("03") ? "asc" : "desc");
|
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());
|
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
|
@Transactional
|
||||||
public void createMove(JSONObject struct) {
|
public void createMove(JSONObject struct) {
|
||||||
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code
|
//attr.struct_code,attr.lock_type,attr.storagevehicle_code,attr.inv_code
|
||||||
@@ -3487,6 +3602,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
handMoveStorService.insertDtl2(mapParam);
|
handMoveStorService.insertDtl2(mapParam);
|
||||||
moveStorAcsTask.immediateNotifyAcs(json.getString("task_id"));
|
moveStorAcsTask.immediateNotifyAcs(json.getString("task_id"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
public void createOut(JSONObject struct) {
|
public void createOut(JSONObject struct) {
|
||||||
List<StIvtIostorinvdis> list = iStIvtIostorinvdisService
|
List<StIvtIostorinvdis> list = iStIvtIostorinvdisService
|
||||||
@@ -3517,6 +3633,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
.in("iostorinvdis_id", disIds));
|
.in("iostorinvdis_id", disIds));
|
||||||
outTask.immediateNotifyAcs(create_task_id);
|
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) {
|
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++) {
|
for (int i = 0; i < allRowArr.size(); i++) {
|
||||||
// 调用当前排处理方法
|
// 调用当前排处理方法
|
||||||
@@ -4560,6 +4677,7 @@ public class CheckOutBillServiceImpl implements CheckOutBillService {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<JSONObject> isNumList(JSONArray arr) {
|
public List<JSONObject> isNumList(JSONArray arr) {
|
||||||
StringJoiner joiner = new StringJoiner(",", "(", ")");
|
StringJoiner joiner = new StringJoiner(",", "(", ")");
|
||||||
List<JSONObject> result = new ArrayList<>();
|
List<JSONObject> result = new ArrayList<>();
|
||||||
|
|||||||
Reference in New Issue
Block a user