- 新增库位拆分状态和类型字段,支持大库位拆分为两个小库位 - 新增拆分与合并接口,支持将三级库位进行拆分或合并操作 - 在查询时自动展开已拆分库位的子节点,显示其两个小库位 - 实现拆分时复用历史子库位逻辑,避免重复创建相同编码库位 - 添加拆分与合并时的业务校验,确保库位状态合法才可操作 - 提供 WmsActualWarehouseSplitBo 用于接收拆分/合并请求参数 - 完善实体类和 VO 类对拆分状态及类型的映射支持 - 更新 Mapper XML 配置以支持新增的拆分相关数据库字段
579 lines
26 KiB
Java
579 lines
26 KiB
Java
package com.klp.service.impl;
|
||
|
||
import cn.hutool.core.bean.BeanUtil;
|
||
import cn.hutool.core.collection.CollUtil;
|
||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||
import com.klp.common.exception.ServiceException;
|
||
import com.klp.common.utils.StringUtils;
|
||
import lombok.RequiredArgsConstructor;
|
||
import org.springframework.stereotype.Service;
|
||
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;
|
||
import com.klp.domain.WmsActualWarehouse;
|
||
import com.klp.mapper.WmsActualWarehouseMapper;
|
||
import com.klp.service.IWmsActualWarehouseService;
|
||
import com.klp.domain.WmsMaterialCoil;
|
||
import com.klp.mapper.WmsMaterialCoilMapper;
|
||
|
||
import java.util.*;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* 实际库区/库位自关联Service业务层处理
|
||
*
|
||
* @author klp
|
||
* @date 2025-11-24
|
||
*/
|
||
@RequiredArgsConstructor
|
||
@Service
|
||
public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService {
|
||
|
||
private final WmsActualWarehouseMapper baseMapper;
|
||
private final WmsMaterialCoilMapper wmsMaterialCoilMapper;
|
||
|
||
/**
|
||
* 查询实际库区/库位自关联
|
||
*/
|
||
@Override
|
||
public WmsActualWarehouseVo queryById(Long actualWarehouseId){
|
||
return baseMapper.selectVoById(actualWarehouseId);
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public int batchGenerateLocations(WmsActualWarehouseBatchGenerateBo bo) {
|
||
if (bo == null) {
|
||
throw new ServiceException("参数不能为空");
|
||
}
|
||
Integer rows = bo.getRowCount();
|
||
Integer cols = bo.getColumnCount();
|
||
Integer layers = bo.getLayerCount();
|
||
String prefix = bo.getPrefix();
|
||
Long parentId = bo.getParentId();
|
||
if (layers == null) {
|
||
layers = 2;
|
||
}
|
||
if (rows == null || cols == null || rows < 1 || cols < 1) {
|
||
throw new ServiceException("行/列必须为正整数");
|
||
}
|
||
if (layers < 1) {
|
||
throw new ServiceException("层必须为正整数");
|
||
}
|
||
if (StringUtils.isBlank(prefix)) {
|
||
throw new ServiceException("前缀不能为空");
|
||
}
|
||
|
||
List<String> codes = new ArrayList<>(rows * cols * layers);
|
||
for (int l = 1; l <= layers; l++) {
|
||
int rowsForLayer = (l == 2) ? Math.max(rows - 1, 1) : rows;
|
||
for (int c = 1; c <= cols; c++) {
|
||
for (int r = 1; r <= rowsForLayer; r++) {
|
||
String rStr = r < 10 ? ("0" + r) : String.valueOf(r);
|
||
String code = prefix + c + '-' + rStr + '-' + l;
|
||
codes.add(code);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 去重:过滤同父级下已存在的编码
|
||
List<WmsActualWarehouse> exists = baseMapper.selectList(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||
.eq(WmsActualWarehouse::getParentId, parentId)
|
||
.in(!codes.isEmpty(), WmsActualWarehouse::getActualWarehouseCode, codes));
|
||
Set<String> existCodes = exists.stream().map(WmsActualWarehouse::getActualWarehouseCode).collect(Collectors.toSet());
|
||
|
||
List<WmsActualWarehouse> toInsert = new ArrayList<>();
|
||
for (String code : codes) {
|
||
if (existCodes.contains(code)) {
|
||
continue;
|
||
}
|
||
WmsActualWarehouse e = new WmsActualWarehouse();
|
||
e.setParentId(parentId);
|
||
e.setActualWarehouseType(3L);
|
||
e.setActualWarehouseCode(code);
|
||
e.setActualWarehouseName(code);
|
||
e.setSortNo(0L);
|
||
e.setIsEnabled(1);
|
||
toInsert.add(e);
|
||
}
|
||
if (toInsert.isEmpty()) {
|
||
return 0;
|
||
}
|
||
boolean ok = baseMapper.insertBatch(toInsert);
|
||
if (!ok) {
|
||
throw new ServiceException("批量生成失败");
|
||
}
|
||
return toInsert.size();
|
||
}
|
||
|
||
|
||
/**
|
||
* 查询实际库区/库位自关联列表
|
||
*/
|
||
@Override
|
||
public List<WmsActualWarehouseVo> queryList(WmsActualWarehouseBo bo) {
|
||
LambdaQueryWrapper<WmsActualWarehouse> lqw = buildQueryWrapper(bo);
|
||
List<WmsActualWarehouseVo> list = baseMapper.selectVoList(lqw);
|
||
|
||
if (CollUtil.isEmpty(list)) {
|
||
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)
|
||
.map(WmsActualWarehouseVo::getActualWarehouseId)
|
||
.filter(Objects::nonNull)
|
||
.distinct()
|
||
.collect(Collectors.toList());
|
||
|
||
if (CollUtil.isEmpty(occupiedAwIds)) {
|
||
return list;
|
||
}
|
||
|
||
// 查询当前在库(del_flag=0, status=0)并且占用这些库位的钢卷,仅选择必要列
|
||
List<WmsMaterialCoil> coils = wmsMaterialCoilMapper.selectList(
|
||
Wrappers.<WmsMaterialCoil>lambdaQuery()
|
||
.select(
|
||
WmsMaterialCoil::getActualWarehouseId,
|
||
WmsMaterialCoil::getCoilId,
|
||
WmsMaterialCoil::getEnterCoilNo,
|
||
WmsMaterialCoil::getCurrentCoilNo,
|
||
WmsMaterialCoil::getSupplierCoilNo
|
||
)
|
||
.in(WmsMaterialCoil::getActualWarehouseId, occupiedAwIds)
|
||
.eq(WmsMaterialCoil::getDelFlag, 0)
|
||
.eq(WmsMaterialCoil::getStatus, 0)
|
||
);
|
||
|
||
if (CollUtil.isEmpty(coils)) {
|
||
return list;
|
||
}
|
||
|
||
// 同一库位若有多条记录,选择最新一条(按更新顺序无字段,这里按主键最大)
|
||
Map<Long, WmsMaterialCoil> coilByAwId = coils.stream()
|
||
.collect(Collectors.toMap(
|
||
WmsMaterialCoil::getActualWarehouseId,
|
||
c -> c,
|
||
(a, b) -> a.getCoilId() != null && b.getCoilId() != null && a.getCoilId() > b.getCoilId() ? a : b
|
||
));
|
||
|
||
list.forEach(it -> {
|
||
if (it.getIsEnabled() != null && it.getIsEnabled() == 0) {
|
||
WmsMaterialCoil c = coilByAwId.get(it.getActualWarehouseId());
|
||
if (c != null) {
|
||
it.setEnterCoilNo(c.getEnterCoilNo());
|
||
it.setCurrentCoilNo(c.getCurrentCoilNo());
|
||
it.setSupplierCoilNo(c.getSupplierCoilNo());
|
||
}
|
||
}
|
||
});
|
||
|
||
return list;
|
||
}
|
||
|
||
@Override
|
||
public List<WmsActualWarehouseTreeVo> queryTree(WmsActualWarehouseBo bo) {
|
||
if (bo == null) {
|
||
bo = new WmsActualWarehouseBo();
|
||
}
|
||
LambdaQueryWrapper<WmsActualWarehouse> wrapper = Wrappers.lambdaQuery();
|
||
wrapper.eq(StringUtils.isNotBlank(bo.getActualWarehouseCode()), WmsActualWarehouse::getActualWarehouseCode, bo.getActualWarehouseCode());
|
||
wrapper.like(StringUtils.isNotBlank(bo.getActualWarehouseName()), WmsActualWarehouse::getActualWarehouseName, bo.getActualWarehouseName());
|
||
wrapper.eq(bo.getActualWarehouseType() != null, WmsActualWarehouse::getActualWarehouseType, bo.getActualWarehouseType());
|
||
wrapper.eq(bo.getIsEnabled() != null, WmsActualWarehouse::getIsEnabled, bo.getIsEnabled());
|
||
wrapper.orderByAsc(WmsActualWarehouse::getSortNo, WmsActualWarehouse::getActualWarehouseId);
|
||
List<WmsActualWarehouseVo> flatList = baseMapper.selectVoList(wrapper);
|
||
Map<Long, WmsActualWarehouseTreeVo> nodeMap = new LinkedHashMap<>();
|
||
flatList.forEach(item -> {
|
||
WmsActualWarehouseTreeVo node = new WmsActualWarehouseTreeVo();
|
||
BeanUtil.copyProperties(item, node);
|
||
nodeMap.put(node.getActualWarehouseId(), node);
|
||
});
|
||
List<WmsActualWarehouseTreeVo> roots = new ArrayList<>();
|
||
nodeMap.values().forEach(node -> {
|
||
Long parentId = Optional.ofNullable(node.getParentId()).orElse(0L);
|
||
if (parentId == 0 || !nodeMap.containsKey(parentId)) {
|
||
roots.add(node);
|
||
} else {
|
||
nodeMap.get(parentId).getChildren().add(node);
|
||
}
|
||
});
|
||
return roots;
|
||
}
|
||
@Override
|
||
public List<WmsActualWarehouseTreeVo> queryTreeExcludeLevelThree(WmsActualWarehouseBo bo) {
|
||
if (bo == null) {
|
||
bo = new WmsActualWarehouseBo();
|
||
}
|
||
// 设置查询条件,排除三级节点(actualWarehouseType=3)
|
||
LambdaQueryWrapper<WmsActualWarehouse> wrapper = Wrappers.lambdaQuery();
|
||
wrapper.eq(StringUtils.isNotBlank(bo.getActualWarehouseCode()), WmsActualWarehouse::getActualWarehouseCode, bo.getActualWarehouseCode());
|
||
wrapper.like(StringUtils.isNotBlank(bo.getActualWarehouseName()), WmsActualWarehouse::getActualWarehouseName, bo.getActualWarehouseName());
|
||
wrapper.eq(bo.getActualWarehouseType() != null, WmsActualWarehouse::getActualWarehouseType, bo.getActualWarehouseType());
|
||
wrapper.eq(bo.getIsEnabled() != null, WmsActualWarehouse::getIsEnabled, bo.getIsEnabled());
|
||
// 排除三级节点(类型为3的节点)
|
||
wrapper.ne(WmsActualWarehouse::getActualWarehouseType, 3);
|
||
wrapper.orderByAsc(WmsActualWarehouse::getSortNo, WmsActualWarehouse::getActualWarehouseId);
|
||
|
||
List<WmsActualWarehouseVo> flatList = baseMapper.selectVoList(wrapper);
|
||
Map<Long, WmsActualWarehouseTreeVo> nodeMap = new LinkedHashMap<>();
|
||
flatList.forEach(item -> {
|
||
WmsActualWarehouseTreeVo node = new WmsActualWarehouseTreeVo();
|
||
BeanUtil.copyProperties(item, node);
|
||
nodeMap.put(node.getActualWarehouseId(), node);
|
||
});
|
||
|
||
List<WmsActualWarehouseTreeVo> roots = new ArrayList<>();
|
||
nodeMap.values().forEach(node -> {
|
||
Long parentId = Optional.ofNullable(node.getParentId()).orElse(0L);
|
||
if (parentId == 0 || !nodeMap.containsKey(parentId)) {
|
||
roots.add(node);
|
||
} else {
|
||
nodeMap.get(parentId).getChildren().add(node);
|
||
}
|
||
});
|
||
return roots;
|
||
}
|
||
|
||
private LambdaQueryWrapper<WmsActualWarehouse> buildQueryWrapper(WmsActualWarehouseBo bo) {
|
||
Map<String, Object> params = bo.getParams();
|
||
LambdaQueryWrapper<WmsActualWarehouse> lqw = Wrappers.lambdaQuery();
|
||
lqw.eq(bo.getParentId() != null, WmsActualWarehouse::getParentId, bo.getParentId());
|
||
lqw.eq(StringUtils.isNotBlank(bo.getActualWarehouseCode()), WmsActualWarehouse::getActualWarehouseCode, bo.getActualWarehouseCode());
|
||
lqw.like(StringUtils.isNotBlank(bo.getActualWarehouseName()), WmsActualWarehouse::getActualWarehouseName, bo.getActualWarehouseName());
|
||
lqw.eq(bo.getActualWarehouseType() != null, WmsActualWarehouse::getActualWarehouseType, bo.getActualWarehouseType());
|
||
lqw.eq(bo.getSortNo() != null, WmsActualWarehouse::getSortNo, bo.getSortNo());
|
||
lqw.eq(bo.getIsEnabled() != null, WmsActualWarehouse::getIsEnabled, bo.getIsEnabled());
|
||
return lqw;
|
||
}
|
||
|
||
/**
|
||
* 新增实际库区/库位自关联
|
||
*/
|
||
@Override
|
||
public Boolean insertByBo(WmsActualWarehouseBo bo) {
|
||
WmsActualWarehouse add = BeanUtil.toBean(bo, WmsActualWarehouse.class);
|
||
validEntityBeforeSave(add);
|
||
boolean flag = baseMapper.insert(add) > 0;
|
||
if (flag) {
|
||
bo.setActualWarehouseId(add.getActualWarehouseId());
|
||
}
|
||
return flag;
|
||
}
|
||
|
||
/**
|
||
* 修改实际库区/库位自关联
|
||
*/
|
||
@Override
|
||
public Boolean updateByBo(WmsActualWarehouseBo bo) {
|
||
WmsActualWarehouse update = BeanUtil.toBean(bo, WmsActualWarehouse.class);
|
||
validEntityBeforeSave(update);
|
||
return baseMapper.updateById(update) > 0;
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public List<Long> createHierarchy(WmsActualWarehouseHierarchyBo bo) {
|
||
if (bo.getLevels() == null || bo.getLevels().isEmpty()) {
|
||
throw new ServiceException("层级数据不能为空");
|
||
}
|
||
List<WmsActualWarehouseHierarchyBo.HierarchyLevel> sortedLevels = bo.getLevels().stream()
|
||
.sorted(Comparator.comparing(WmsActualWarehouseHierarchyBo.HierarchyLevel::getLevel))
|
||
.collect(Collectors.toList());
|
||
Long parentId = 0L;
|
||
List<Long> createdIds = new ArrayList<>();
|
||
for (WmsActualWarehouseHierarchyBo.HierarchyLevel level : sortedLevels) {
|
||
Integer levelValue = level.getLevel();
|
||
if (levelValue == null || levelValue < 1 || levelValue > 3) {
|
||
throw new ServiceException("层级必须在1-3之间");
|
||
}
|
||
if (level.getActualWarehouseId() != null) {
|
||
WmsActualWarehouse existing = baseMapper.selectById(level.getActualWarehouseId());
|
||
if (existing == null) {
|
||
throw new ServiceException("指定的节点不存在:" + level.getActualWarehouseId());
|
||
}
|
||
if (!Objects.equals(Optional.ofNullable(existing.getParentId()).orElse(0L), parentId)) {
|
||
throw new ServiceException("节点不属于当前父级,无法复用");
|
||
}
|
||
parentId = existing.getActualWarehouseId();
|
||
continue;
|
||
}
|
||
if (StringUtils.isBlank(level.getActualWarehouseCode()) || StringUtils.isBlank(level.getActualWarehouseName())) {
|
||
throw new ServiceException("编码与名称不能为空");
|
||
}
|
||
WmsActualWarehouse duplicate = baseMapper.selectOne(Wrappers.<WmsActualWarehouse>lambdaQuery()
|
||
.eq(WmsActualWarehouse::getParentId, parentId)
|
||
.and(wrapper -> wrapper.eq(WmsActualWarehouse::getActualWarehouseCode, level.getActualWarehouseCode())
|
||
.or()
|
||
.eq(WmsActualWarehouse::getActualWarehouseName, level.getActualWarehouseName())));
|
||
if (duplicate != null) {
|
||
parentId = duplicate.getActualWarehouseId();
|
||
continue;
|
||
}
|
||
WmsActualWarehouse entity = new WmsActualWarehouse();
|
||
entity.setParentId(parentId);
|
||
entity.setActualWarehouseType(levelValue.longValue());
|
||
entity.setActualWarehouseCode(level.getActualWarehouseCode());
|
||
entity.setActualWarehouseName(level.getActualWarehouseName());
|
||
entity.setSortNo(Optional.ofNullable(level.getSortNo()).orElse(0L));
|
||
entity.setIsEnabled(Optional.ofNullable(level.getIsEnabled()).orElse(1));
|
||
entity.setRemark(level.getRemark());
|
||
baseMapper.insert(entity);
|
||
parentId = entity.getActualWarehouseId();
|
||
createdIds.add(parentId);
|
||
}
|
||
return createdIds;
|
||
}
|
||
|
||
@Override
|
||
@Transactional(rollbackFor = Exception.class)
|
||
public void importHierarchy(List<WmsActualWarehouseImportVo> importList) {
|
||
if (CollUtil.isEmpty(importList)) {
|
||
throw new ServiceException("导入数据不能为空");
|
||
}
|
||
for (WmsActualWarehouseImportVo row : importList) {
|
||
List<WmsActualWarehouseHierarchyBo.HierarchyLevel> levels = new ArrayList<>();
|
||
appendLevel(levels, 1, row.getLevelOneCode(), row.getLevelOneName(), row.getLevelOneSort());
|
||
appendLevel(levels, 2, row.getLevelTwoCode(), row.getLevelTwoName(), row.getLevelTwoSort());
|
||
appendLevel(levels, 3, row.getLevelThreeCode(), row.getLevelThreeName(), row.getLevelThreeSort());
|
||
if (levels.isEmpty()) {
|
||
continue;
|
||
}
|
||
WmsActualWarehouseHierarchyBo bo = new WmsActualWarehouseHierarchyBo();
|
||
bo.setLevels(levels);
|
||
createHierarchy(bo);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 保存前的数据校验
|
||
*/
|
||
private void validEntityBeforeSave(WmsActualWarehouse entity){
|
||
//TODO 做一些数据校验,如唯一约束
|
||
}
|
||
|
||
private void appendLevel(List<WmsActualWarehouseHierarchyBo.HierarchyLevel> levels,
|
||
int level,
|
||
String code,
|
||
String name,
|
||
Long sortNo) {
|
||
if (StringUtils.isBlank(code) || StringUtils.isBlank(name)) {
|
||
return;
|
||
}
|
||
WmsActualWarehouseHierarchyBo.HierarchyLevel item = new WmsActualWarehouseHierarchyBo.HierarchyLevel();
|
||
item.setLevel(level);
|
||
item.setActualWarehouseCode(code.trim());
|
||
item.setActualWarehouseName(name.trim());
|
||
item.setSortNo(Optional.ofNullable(sortNo).orElse(0L));
|
||
item.setIsEnabled(1);
|
||
levels.add(item);
|
||
}
|
||
|
||
/**
|
||
* 批量删除实际库区/库位自关联
|
||
*/
|
||
@Override
|
||
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
||
if(isValid){
|
||
//TODO 做一些业务上的校验,判断是否需要校验
|
||
}
|
||
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);
|
||
}
|
||
}
|
||
|
||
|
||
}
|