refactor(wms): 优化库位拆分与合并逻辑
- 移除子库位启用状态的重复设置 - 改进子库位排序算法,提升性能和准确性 - 优化编码生成逻辑,支持更灵活的层级分配 - 批量处理父库位状态更新,提高执行效率 - 增强合并前的占用检查机制 - 实现子库位隐藏和父库位重置的批量操作 - 添加空值检查和异常处理,提升代码健壮性
This commit is contained in:
@@ -479,7 +479,6 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
// 复用原有子库位:恢复启用状态,更新拆分类型
|
// 复用原有子库位:恢复启用状态,更新拆分类型
|
||||||
for (WmsActualWarehouse child : existingChildren) {
|
for (WmsActualWarehouse child : existingChildren) {
|
||||||
child.setDelFlag(0); // 恢复未删除
|
child.setDelFlag(0); // 恢复未删除
|
||||||
child.setIsEnabled(1);
|
|
||||||
child.setSplitStatus(1);
|
child.setSplitStatus(1);
|
||||||
child.setSplitType(splitType);
|
child.setSplitType(splitType);
|
||||||
toUpdate.add(child);
|
toUpdate.add(child);
|
||||||
@@ -549,40 +548,88 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
allSubLocations.addAll(toInsert);
|
allSubLocations.addAll(toInsert);
|
||||||
allSubLocations.addAll(toUpdate);
|
allSubLocations.addAll(toUpdate);
|
||||||
|
|
||||||
// 按父库位排序(保持物理顺序)
|
if (!allSubLocations.isEmpty()) {
|
||||||
allSubLocations.sort((a, b) -> {
|
// 按父库位在columnLocations中的顺序排序
|
||||||
Long parentA = a.getParentId();
|
Map<Long, Integer> parentOrderMap = new HashMap<>();
|
||||||
Long parentB = b.getParentId();
|
for (int i = 0; i < columnLocations.size(); i++) {
|
||||||
int idxA = columnLocations.stream().map(WmsActualWarehouse::getActualWarehouseId).collect(Collectors.toList()).indexOf(parentA);
|
parentOrderMap.put(columnLocations.get(i).getActualWarehouseId(), i);
|
||||||
int idxB = columnLocations.stream().map(WmsActualWarehouse::getActualWarehouseId).collect(Collectors.toList()).indexOf(parentB);
|
}
|
||||||
return Integer.compare(idxA, idxB);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 生成规范编码
|
allSubLocations.sort((a, b) -> {
|
||||||
String prefix = columnFlag;
|
int orderA = parentOrderMap.getOrDefault(a.getParentId(), Integer.MAX_VALUE);
|
||||||
List<WmsActualWarehouse> codeToUpdate = new ArrayList<>();
|
int orderB = parentOrderMap.getOrDefault(b.getParentId(), Integer.MAX_VALUE);
|
||||||
for (int i = 0; i < allSubLocations.size(); i++) {
|
if (orderA != orderB) {
|
||||||
WmsActualWarehouse sub = allSubLocations.get(i);
|
return Integer.compare(orderA, orderB);
|
||||||
int sequenceNum = (i / 2) + 1;
|
}
|
||||||
int layer = (i % 2) + 1;
|
// 同一父库位下,按层级排序(假设层级1在前,层级2在后)
|
||||||
String newCode = String.format("%s-X%02d-%d", prefix, sequenceNum, layer);
|
return Long.compare(a.getActualWarehouseId(), b.getActualWarehouseId());
|
||||||
|
});
|
||||||
|
|
||||||
sub.setActualWarehouseCode(newCode);
|
// 生成规范编码
|
||||||
sub.setActualWarehouseName(newCode);
|
String prefix = columnFlag;
|
||||||
codeToUpdate.add(sub);
|
List<WmsActualWarehouse> codeToUpdate = new ArrayList<>();
|
||||||
|
|
||||||
|
int sequenceNum = 1;
|
||||||
|
for (int i = 0; i < allSubLocations.size(); i++) {
|
||||||
|
WmsActualWarehouse sub = allSubLocations.get(i);
|
||||||
|
|
||||||
|
// 判断是第一层还是第二层
|
||||||
|
// 如果是拆分库位的子库位,按顺序分配层级
|
||||||
|
// 如果是剩余库位的子库位,保持原层级
|
||||||
|
Long parentId = sub.getParentId();
|
||||||
|
boolean isFromSplitLocation = splitLocations.stream()
|
||||||
|
.anyMatch(loc -> loc.getActualWarehouseId().equals(parentId));
|
||||||
|
|
||||||
|
int layer;
|
||||||
|
if (isFromSplitLocation) {
|
||||||
|
// 拆分库位:第一个子库位是层级1,第二个是层级2
|
||||||
|
final int currentIndex = i; // 创建一个有效的final变量
|
||||||
|
long sameParentCount = allSubLocations.stream()
|
||||||
|
.filter(s -> s.getParentId().equals(parentId))
|
||||||
|
.filter(s -> allSubLocations.indexOf(s) <= currentIndex)
|
||||||
|
.count();
|
||||||
|
layer = (int) ((sameParentCount - 1) % 2) + 1;
|
||||||
|
} else {
|
||||||
|
// 剩余库位:保持原层级
|
||||||
|
WmsActualWarehouse parent = columnLocations.stream()
|
||||||
|
.filter(loc -> loc.getActualWarehouseId().equals(parentId))
|
||||||
|
.findFirst().orElse(null);
|
||||||
|
if (parent != null) {
|
||||||
|
String[] parts = parent.getActualWarehouseCode().split("-");
|
||||||
|
layer = parts.length >= 3 ? Integer.parseInt(parts[2]) : 1;
|
||||||
|
} else {
|
||||||
|
layer = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String newCode = String.format("%s-X%02d-%d", prefix, sequenceNum, layer);
|
||||||
|
sub.setActualWarehouseCode(newCode);
|
||||||
|
sub.setActualWarehouseName(newCode);
|
||||||
|
codeToUpdate.add(sub);
|
||||||
|
|
||||||
|
// 如果是拆分库位的第二个子库位,或者是剩余库位的子库位,序号递增
|
||||||
|
if (!isFromSplitLocation || layer == 2) {
|
||||||
|
sequenceNum++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量更新编码
|
||||||
|
for (WmsActualWarehouse sub : codeToUpdate) {
|
||||||
|
baseMapper.updateById(sub);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量更新编码
|
// 7. 批量更新父库位拆分状态
|
||||||
for (WmsActualWarehouse sub : codeToUpdate) {
|
List<WmsActualWarehouse> parentUpdates = new ArrayList<>();
|
||||||
baseMapper.updateById(sub);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. 更新父库位拆分状态
|
|
||||||
for (WmsActualWarehouse location : columnLocations) {
|
for (WmsActualWarehouse location : columnLocations) {
|
||||||
WmsActualWarehouse upd = new WmsActualWarehouse();
|
WmsActualWarehouse upd = new WmsActualWarehouse();
|
||||||
upd.setActualWarehouseId(location.getActualWarehouseId());
|
upd.setActualWarehouseId(location.getActualWarehouseId());
|
||||||
upd.setSplitStatus(1);
|
upd.setSplitStatus(1);
|
||||||
upd.setSplitType(splitType);
|
upd.setSplitType(splitType);
|
||||||
|
parentUpdates.add(upd);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (WmsActualWarehouse upd : parentUpdates) {
|
||||||
baseMapper.updateById(upd);
|
baseMapper.updateById(upd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -609,49 +656,101 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
|||||||
throw new ServiceException("参数不能为空");
|
throw new ServiceException("参数不能为空");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 批量查询父库位
|
||||||
List<WmsActualWarehouse> parents = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
List<WmsActualWarehouse> parents = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||||
.in(WmsActualWarehouse::getActualWarehouseId, bo.getLocationIds())
|
.in(WmsActualWarehouse::getActualWarehouseId, bo.getLocationIds())
|
||||||
.eq(WmsActualWarehouse::getDelFlag, 0));
|
.eq(WmsActualWarehouse::getDelFlag, 0));
|
||||||
|
|
||||||
for (WmsActualWarehouse parent : parents) {
|
if (CollUtil.isEmpty(parents)) {
|
||||||
Integer splitStatus = Optional.ofNullable(parent.getSplitStatus()).orElse(0);
|
return;
|
||||||
if (splitStatus != 1) {
|
}
|
||||||
// 未拆分状态,无需处理
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询父库位下的所有四级子库位(包含已逻辑删除的)
|
// 过滤出已拆分的父库位
|
||||||
List<WmsActualWarehouse> children = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
List<WmsActualWarehouse> splitParents = parents.stream()
|
||||||
.eq(WmsActualWarehouse::getParentId, parent.getActualWarehouseId())
|
.filter(p -> Optional.ofNullable(p.getSplitStatus()).orElse(0) == 1)
|
||||||
.eq(WmsActualWarehouse::getActualWarehouseType, 4)
|
.collect(Collectors.toList());
|
||||||
.eq(WmsActualWarehouse::getDelFlag, 0));
|
|
||||||
|
if (CollUtil.isEmpty(splitParents)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量查询所有子库位
|
||||||
|
List<Long> splitParentIds = splitParents.stream()
|
||||||
|
.map(WmsActualWarehouse::getActualWarehouseId)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<WmsActualWarehouse> allChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||||
|
.in(WmsActualWarehouse::getParentId, splitParentIds)
|
||||||
|
.eq(WmsActualWarehouse::getActualWarehouseType, 4)
|
||||||
|
.eq(WmsActualWarehouse::getDelFlag, 0));
|
||||||
|
|
||||||
|
// 按父ID分组子库位
|
||||||
|
Map<Long, List<WmsActualWarehouse>> childrenByParent = allChildren.stream()
|
||||||
|
.collect(Collectors.groupingBy(WmsActualWarehouse::getParentId));
|
||||||
|
|
||||||
|
// 检查是否有被占用的子库位
|
||||||
|
List<WmsActualWarehouse> occupiedChildren = allChildren.stream()
|
||||||
|
.filter(c -> !Objects.equals(c.getIsEnabled(), 1))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (!occupiedChildren.isEmpty()) {
|
||||||
|
// 找到被占用子库位的父库位名称
|
||||||
|
Set<Long> occupiedParentIds = occupiedChildren.stream()
|
||||||
|
.map(WmsActualWarehouse::getParentId)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
List<String> occupiedParentCodes = splitParents.stream()
|
||||||
|
.filter(p -> occupiedParentIds.contains(p.getActualWarehouseId()))
|
||||||
|
.map(WmsActualWarehouse::getActualWarehouseCode)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
throw new ServiceException("以下库位的小库位被占用,不能合并:" + String.join(", ", occupiedParentCodes));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备批量更新操作
|
||||||
|
List<WmsActualWarehouse> childrenToHide = new ArrayList<>();
|
||||||
|
List<WmsActualWarehouse> parentsToReset = new ArrayList<>();
|
||||||
|
|
||||||
|
for (WmsActualWarehouse parent : splitParents) {
|
||||||
|
List<WmsActualWarehouse> children = childrenByParent.get(parent.getActualWarehouseId());
|
||||||
|
|
||||||
if (CollUtil.isEmpty(children)) {
|
if (CollUtil.isEmpty(children)) {
|
||||||
// 无子库位,直接还原父库位状态
|
// 无子库位,直接重置父库位状态
|
||||||
resetParentLocationStatus(parent);
|
WmsActualWarehouse parentUpdate = new WmsActualWarehouse();
|
||||||
|
parentUpdate.setActualWarehouseId(parent.getActualWarehouseId());
|
||||||
|
parentUpdate.setSplitStatus(0);
|
||||||
|
parentUpdate.setSplitType(0);
|
||||||
|
parentsToReset.add(parentUpdate);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查子库位是否被占用(仅检查未删除的子库位)
|
// 准备隐藏子库位
|
||||||
boolean anyOccupied = children.stream()
|
|
||||||
.filter(c -> c.getDelFlag() == 0) // 只检查启用中的子库位
|
|
||||||
.anyMatch(c -> !Objects.equals(c.getIsEnabled(), 1));
|
|
||||||
|
|
||||||
if (anyOccupied) {
|
|
||||||
throw new ServiceException("小库位被占用,不能合并:" + parent.getActualWarehouseCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 逻辑删除子库位(保留数据,用于后续拆分复用)
|
|
||||||
for (WmsActualWarehouse child : children) {
|
for (WmsActualWarehouse child : children) {
|
||||||
WmsActualWarehouse updChild = new WmsActualWarehouse();
|
WmsActualWarehouse childUpdate = new WmsActualWarehouse();
|
||||||
updChild.setActualWarehouseId(child.getActualWarehouseId());
|
childUpdate.setActualWarehouseId(child.getActualWarehouseId());
|
||||||
updChild.setDelFlag(1); // 逻辑删除
|
childUpdate.setDelFlag(1); // 逻辑删除(隐藏)
|
||||||
updChild.setIsEnabled(0); // 禁用
|
childrenToHide.add(childUpdate);
|
||||||
baseMapper.updateById(updChild);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 还原父库位状态
|
// 准备重置父库位状态
|
||||||
resetParentLocationStatus(parent);
|
WmsActualWarehouse parentUpdate = new WmsActualWarehouse();
|
||||||
|
parentUpdate.setActualWarehouseId(parent.getActualWarehouseId());
|
||||||
|
parentUpdate.setSplitStatus(0);
|
||||||
|
parentUpdate.setSplitType(0);
|
||||||
|
parentsToReset.add(parentUpdate);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量执行更新操作
|
||||||
|
if (!childrenToHide.isEmpty()) {
|
||||||
|
for (WmsActualWarehouse child : childrenToHide) {
|
||||||
|
baseMapper.updateById(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!parentsToReset.isEmpty()) {
|
||||||
|
for (WmsActualWarehouse parent : parentsToReset) {
|
||||||
|
baseMapper.updateById(parent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user