前后端修改

This commit is contained in:
2025-11-25 01:13:26 +08:00
parent f0a1598fa3
commit 28d0852a81
18 changed files with 1574 additions and 440 deletions

View File

@@ -2,10 +2,13 @@ package com.klp.controller;
import java.util.List;
import java.util.Arrays;
import java.util.ArrayList;
import lombok.RequiredArgsConstructor;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.*;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import com.klp.common.annotation.RepeatSubmit;
@@ -16,9 +19,13 @@ import com.klp.common.core.domain.R;
import com.klp.common.core.validate.AddGroup;
import com.klp.common.core.validate.EditGroup;
import com.klp.common.enums.BusinessType;
import com.klp.common.excel.ExcelResult;
import com.klp.common.utils.poi.ExcelUtil;
import com.klp.domain.vo.WmsActualWarehouseVo;
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
import com.klp.domain.vo.WmsActualWarehouseImportVo;
import com.klp.domain.bo.WmsActualWarehouseBo;
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
import com.klp.service.IWmsActualWarehouseService;
/**
@@ -44,6 +51,34 @@ public class WmsActualWarehouseController extends BaseController {
return R.ok(list);
}
/**
* 获取完整三级目录树
*/
@GetMapping("/tree")
public R<List<WmsActualWarehouseTreeVo>> tree(WmsActualWarehouseBo bo) {
return R.ok(iWmsActualWarehouseService.queryTree(bo));
}
/**
* 导入实际库区/库位数据
*/
@Log(title = "实际库区/库位自关联", businessType = BusinessType.IMPORT)
@PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<Void> importData(@RequestPart("file") MultipartFile file) throws Exception {
ExcelResult<WmsActualWarehouseImportVo> result = ExcelUtil.importExcel(file.getInputStream(), WmsActualWarehouseImportVo.class, true);
iWmsActualWarehouseService.importHierarchy(result.getList());
return R.ok(result.getAnalysis());
}
/**
* 下载导入模板
*/
@PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) {
List<WmsActualWarehouseImportVo> template = buildTemplateData();
ExcelUtil.exportExcel(template, "实际库区导入模板", WmsActualWarehouseImportVo.class, response);
}
/**
* 导出实际库区/库位自关联列表
*/
@@ -75,6 +110,15 @@ public class WmsActualWarehouseController extends BaseController {
return toAjax(iWmsActualWarehouseService.insertByBo(bo));
}
/**
* 批量新增或复用层级目录
*/
@Log(title = "实际库区/库位自关联-批量新增", businessType = BusinessType.INSERT)
@PostMapping("/hierarchy")
public R<List<Long>> addHierarchy(@Validated @RequestBody WmsActualWarehouseHierarchyBo bo) {
return R.ok(iWmsActualWarehouseService.createHierarchy(bo));
}
/**
* 修改实际库区/库位自关联
*/
@@ -96,4 +140,30 @@ public class WmsActualWarehouseController extends BaseController {
@PathVariable Long[] actualWarehouseIds) {
return toAjax(iWmsActualWarehouseService.deleteWithValidByIds(Arrays.asList(actualWarehouseIds), true));
}
private List<WmsActualWarehouseImportVo> buildTemplateData() {
List<WmsActualWarehouseImportVo> list = new ArrayList<>();
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-A", "A通道", 10L, "L1-001-A-01", "A-01货位", 10L));
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-A", "A通道", 10L, "L1-001-A-02", "A-02货位", 20L));
list.add(buildRow("L1-001", "一号库区", 10L, "L1-001-B", "B通道", 20L, "L1-001-B-01", "B-01货位", 10L));
list.add(buildRow("L1-002", "二号库区", 20L, "L1-002-A", "冷藏区", 10L, null, null, null));
list.add(buildRow("L1-002", "二号库区", 20L, "L1-002-B", "常温区", 20L, "L1-002-B-01", "常温-01", 10L));
return list;
}
private WmsActualWarehouseImportVo buildRow(String l1Code, String l1Name, Long l1Sort,
String l2Code, String l2Name, Long l2Sort,
String l3Code, String l3Name, Long l3Sort) {
WmsActualWarehouseImportVo vo = new WmsActualWarehouseImportVo();
vo.setLevelOneCode(l1Code);
vo.setLevelOneName(l1Name);
vo.setLevelOneSort(l1Sort);
vo.setLevelTwoCode(l2Code);
vo.setLevelTwoName(l2Name);
vo.setLevelTwoSort(l2Sort);
vo.setLevelThreeCode(l3Code);
vo.setLevelThreeName(l3Name);
vo.setLevelThreeSort(l3Sort);
return vo;
}
}

View File

