refactor(wms): 优化库位拆分与合并逻辑

- 批量查询子库位以减少数据库访问次数
- 使用批量更新替代循环单条更新提高性能
- 优化复活子库位逻辑,支持批量操作
- 合并库位时增加占用状态检查
- 提取需要合并的库位进行针对性处理
- 子库位隐藏状态从1改为2以区分删除状态
This commit is contained in:
2025-12-20 16:44:19 +08:00
parent 8f5098c98c
commit dacd1cb8fd

View File

@@ -455,80 +455,92 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
throw new ServiceException("未找到列标识为 " + columnFlag + " 的库位");
}
// 检查是否已经有子库位存在(包括被删除的
boolean hasExistingChildren = false;
for (WmsActualWarehouse location : columnLocations) {
List<WmsActualWarehouse> existingChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
.eq(WmsActualWarehouse::getParentId, location.getActualWarehouseId())
.eq(WmsActualWarehouse::getActualWarehouseType, 4)); // 四级子库位
if (CollUtil.isNotEmpty(existingChildren)) {
hasExistingChildren = true;
break;
}
}
// 批量查询所有子库位(一次性查询,避免循环查询
List<Long> parentIds = columnLocations.stream()
.map(WmsActualWarehouse::getActualWarehouseId)
.collect(Collectors.toList());
List<WmsActualWarehouse> allChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
.in(WmsActualWarehouse::getParentId, parentIds)
.eq(WmsActualWarehouse::getActualWarehouseType, 4)); // 四级子库位
boolean hasExistingChildren = CollUtil.isNotEmpty(allChildren);
if (hasExistingChildren) {
// 如果已经有子库位,执行复活逻辑
reviveExistingSubLocations(columnLocations, splitIds, splitType);
reviveExistingSubLocations(columnLocations, splitIds, splitType, allChildren);
} else {
// 如果没有子库位,执行创建逻辑
createNewSubLocationsWithOriginalLogic(columnLocations, splitIds, splitType, columnFlag);
}
// 更新该列所有被拆分库位的状态
// 批量更新该列所有被拆分库位的状态
List<WmsActualWarehouse> toUpdate = new ArrayList<>();
for (WmsActualWarehouse location : columnLocations) {
WmsActualWarehouse upd = new WmsActualWarehouse();
upd.setActualWarehouseId(location.getActualWarehouseId());
upd.setSplitStatus(1);
upd.setSplitType(splitType);
baseMapper.updateById(upd);
toUpdate.add(upd);
}
if (!toUpdate.isEmpty()) {
baseMapper.updateBatchById(toUpdate);
}
}
/**
* 复活已存在的子库位
* 复活已存在的子库位(优化版:批量操作)
*/
private void reviveExistingSubLocations(List<WmsActualWarehouse> columnLocations, Set<Long> splitIds, Integer splitType) {
private void reviveExistingSubLocations(List<WmsActualWarehouse> columnLocations, Set<Long> splitIds, Integer splitType, List<WmsActualWarehouse> allChildren) {
// 按父ID分组子库位
Map<Long, List<WmsActualWarehouse>> childrenByParent = allChildren.stream()
.sorted(Comparator.comparing(WmsActualWarehouse::getActualWarehouseId))
.collect(Collectors.groupingBy(WmsActualWarehouse::getParentId, LinkedHashMap::new, Collectors.toList()));
List<WmsActualWarehouse> toUpdate = new ArrayList<>();
for (WmsActualWarehouse location : columnLocations) {
boolean isSplitLocation = splitIds.contains(location.getActualWarehouseId());
List<WmsActualWarehouse> children = childrenByParent.get(location.getActualWarehouseId());
if (CollUtil.isEmpty(children)) {
continue;
}
// 查询该库位下所有子库位(包括已删除的)
List<WmsActualWarehouse> allChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
.eq(WmsActualWarehouse::getParentId, location.getActualWarehouseId())
.eq(WmsActualWarehouse::getActualWarehouseType, 4) // 四级子库位
.orderByAsc(WmsActualWarehouse::getActualWarehouseId));
// 根据是否为拆分库位决定需要复活的子库位数量
int requiredCount = isSplitLocation ? 2 : 1;
if (CollUtil.isNotEmpty(allChildren)) {
// 根据是否为拆分库位决定需要复活的子库位数量
int requiredCount = isSplitLocation ? 2 : 1;
// 复活前N个子库位
for (int i = 0; i < Math.min(requiredCount, children.size()); i++) {
WmsActualWarehouse child = children.get(i);
if (child.getDelFlag() == 1) { // 只处理已删除的子库位
WmsActualWarehouse childUpdate = new WmsActualWarehouse();
childUpdate.setActualWarehouseId(child.getActualWarehouseId());
childUpdate.setDelFlag(0);
childUpdate.setSplitStatus(1);
childUpdate.setSplitType(splitType);
toUpdate.add(childUpdate);
}
}
// 复活前N个子库位
for (int i = 0; i < Math.min(requiredCount, allChildren.size()); i++) {
WmsActualWarehouse child = allChildren.get(i);
if (child.getDelFlag() == 1) { // 只处理已删除的子库位
// 如果子库位数量超过需要的数量,隐藏多余的
if (children.size() > requiredCount) {
for (int i = requiredCount; i < children.size(); i++) {
WmsActualWarehouse child = children.get(i);
if (child.getDelFlag() == 0) { // 只处理未删除的子库位
WmsActualWarehouse childUpdate = new WmsActualWarehouse();
childUpdate.setActualWarehouseId(child.getActualWarehouseId());
childUpdate.setDelFlag(0);
childUpdate.setSplitStatus(1);
childUpdate.setSplitType(splitType);
baseMapper.updateById(childUpdate);
}
}
// 如果子库位数量超过需要的数量,隐藏多余的
if (allChildren.size() > requiredCount) {
for (int i = requiredCount; i < allChildren.size(); i++) {
WmsActualWarehouse child = allChildren.get(i);
if (child.getDelFlag() == 0) { // 只处理未删除的子库位
WmsActualWarehouse childUpdate = new WmsActualWarehouse();
childUpdate.setActualWarehouseId(child.getActualWarehouseId());
childUpdate.setDelFlag(1);
baseMapper.updateById(childUpdate);
}
childUpdate.setDelFlag(1);
toUpdate.add(childUpdate);
}
}
}
}
// 批量更新
if (!toUpdate.isEmpty()) {
baseMapper.updateBatchById(toUpdate);
}
}
/**
@@ -640,9 +652,7 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
// 3. 批量更新编码
if (!toUpdate.isEmpty()) {
for (WmsActualWarehouse item : toUpdate) {
baseMapper.updateById(item);
}
baseMapper.updateBatchById(toUpdate);
}
}
@@ -670,38 +680,56 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
throw new ServiceException("未找到列标识为 " + columnFlag + " 的库位");
}
// 合并操作:隐藏子库位
for (WmsActualWarehouse location : columnLocations) {
Integer currentSplitStatus = Optional.ofNullable(location.getSplitStatus()).orElse(0);
if (currentSplitStatus != 1) {
// 未拆分的库位无需合并
continue;
}
// 过滤出需要合并的库位splitStatus=1
List<WmsActualWarehouse> locationsToMerge = columnLocations.stream()
.filter(loc -> Optional.ofNullable(loc.getSplitStatus()).orElse(0) == 1)
.collect(Collectors.toList());
// 查询该库位下所有子库位(包括已删除的)
List<WmsActualWarehouse> allChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
.eq(WmsActualWarehouse::getParentId, location.getActualWarehouseId())
.eq(WmsActualWarehouse::getActualWarehouseType, 4)); // 四级子库位
if (CollUtil.isEmpty(locationsToMerge)) {
return; // 没有需要合并的库位
}
if (CollUtil.isNotEmpty(allChildren)) {
// 检查子库位是否被占用(只检查未删除的子库位)
List<WmsActualWarehouse> activeChildren = allChildren.stream()
// 批量查询所有子库位
List<Long> parentIds = locationsToMerge.stream()
.map(WmsActualWarehouse::getActualWarehouseId)
.collect(Collectors.toList());
List<WmsActualWarehouse> allChildren = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
.in(WmsActualWarehouse::getParentId, parentIds)
.eq(WmsActualWarehouse::getActualWarehouseType, 4)); // 四级子库位
// 按父ID分组子库位
Map<Long, List<WmsActualWarehouse>> childrenByParent = allChildren.stream()
.collect(Collectors.groupingBy(WmsActualWarehouse::getParentId));
// 检查是否有子库位被占用
for (WmsActualWarehouse location : locationsToMerge) {
List<WmsActualWarehouse> children = childrenByParent.get(location.getActualWarehouseId());
if (CollUtil.isNotEmpty(children)) {
boolean anyOccupied = children.stream()
.filter(c -> c.getDelFlag() == 0)
.collect(Collectors.toList());
boolean anyOccupied = activeChildren.stream()
.anyMatch(c -> !Objects.equals(c.getIsEnabled(), 1));
if (anyOccupied) {
throw new ServiceException("子库位被占用,不能合并:" + location.getActualWarehouseCode());
}
}
}
// 隐藏所有子库位设置delFlag=1
for (WmsActualWarehouse child : allChildren) {
if (child.getDelFlag() == 0) { // 只处理未删除的子库位
// 批量更新子库位和父库位
List<WmsActualWarehouse> childrenToUpdate = new ArrayList<>();
List<WmsActualWarehouse> parentsToUpdate = new ArrayList<>();
for (WmsActualWarehouse location : locationsToMerge) {
List<WmsActualWarehouse> children = childrenByParent.get(location.getActualWarehouseId());
// 隐藏所有子库位
if (CollUtil.isNotEmpty(children)) {
for (WmsActualWarehouse child : children) {
if (child.getDelFlag() == 0) {
WmsActualWarehouse childUpdate = new WmsActualWarehouse();
childUpdate.setActualWarehouseId(child.getActualWarehouseId());
childUpdate.setDelFlag(2);
baseMapper.updateById(childUpdate);
childrenToUpdate.add(childUpdate);
}
}
}
@@ -711,7 +739,15 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
parentUpdate.setActualWarehouseId(location.getActualWarehouseId());
parentUpdate.setSplitStatus(0);
parentUpdate.setSplitType(0);
baseMapper.updateById(parentUpdate);
parentsToUpdate.add(parentUpdate);
}
// 批量更新
if (!childrenToUpdate.isEmpty()) {
baseMapper.updateBatchById(childrenToUpdate);
}
if (!parentsToUpdate.isEmpty()) {
baseMapper.updateBatchById(parentsToUpdate);
}
}