feat(wms): 实现库位拆分与合并功能
- 新增库位拆分状态和类型字段,支持大库位拆分为两个小库位 - 新增拆分与合并接口,支持将三级库位进行拆分或合并操作 - 在查询时自动展开已拆分库位的子节点,显示其两个小库位 - 实现拆分时复用历史子库位逻辑,避免重复创建相同编码库位 - 添加拆分与合并时的业务校验,确保库位状态合法才可操作 - 提供 WmsActualWarehouseSplitBo 用于接收拆分/合并请求参数 - 完善实体类和 VO 类对拆分状态及类型的映射支持 - 更新 Mapper XML 配置以支持新增的拆分相关数据库字段
This commit is contained in:
@@ -12,6 +12,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import com.klp.domain.bo.WmsActualWarehouseBo;
|
||||
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
|
||||
import com.klp.domain.bo.WmsActualWarehouseBatchGenerateBo;
|
||||
import com.klp.domain.bo.WmsActualWarehouseSplitBo;
|
||||
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
|
||||
import com.klp.domain.vo.WmsActualWarehouseImportVo;
|
||||
import com.klp.domain.vo.WmsActualWarehouseVo;
|
||||
@@ -124,6 +125,36 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
||||
return list;
|
||||
}
|
||||
|
||||
// 如果当前查询的是某二级父节点下的三级库位,需要将被拆分的大库位替换为其两个子库位
|
||||
if (bo.getParentId() != null) {
|
||||
List<Long> splitParentIds = list.stream()
|
||||
.filter(v -> Optional.ofNullable(v.getSplitStatus()).orElse(0) == 1)
|
||||
.map(WmsActualWarehouseVo::getActualWarehouseId)
|
||||
.collect(Collectors.toList());
|
||||
if (CollUtil.isNotEmpty(splitParentIds)) {
|
||||
List<WmsActualWarehouseVo> children = baseMapper.selectVoList(
|
||||
Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||
.in(WmsActualWarehouse::getParentId, splitParentIds)
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0)
|
||||
.orderByAsc(WmsActualWarehouse::getSortNo, WmsActualWarehouse::getActualWarehouseId)
|
||||
);
|
||||
Map<Long, List<WmsActualWarehouseVo>> childrenMap = children.stream()
|
||||
.collect(Collectors.groupingBy(WmsActualWarehouseVo::getParentId, LinkedHashMap::new, Collectors.toList()));
|
||||
List<WmsActualWarehouseVo> expanded = new ArrayList<>(list.size() + children.size());
|
||||
for (WmsActualWarehouseVo v : list) {
|
||||
if (Optional.ofNullable(v.getSplitStatus()).orElse(0) == 1) {
|
||||
List<WmsActualWarehouseVo> ch = childrenMap.get(v.getActualWarehouseId());
|
||||
if (CollUtil.isNotEmpty(ch)) {
|
||||
expanded.addAll(ch);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
expanded.add(v);
|
||||
}
|
||||
list = expanded;
|
||||
}
|
||||
}
|
||||
|
||||
// 仅对被占用的位置(isEnabled=0)补充钢卷信息
|
||||
List<Long> occupiedAwIds = list.stream()
|
||||
.filter(it -> it.getIsEnabled() != null && it.getIsEnabled() == 0)
|
||||
@@ -386,5 +417,162 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
|
||||
return baseMapper.deleteBatchIds(ids) > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void splitLocations(WmsActualWarehouseSplitBo bo) {
|
||||
if (bo == null || CollUtil.isEmpty(bo.getLocationIds())) {
|
||||
throw new ServiceException("参数不能为空");
|
||||
}
|
||||
int splitType = Optional.ofNullable(bo.getSplitType()).orElse(0);
|
||||
// 仅允许列拆分(1拆2)的类型,防止非法拆分类型
|
||||
if (splitType != 0) {
|
||||
throw new ServiceException("暂仅支持列拆分(1拆2)");
|
||||
}
|
||||
// 查询父库位并校验有效性
|
||||
List<Long> locationIds = bo.getLocationIds();
|
||||
List<WmsActualWarehouse> parents = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||
.in(WmsActualWarehouse::getActualWarehouseId, locationIds)
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0));
|
||||
// 校验无效ID并明确提示
|
||||
Set<Long> existIds = parents.stream().map(WmsActualWarehouse::getActualWarehouseId).collect(Collectors.toSet());
|
||||
List<Long> invalidIds = locationIds.stream().filter(id -> !existIds.contains(id)).collect(Collectors.toList());
|
||||
if (!invalidIds.isEmpty()) {
|
||||
throw new ServiceException("存在无效库位ID:" + invalidIds);
|
||||
}
|
||||
// 检查占用与状态:仅依据 isEnabled=1 为未占用,可拆分
|
||||
for (WmsActualWarehouse p : parents) {
|
||||
Integer st = Optional.ofNullable(p.getSplitStatus()).orElse(0);
|
||||
if (st == 1) {
|
||||
throw new ServiceException("库位已拆分:" + p.getActualWarehouseCode());
|
||||
}
|
||||
if (!Objects.equals(p.getIsEnabled(), 1)) {
|
||||
throw new ServiceException("库位被占用或禁用,不能拆分:" + p.getActualWarehouseCode());
|
||||
}
|
||||
}
|
||||
List<WmsActualWarehouse> toInsert = new ArrayList<>();
|
||||
for (WmsActualWarehouse p : parents) {
|
||||
String base = p.getActualWarehouseCode();
|
||||
// 先查找是否存在历史子库位(逻辑删除状态)
|
||||
List<WmsActualWarehouse> historyChildren = baseMapper.selectList(
|
||||
Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||
.eq(WmsActualWarehouse::getParentId, p.getActualWarehouseId())
|
||||
.in(WmsActualWarehouse::getActualWarehouseCode, Arrays.asList(base + "-1", base + "-2"))
|
||||
.eq(WmsActualWarehouse::getDelFlag, 1)
|
||||
);
|
||||
if (CollUtil.isNotEmpty(historyChildren)) {
|
||||
// 复活历史子库位,避免新建,保持原ID和二维码
|
||||
for (WmsActualWarehouse his : historyChildren) {
|
||||
WmsActualWarehouse revive = new WmsActualWarehouse();
|
||||
revive.setActualWarehouseId(his.getActualWarehouseId());
|
||||
revive.setDelFlag(0);
|
||||
revive.setSplitStatus(1);
|
||||
revive.setSplitType(splitType);
|
||||
revive.setIsEnabled(1);
|
||||
baseMapper.updateById(revive);
|
||||
}
|
||||
// 如果只找到了一个历史子库位,另一个需要新建
|
||||
if (historyChildren.size() < 2) {
|
||||
Set<String> found = historyChildren.stream().map(WmsActualWarehouse::getActualWarehouseCode).collect(Collectors.toSet());
|
||||
String miss = !found.contains(base + "-1") ? base + "-1" : base + "-2";
|
||||
WmsActualWarehouse c = new WmsActualWarehouse();
|
||||
c.setParentId(p.getActualWarehouseId());
|
||||
c.setActualWarehouseType(p.getActualWarehouseType());
|
||||
c.setActualWarehouseCode(miss);
|
||||
c.setActualWarehouseName(miss);
|
||||
c.setSortNo(Optional.ofNullable(p.getSortNo()).orElse(0L));
|
||||
c.setIsEnabled(1);
|
||||
c.setSplitStatus(1);
|
||||
c.setSplitType(splitType);
|
||||
toInsert.add(c);
|
||||
}
|
||||
} else {
|
||||
// 无历史记录,则正常新建两个
|
||||
WmsActualWarehouse c1 = new WmsActualWarehouse();
|
||||
c1.setParentId(p.getActualWarehouseId());
|
||||
c1.setActualWarehouseType(p.getActualWarehouseType());
|
||||
c1.setActualWarehouseCode(base + "-1");
|
||||
c1.setActualWarehouseName(base + "-1");
|
||||
c1.setSortNo(Optional.ofNullable(p.getSortNo()).orElse(0L));
|
||||
c1.setIsEnabled(1);
|
||||
c1.setSplitStatus(1);
|
||||
c1.setSplitType(splitType);
|
||||
toInsert.add(c1);
|
||||
|
||||
WmsActualWarehouse c2 = new WmsActualWarehouse();
|
||||
c2.setParentId(p.getActualWarehouseId());
|
||||
c2.setActualWarehouseType(p.getActualWarehouseType());
|
||||
c2.setActualWarehouseCode(base + "-2");
|
||||
c2.setActualWarehouseName(base + "-2");
|
||||
c2.setSortNo(Optional.ofNullable(p.getSortNo()).orElse(0L));
|
||||
c2.setIsEnabled(1);
|
||||
c2.setSplitStatus(1);
|
||||
c2.setSplitType(splitType);
|
||||
toInsert.add(c2);
|
||||
}
|
||||
}
|
||||
if (!toInsert.isEmpty()) {
|
||||
boolean ok = baseMapper.insertBatch(toInsert);
|
||||
if (!ok) {
|
||||
throw new ServiceException("新增小库位失败");
|
||||
}
|
||||
}
|
||||
// 更新父节点拆分状态
|
||||
for (WmsActualWarehouse p : parents) {
|
||||
WmsActualWarehouse upd = new WmsActualWarehouse();
|
||||
upd.setActualWarehouseId(p.getActualWarehouseId());
|
||||
upd.setSplitStatus(1);
|
||||
upd.setSplitType(splitType);
|
||||
baseMapper.updateById(upd);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void mergeLocations(WmsActualWarehouseSplitBo bo) {
|
||||
if (bo == null || CollUtil.isEmpty(bo.getLocationIds())) {
|
||||
throw new ServiceException("参数不能为空");
|
||||
}
|
||||
List<WmsActualWarehouse> parents = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||
.in(WmsActualWarehouse::getActualWarehouseId, bo.getLocationIds())
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0));
|
||||
for (WmsActualWarehouse p : parents) {
|
||||
Integer st = Optional.ofNullable(p.getSplitStatus()).orElse(0);
|
||||
if (st != 1) {
|
||||
// 未拆分无需合并
|
||||
continue;
|
||||
}
|
||||
List<WmsActualWarehouse> children = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||||
.eq(WmsActualWarehouse::getParentId, p.getActualWarehouseId())
|
||||
.eq(WmsActualWarehouse::getDelFlag, 0));
|
||||
if (CollUtil.isEmpty(children)) {
|
||||
// 无子节点,直接还原状态
|
||||
WmsActualWarehouse upd = new WmsActualWarehouse();
|
||||
upd.setActualWarehouseId(p.getActualWarehouseId());
|
||||
upd.setSplitStatus(0);
|
||||
upd.setSplitType(0);
|
||||
baseMapper.updateById(upd);
|
||||
continue;
|
||||
}
|
||||
// 检查子库位 isEnabled 必须为1(未占用)
|
||||
boolean anyOccupied = children.stream().anyMatch(c -> !Objects.equals(c.getIsEnabled(), 1));
|
||||
if (anyOccupied) {
|
||||
throw new ServiceException("小库位被占用,不能合并:" + p.getActualWarehouseCode());
|
||||
}
|
||||
// 逻辑删除小库位
|
||||
for (WmsActualWarehouse c : children) {
|
||||
WmsActualWarehouse updC = new WmsActualWarehouse();
|
||||
updC.setActualWarehouseId(c.getActualWarehouseId());
|
||||
updC.setDelFlag(1);
|
||||
baseMapper.updateById(updC);
|
||||
}
|
||||
// 更新父状态
|
||||
WmsActualWarehouse upd = new WmsActualWarehouse();
|
||||
upd.setActualWarehouseId(p.getActualWarehouseId());
|
||||
upd.setSplitStatus(0);
|
||||
upd.setSplitType(0);
|
||||
baseMapper.updateById(upd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user