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.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 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; /** * 查询实际库区/库位自关联 */ @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 (rows == null || cols == null || layers == null || rows < 1 || cols < 1 || layers < 1) { throw new ServiceException("行/列/层必须为正整数"); } if (StringUtils.isBlank(prefix)) { throw new ServiceException("前缀不能为空"); } // 预生成候选编码 List codes = new ArrayList<>(rows * cols * layers); for (int c = 1; c <= cols; c++) { for (int r = 1; r <= rows; r++) { String rStr = r < 10 ? ("0" + r) : String.valueOf(r); for (int l = 1; l <= layers; l++) { String code = prefix + c + rStr + '-' + l; codes.add(code); } } } // 去重:过滤同父级下已存在的编码 List exists = baseMapper.selectList(Wrappers.lambdaQuery() .eq(WmsActualWarehouse::getParentId, parentId) .in(!codes.isEmpty(), WmsActualWarehouse::getActualWarehouseCode, codes)); Set existCodes = exists.stream().map(WmsActualWarehouse::getActualWarehouseCode).collect(Collectors.toSet()); List toInsert = new ArrayList<>(); for (String code : codes) { if (existCodes.contains(code)) { continue; } WmsActualWarehouse e = new WmsActualWarehouse(); e.setParentId(parentId); e.setActualWarehouseType(2L); 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 queryList(WmsActualWarehouseBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); return baseMapper.selectVoList(lqw); } @Override public List queryTree(WmsActualWarehouseBo bo) { if (bo == null) { bo = new WmsActualWarehouseBo(); } LambdaQueryWrapper 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 flatList = baseMapper.selectVoList(wrapper); Map nodeMap = new LinkedHashMap<>(); flatList.forEach(item -> { WmsActualWarehouseTreeVo node = new WmsActualWarehouseTreeVo(); BeanUtil.copyProperties(item, node); nodeMap.put(node.getActualWarehouseId(), node); }); List 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 queryTreeExcludeLevelThree(WmsActualWarehouseBo bo) { if (bo == null) { bo = new WmsActualWarehouseBo(); } // 设置查询条件,排除三级节点(actualWarehouseType=3) LambdaQueryWrapper 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 flatList = baseMapper.selectVoList(wrapper); Map nodeMap = new LinkedHashMap<>(); flatList.forEach(item -> { WmsActualWarehouseTreeVo node = new WmsActualWarehouseTreeVo(); BeanUtil.copyProperties(item, node); nodeMap.put(node.getActualWarehouseId(), node); }); List 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 buildQueryWrapper(WmsActualWarehouseBo bo) { Map params = bo.getParams(); LambdaQueryWrapper 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 createHierarchy(WmsActualWarehouseHierarchyBo bo) { if (bo.getLevels() == null || bo.getLevels().isEmpty()) { throw new ServiceException("层级数据不能为空"); } List sortedLevels = bo.getLevels().stream() .sorted(Comparator.comparing(WmsActualWarehouseHierarchyBo.HierarchyLevel::getLevel)) .collect(Collectors.toList()); Long parentId = 0L; List 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.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 importList) { if (CollUtil.isEmpty(importList)) { throw new ServiceException("导入数据不能为空"); } for (WmsActualWarehouseImportVo row : importList) { List 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 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 ids, Boolean isValid) { if(isValid){ //TODO 做一些业务上的校验,判断是否需要校验 } return baseMapper.deleteBatchIds(ids) > 0; } }