@@ -0,0 +1,64 @@
package com.klp.domain.bo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import javax.validation.Valid;
import javax.validation.constraints.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 用于批量新增/匹配一级-三级节点的请求体
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class WmsActualWarehouseHierarchyBo implements Serializable {
@NotEmpty(message = "三级目录数据不能为空")
@Valid
private List<HierarchyLevel> levels = new ArrayList<>();
@Data
public static class HierarchyLevel implements Serializable {
/**
* 层级1/2/3
*/
@NotNull(message = "层级不能为空")
@Min(value = 1, message = "层级最小为1")
@Max(value = 3, message = "层级最大为3")
private Integer level;
/**
* 选中了已有节点时携带的ID用于比对去重
*/
private Long actualWarehouseId;
/**
* 编码(当 actualWarehouseId 为空时必填)
*/
private String actualWarehouseCode;
/**
* 名称(当 actualWarehouseId 为空时必填)
*/
private String actualWarehouseName;
/**
* 同级排序号
*/
private Long sortNo;
/**
* 状态
*/
private Integer isEnabled;
/**
* 备注
*/
private String remark;
}
}

View File

@@ -0,0 +1,41 @@
package com.klp.domain.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
/**
* 实际库区/库位导入模板
*/
@Data
@ExcelIgnoreUnannotated
public class WmsActualWarehouseImportVo {
@ExcelProperty("一级编码")
private String levelOneCode;
@ExcelProperty("一级名称")
private String levelOneName;
@ExcelProperty("一级排序号")
private Long levelOneSort;
@ExcelProperty("二级编码")
private String levelTwoCode;
@ExcelProperty("二级名称")
private String levelTwoName;
@ExcelProperty("二级排序号")
private Long levelTwoSort;
@ExcelProperty("三级编码")
private String levelThreeCode;
@ExcelProperty("三级名称")
private String levelThreeName;
@ExcelProperty("三级排序号")
private Long levelThreeSort;
}

View File

@@ -0,0 +1,18 @@
package com.klp.domain.vo;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.ArrayList;
import java.util.List;
/**
* 树形结构视图对象,用于一次性返回三级目录
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class WmsActualWarehouseTreeVo extends WmsActualWarehouseVo {
private List<WmsActualWarehouseTreeVo> children = new ArrayList<>();
}

View File

@@ -1,8 +1,10 @@
package com.klp.service;
import com.klp.domain.WmsActualWarehouse;
import com.klp.domain.vo.WmsActualWarehouseVo;
import com.klp.domain.vo.WmsActualWarehouseTreeVo;
import com.klp.domain.vo.WmsActualWarehouseImportVo;
import com.klp.domain.bo.WmsActualWarehouseBo;
import com.klp.domain.bo.WmsActualWarehouseHierarchyBo;
import java.util.Collection;
import java.util.List;
@@ -26,11 +28,26 @@ public interface IWmsActualWarehouseService {
*/
List<WmsActualWarehouseVo> queryList(WmsActualWarehouseBo bo);
/**
* 查询完整的三级目录树
*/
List<WmsActualWarehouseTreeVo> queryTree(WmsActualWarehouseBo bo);
/**
* 新增实际库区/库位自关联
*/
Boolean insertByBo(WmsActualWarehouseBo bo);
/**
* 通过一次提交批量创建/复用三级目录
*/
List<Long> createHierarchy(WmsActualWarehouseHierarchyBo bo);
/**
* 导入层级目录
*/
void importHierarchy(List<WmsActualWarehouseImportVo> importList);
/**
* 修改实际库区/库位自关联
*/

View File

@@ -1,20 +1,25 @@
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.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.List;
import java.util.Map;
import java.util.Collection;
import java.util.*;
import java.util.stream.Collectors;
/**
* 实际库区/库位自关联Service业务层处理
@@ -46,6 +51,36 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
return baseMapper.selectVoList(lqw);
}
@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;
}
private LambdaQueryWrapper<WmsActualWarehouse> buildQueryWrapper(WmsActualWarehouseBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<WmsActualWarehouse> lqw = Wrappers.lambdaQuery();
@@ -82,6 +117,80 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
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);
}
}
/**
* 保存前的数据校验
*/
@@ -89,6 +198,23 @@ public class WmsActualWarehouseServiceImpl implements IWmsActualWarehouseService
//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);
}
/**
* 批量删除实际库区/库位自关联
*/

View File

@@ -56,7 +56,7 @@ public class WmsCoilPendingActionServiceImpl implements IWmsCoilPendingActionSer
qw.eq(bo.getCoilId() != null, "wcpa.coil_id", bo.getCoilId());
qw.like(StringUtils.isNotBlank(bo.getCurrentCoilNo()), "wcpa.current_coil_no", bo.getCurrentCoilNo());
qw.eq(bo.getActionType() != null, "wcpa.action_type", bo.getActionType());
qw.eq(bo.getActionStatus() != null, "wcpa.action_status", bo.getActionStatus());
qw.ne(bo.getActionStatus() != null, "wcpa.action_status",2);
qw.eq(bo.getWarehouseId() != null, "wcpa.warehouse_id", bo.getWarehouseId());
qw.eq(bo.getPriority() != null, "wcpa.priority", bo.getPriority());
qw.like(StringUtils.isNotBlank(bo.getSourceType()), "wcpa.source_type", bo.getSourceType());