From 345a14d7ae681ab66cc5de3e405da754e0aa32df Mon Sep 17 00:00:00 2001 From: liangzhou <594755172@qq.com> Date: Wed, 9 Oct 2024 19:58:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0=EF=BC=9A?= =?UTF-8?q?=201.=20=E9=9C=80=E6=B1=82=E7=9C=8B=E6=9D=BF=E6=94=B9=E5=8A=A8?= =?UTF-8?q?=202.=20=E4=BF=AE=E5=A4=8D=E6=94=B9=E6=95=B0=E9=87=8F=E6=97=B6?= =?UTF-8?q?=E6=9C=AA=E9=87=8D=E6=96=B0=E5=8F=AB=E6=96=99=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/wms/controller/ExcelController.java | 214 +++++++---- .../java/com/wms/controller/JobComponent.java | 6 - .../controller/KateWorkQueryController.java | 37 ++ .../com/wms/controller/TaskController.java | 18 +- .../wms/entity/app/request/KanbanRequest.java | 6 + src/main/java/com/wms/entity/table/Goods.java | 20 +- .../com/wms/entity/table/OutsideVehicles.java | 1 + .../WmsTaskServiceImplements.java | 173 +++++---- .../WorkServiceImplements.java | 12 +- .../listener/UploadBaseGoodsListener.java | 113 ++++++ .../excel/listener/UploadKanbanListener.java | 134 +++++++ .../wms/utils/excel/vo/BaseGoodsExcelVo.java | 94 +++++ .../utils/excel/vo/KanbanGoodsExcelVo.java | 350 ++++++++++++++++++ 13 files changed, 1016 insertions(+), 162 deletions(-) create mode 100644 src/main/java/com/wms/utils/excel/listener/UploadBaseGoodsListener.java create mode 100644 src/main/java/com/wms/utils/excel/listener/UploadKanbanListener.java create mode 100644 src/main/java/com/wms/utils/excel/vo/BaseGoodsExcelVo.java create mode 100644 src/main/java/com/wms/utils/excel/vo/KanbanGoodsExcelVo.java diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java index f6de774..7cbac4b 100644 --- a/src/main/java/com/wms/controller/ExcelController.java +++ b/src/main/java/com/wms/controller/ExcelController.java @@ -10,8 +10,6 @@ import com.wms.annotation.MyLog; import com.wms.constants.enums.*; import com.wms.entity.app.ResponseEntity; import com.wms.entity.app.dto.PageDto; -import com.wms.entity.app.dto.StockOfGoodsDto; -import com.wms.entity.app.dto.extend.KanbanEntity; import com.wms.entity.app.request.*; import com.wms.entity.app.vo.FileVo; import com.wms.entity.app.vo.UploadRecordVo; @@ -37,8 +35,6 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; -import java.math.BigDecimal; -import java.math.RoundingMode; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.*; @@ -70,10 +66,11 @@ public class ExcelController { private final WorkSummaryService workSummaryService;// 工作分析服务 private final KanbanService kanbanService;// 看板服务 - private final List uploadFileHashStringList = new ArrayList<>(); + private final List uploadFileHashStringList = new ArrayList<>(); /** * 查询上传记录 + * * @param uploadRecordQuery 查询参数 * @return 结果 */ @@ -267,16 +264,16 @@ public class ExcelController { } /** - * 导入看板 + * 导入物料基本信息 * * @param file 文件 * @return 导入结果 */ - @PostMapping("/uploadKanban") + @PostMapping("/uploadBaseGoods") @ResponseBody @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) - public String uploadKanban(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) { - logger.info("导入物料,请求ip:{},文件详情:{}", getIpAddr(servletRequest), convertJsonString(fileVo)); + public String uploadBaseGoods(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) { + logger.info("导入物料基本信息,请求ip:{},文件详情:{}", getIpAddr(servletRequest), convertJsonString(fileVo)); ResponseEntity response = new ResponseEntity(); try { // 判断是否重复导入 @@ -287,20 +284,68 @@ public class ExcelController { } uploadFileHashStringList.add(fileVo.getHash()); // 导入excel - EasyExcel.read(file.getInputStream(), GoodsExcelVo.class, new UploadGoodsListener(goodsService, fileVo.getUserName())).sheet("基本信息").doRead(); + EasyExcel.read(file.getInputStream(), BaseGoodsExcelVo.class, new UploadBaseGoodsListener(goodsService, fileVo.getUserName())).sheet("基本信息").doRead(); // 添加导入记录 - uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "GOODS")); + uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "GOODS_BASE")); uploadFileHashStringList.remove(fileVo.getHash()); response.setCode(ResponseCode.OK.getCode()); - response.setMessage("导入物料成功。"); + response.setMessage("导入物料基本信息成功。"); return convertJsonString(response); } catch (Exception e) { - logger.error("导入物料异常:{}", e.getMessage()); + logger.error("导入物料基本信息异常:{}", e.getMessage()); // 回滚事务 TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); uploadFileHashStringList.remove(fileVo.getHash()); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("导入物料异常:" + e.getMessage()); + response.setMessage("导入物料基本信息异常:" + e.getMessage()); + return convertJsonString(response); + } + } + + /** + * 导入看板 + * + * @param file 文件 + * @return 导入结果 + */ + @PostMapping("/uploadKanban") + @ResponseBody + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) + public String uploadKanban(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) { + logger.info("导入看板,请求ip:{},文件详情:{}", getIpAddr(servletRequest), convertJsonString(fileVo)); + ResponseEntity response = new ResponseEntity(); + try { + // 判断是否重复导入 + if (uploadFileHashStringList.contains(fileVo.getHash())) { + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("请勿导入相同文件。"); + return convertJsonString(response); + } + uploadFileHashStringList.add(fileVo.getHash()); + // 获取之前物料表的内容 + Map goodsMap = goodsService.list().stream().collect(Collectors.toMap(Goods::getGoodsId, goods -> goods)); + if (goodsMap.isEmpty()) { + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("请先导入物料基本信息。"); + return convertJsonString(response); + } + // 查询之前的看板 + Map kanbanMap = kanbanService.list().stream().collect(Collectors.toMap(kanban -> kanban.getGoodsId() + kanban.getKanbanId(), kanban -> kanban)); + // 导入excel + EasyExcel.read(file.getInputStream(), KanbanGoodsExcelVo.class, new UploadKanbanListener(goodsService, goodsMap, kanbanService, kanbanMap, fileVo.getUserName())).sheet("CLC看板信息").doRead(); + // 添加导入记录 + uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "KANBAN")); + uploadFileHashStringList.remove(fileVo.getHash()); + response.setCode(ResponseCode.OK.getCode()); + response.setMessage("导入看板成功。"); + return convertJsonString(response); + } catch (Exception e) { + logger.error("导入看板异常:{}", e.getMessage()); + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + uploadFileHashStringList.remove(fileVo.getHash()); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("导入看板异常:" + e.getMessage()); return convertJsonString(response); } } @@ -377,36 +422,6 @@ public class ExcelController { .doWrite(stockPoList.stream().map(StockExcelVo::of).toList()); } -// /** -// * 导出CLC看板需求 -// * -// * @param response 请求 -// */ -// @PostMapping("/downloadClcKanbanRequirementExcel") -// @ResponseBody -// public void downloadClcKanbanRequirementExcel(@RequestBody KanbanRequest request, HttpServletResponse response) throws IOException { -// logger.info("导出CLC看板需求,筛选参数:{},请求ip:{}", convertJsonString(request), getIpAddr(servletRequest)); -// //设置响应格式 -// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); -//// response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 -// response.setCharacterEncoding("utf-8"); -// // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 -// String fileName = URLEncoder.encode("CLC看板需求", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); -// response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); -// // 内容样式 -// HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); -// // 获取看板需求 -// List KanbanList = kanbanService.list(new LambdaQueryWrapper() -// .eq(StringUtils.isNotEmpty(request.getGoodsId()), Kanban::getGoodsId, request.getGoodsId()) -// .eq(request.getKanbanStatus() != null, Kanban::getKanbanStatus, request.getKanbanStatus())); -// -// EasyExcel.write(response.getOutputStream(), ClcKanbanExcelVo.class) -// .excelType(ExcelTypeEnum.XLSX) -// .registerWriteHandler(horizontalCellStyleStrategy) -// .sheet("CLC看板需求") -// .doWrite(KanbanList.stream().map(ClcKanbanExcelVo::of).toList()); -// } - /** * 导出CLC看板需求 * @@ -414,7 +429,7 @@ public class ExcelController { */ @PostMapping("/downloadClcKanbanRequirementExcel") @ResponseBody - public void downloadClcKanbanRequirementExcel(@RequestBody ClcKanbanRequirementRequest request, HttpServletResponse response) throws IOException { + public void downloadClcKanbanRequirementExcel(@RequestBody KanbanRequest request, HttpServletResponse response) throws IOException { logger.info("导出CLC看板需求,筛选参数:{},请求ip:{}", convertJsonString(request), getIpAddr(servletRequest)); //设置响应格式 response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); @@ -425,50 +440,85 @@ public class ExcelController { response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); // 内容样式 HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); - // 获取导出结果 - List clcKanbanRequirementExcelVoList = new ArrayList<>(); - // 查询物料库存信息 - List stockOfGoodsDtoList = stockService.selectSumOfGoods(""); - if (stockOfGoodsDtoList == null || stockOfGoodsDtoList.isEmpty()) { - clcKanbanRequirementExcelVoList = Collections.emptyList(); - } else { - for (StockOfGoodsDto stockOfGoodsDto : stockOfGoodsDtoList) { - if (Objects.equals(stockOfGoodsDto.getFeedType(), "PULL")) { - // 剩余数量少于补货点时,需要补货 - if (stockOfGoodsDto.getRemainNumSum().compareTo(stockOfGoodsDto.getFeedPoint()) <= 0) { - ClcKanbanRequirementExcelVo tempClcKanbanRequirementExcelVo = new ClcKanbanRequirementExcelVo(); - // 目标数量 - BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban()); - // 计算需要多少个看板 - BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 0, RoundingMode.FLOOR); - // 设定物流数据 - tempClcKanbanRequirementExcelVo.setGoodsId(stockOfGoodsDto.getGoodsId()); - tempClcKanbanRequirementExcelVo.setReleasePoint(stockOfGoodsDto.getReleasePoint()); - // 设定看板 - List needKanbanList = new ArrayList<>(); - for (KanbanEntity kanbanEntity : stockOfGoodsDto.getKanbanList()) { - if (needKanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) { - break; - } - needKanbanQuantity = needKanbanQuantity.subtract(BigDecimal.ONE); - needKanbanList.add(kanbanEntity); - } - if (!needKanbanList.isEmpty()) { - tempClcKanbanRequirementExcelVo.setKanban(needKanbanList); - } - clcKanbanRequirementExcelVoList.add(tempClcKanbanRequirementExcelVo); - } - } - } + // 获取看板需求 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .like(StringUtils.isNotEmpty(request.getGoodsId()), Kanban::getGoodsId, request.getGoodsId()) + .eq(request.getKanbanStatus() != null, Kanban::getKanbanStatus, request.getKanbanStatus()); + if (request.getLastPullTime() != null) { + // 设置收货 + queryWrapper.likeRight(Kanban::getLastPullTime, request.getLastPullTime().toString().substring(0, 10)); } + List KanbanList = kanbanService.list(queryWrapper); - EasyExcel.write(response.getOutputStream(), ClcKanbanRequirementExcelVo.class) + EasyExcel.write(response.getOutputStream(), ClcKanbanExcelVo.class) .excelType(ExcelTypeEnum.XLSX) .registerWriteHandler(horizontalCellStyleStrategy) .sheet("CLC看板需求") - .doWrite(clcKanbanRequirementExcelVoList); + .doWrite(KanbanList.stream().map(ClcKanbanExcelVo::of).toList()); } +// /** +// * 导出CLC看板需求 +// * +// * @param response 请求 +// */ +// @PostMapping("/downloadClcKanbanRequirementExcel") +// @ResponseBody +// public void downloadClcKanbanRequirementExcel(@RequestBody ClcKanbanRequirementRequest request, HttpServletResponse response) throws IOException { +// logger.info("导出CLC看板需求,筛选参数:{},请求ip:{}", convertJsonString(request), getIpAddr(servletRequest)); +// //设置响应格式 +// response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); +//// response.setContentType("application/vnd.ms-excel"); //文件扩展名为excel格式 +// response.setCharacterEncoding("utf-8"); +// // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系 +// String fileName = URLEncoder.encode("CLC看板需求", StandardCharsets.UTF_8).replaceAll("\\+", "%20"); +// response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx"); +// // 内容样式 +// HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); +// // 获取导出结果 +// List clcKanbanRequirementExcelVoList = new ArrayList<>(); +// // 查询物料库存信息 +// List stockOfGoodsDtoList = stockService.selectSumOfGoods(""); +// if (stockOfGoodsDtoList == null || stockOfGoodsDtoList.isEmpty()) { +// clcKanbanRequirementExcelVoList = Collections.emptyList(); +// } else { +// for (StockOfGoodsDto stockOfGoodsDto : stockOfGoodsDtoList) { +// if (Objects.equals(stockOfGoodsDto.getFeedType(), "PULL")) { +// // 剩余数量少于补货点时,需要补货 +// if (stockOfGoodsDto.getRemainNumSum().compareTo(stockOfGoodsDto.getFeedPoint()) <= 0) { +// ClcKanbanRequirementExcelVo tempClcKanbanRequirementExcelVo = new ClcKanbanRequirementExcelVo(); +// // 目标数量 +// BigDecimal targetNum = stockOfGoodsDto.getNumOfKanban().multiply(stockOfGoodsDto.getNumOfPerKanban()); +// // 计算需要多少个看板 +// BigDecimal needKanbanQuantity = targetNum.subtract(stockOfGoodsDto.getRemainNumSum()).divide(stockOfGoodsDto.getNumOfPerKanban(), 0, RoundingMode.FLOOR); +// // 设定物流数据 +// tempClcKanbanRequirementExcelVo.setGoodsId(stockOfGoodsDto.getGoodsId()); +// tempClcKanbanRequirementExcelVo.setReleasePoint(stockOfGoodsDto.getReleasePoint()); +// // 设定看板 +// List needKanbanList = new ArrayList<>(); +// for (KanbanEntity kanbanEntity : stockOfGoodsDto.getKanbanList()) { +// if (needKanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) { +// break; +// } +// needKanbanQuantity = needKanbanQuantity.subtract(BigDecimal.ONE); +// needKanbanList.add(kanbanEntity); +// } +// if (!needKanbanList.isEmpty()) { +// tempClcKanbanRequirementExcelVo.setKanban(needKanbanList); +// } +// clcKanbanRequirementExcelVoList.add(tempClcKanbanRequirementExcelVo); +// } +// } +// } +// } +// +// EasyExcel.write(response.getOutputStream(), ClcKanbanRequirementExcelVo.class) +// .excelType(ExcelTypeEnum.XLSX) +// .registerWriteHandler(horizontalCellStyleStrategy) +// .sheet("CLC看板需求") +// .doWrite(clcKanbanRequirementExcelVoList); +// } + /** * 导出入库记录 * diff --git a/src/main/java/com/wms/controller/JobComponent.java b/src/main/java/com/wms/controller/JobComponent.java index 510e55d..499f473 100644 --- a/src/main/java/com/wms/controller/JobComponent.java +++ b/src/main/java/com/wms/controller/JobComponent.java @@ -133,7 +133,6 @@ public class JobComponent { * 创建工作 */ @Scheduled(fixedDelay = 2000) - @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void createWork() { String createWork = configMap.get(ConfigMapKeyEnum.CREATE_WORK.getConfigKey()); if (StringUtils.isEmpty(createWork) || !createWork.equals("1")) { @@ -148,8 +147,6 @@ public class JobComponent { // 创建工作 workService.createWork(workStation.getStandId()); } catch (Exception e) { - // 回滚事务 - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); logger.error("创建工作时发生错误:{}", convertJsonString(e.getMessage())); } } @@ -159,7 +156,6 @@ public class JobComponent { * 执行工作 */ @Scheduled(fixedDelay = 2000) - @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void doWork() { String startWork = configMap.get(ConfigMapKeyEnum.START_WORK.getConfigKey()); if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) { @@ -174,8 +170,6 @@ public class JobComponent { // 执行工作 workService.doWork(workStation.getStandId()); } catch (Exception e) { - // 回滚事务 - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); logger.error("执行工作时发生错误:{}", convertJsonString(e.getMessage())); } } diff --git a/src/main/java/com/wms/controller/KateWorkQueryController.java b/src/main/java/com/wms/controller/KateWorkQueryController.java index 17f1f1c..c167014 100644 --- a/src/main/java/com/wms/controller/KateWorkQueryController.java +++ b/src/main/java/com/wms/controller/KateWorkQueryController.java @@ -19,6 +19,7 @@ import com.wms.utils.StringUtils; import com.wms.utils.excel.vo.ClcKanbanRequirementExcelVo; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; +import org.joda.time.LocalDate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -638,6 +639,42 @@ public class KateWorkQueryController { } } + /** + * 查询所有看板信息 + */ + @PostMapping("/getClcKanbanByPage") + @ResponseBody + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) + @MyLog(logTitle = "查询所有看板信息", logMethod = "getClcKanbanByPage") + public String getClcKanbanByPage(@RequestBody KanbanRequest request) { + logger.info("接收到查询所有看板信息请求:{},请求ip:{}", convertJsonString(request), HttpUtils.getIpAddr(servletRequest)); + ResponseEntity response = new ResponseEntity(); + try { + Page page = request.toMpPage(); + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .like(StringUtils.isNotEmpty(request.getGoodsId()), Kanban::getGoodsId, request.getGoodsId()) + .eq(request.getKanbanStatus() != null, Kanban::getKanbanStatus, request.getKanbanStatus()); + if (request.getLastPullTime() != null) { + // 设置收货 + queryWrapper.likeRight(Kanban::getLastPullTime, request.getLastPullTime().toString().substring(0, 10)); + } + Page kanbanPage = kanbanService.page(page, queryWrapper); + PageDto pageDto = PageDto.of(kanbanPage, kanban -> BeanUtil.copyProperties(kanban, KanbanVo.class)); + logger.info("查询所有看板信息成功。"); + response.setCode(ResponseCode.OK.getCode()); + response.setMessage("查询所有看板信息成功。"); + response.setReturnData(pageDto); + return convertJsonString(response); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + logger.error("查询所有看板信息发生异常:{}", convertJsonString(e)); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("查询所有看板信息发生异常。"); + return convertJsonString(response); + } + } + /** * 查询工作流 */ diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index e5a73aa..ff646a0 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -377,7 +377,7 @@ public class TaskController { List kanbanList = kanbanService.list(new LambdaQueryWrapper() .eq(Kanban::getGoodsId, goods.getGoodsId()) .eq(Kanban::getKanbanStatus, 0) - .orderByAsc(Kanban::getLastPullTime)); + .orderByAsc(Kanban::getLastRequestTime)); for (Kanban kanban : kanbanList) { if (kanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) { break; @@ -1239,6 +1239,22 @@ public class TaskController { goodsToStation.setDistributeStatus(1); goodsToStationService.updateById(goodsToStation); } + // 查询当前站台的拣货任务 + PickTask pickTask = pickTaskService.getOne(new LambdaQueryWrapper() + .eq(PickTask::getStandId, workFlow.getWorkStation()) + .eq(PickTask::getPickStatus, PickTaskStatusEnum.FINISH.getCode()) + .last("limit 1")); + if (pickTask != null) { + // 更新当前的outsideVehicles状态为一个新状态,拉取任务时不拉取它 + List outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper() + .eq(OutsideVehicles::getVehicleId, pickTask.getVehicleId()) + .eq(OutsideVehicles::getGoodsId, workFlow.getGoodsId())); + for (OutsideVehicles outsideVehicles : outsideVehiclesList) { + outsideVehicles.setOutStatus(2); + } + outsideVehiclesService.updateBatchById(outsideVehiclesList); + } + // 更新workFlow状态 workFlow.setLightStatus(0);// 未亮灯 workFlow.setWorkStatus(1);// 正在做 } else { diff --git a/src/main/java/com/wms/entity/app/request/KanbanRequest.java b/src/main/java/com/wms/entity/app/request/KanbanRequest.java index 6126822..ef2198f 100644 --- a/src/main/java/com/wms/entity/app/request/KanbanRequest.java +++ b/src/main/java/com/wms/entity/app/request/KanbanRequest.java @@ -1,8 +1,10 @@ package com.wms.entity.app.request; +import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lombok.EqualsAndHashCode; +import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDateTime; @@ -38,6 +40,8 @@ public class KanbanRequest extends PageQuery { * 上次补货时间 */ @JsonProperty("lastPullTime") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime lastPullTime; /** * 上次补货人员 @@ -48,6 +52,8 @@ public class KanbanRequest extends PageQuery { * 上次请求看板时间 */ @JsonProperty("lastRequestTime") + @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime lastRequestTime; /** * 上次请求看板用户 diff --git a/src/main/java/com/wms/entity/table/Goods.java b/src/main/java/com/wms/entity/table/Goods.java index 0ebf45b..d7f2c31 100644 --- a/src/main/java/com/wms/entity/table/Goods.java +++ b/src/main/java/com/wms/entity/table/Goods.java @@ -9,7 +9,6 @@ import lombok.Data; import java.math.BigDecimal; import java.time.LocalDateTime; -import java.util.Date; import java.util.List; /** @@ -145,4 +144,23 @@ public class Goods { */ @TableField("release_point") private String releasePoint; + /** + * 盘点管理 + * YES + * NO + */ + @TableField("need_inventory") + private String needInventory; + /** + * SLED管理 + * YES + * NO + */ + @TableField("have_sled") + private String haveSled; + /** + * SLED天数 + */ + @TableField("sled_days") + private Integer SledDays; } diff --git a/src/main/java/com/wms/entity/table/OutsideVehicles.java b/src/main/java/com/wms/entity/table/OutsideVehicles.java index 4a46790..8fe66af 100644 --- a/src/main/java/com/wms/entity/table/OutsideVehicles.java +++ b/src/main/java/com/wms/entity/table/OutsideVehicles.java @@ -37,6 +37,7 @@ public class OutsideVehicles { * 状态 * 0:未出库完成 * 1:已出库完成 + * 2: 不可使用 */ @TableField("out_status") private Integer outStatus; diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java index 292ff97..163b20f 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java @@ -17,6 +17,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -42,6 +46,7 @@ public class WmsTaskServiceImplements implements IWmsTaskService { private final GoodsService goodsService;// 物料服务 private final OutsideVehiclesService outsideVehiclesService;// 流转中的箱子服务 private final PickTaskService pickTaskService;// 拣选任务服务 + private final StandService standService;// 站台服务 /** @@ -299,88 +304,109 @@ public class WmsTaskServiceImplements implements IWmsTaskService { } @Override + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public BigDecimal callGoods(String goodsId, BigDecimal needNum, String workStation) { - // 判断当前物料是否在流转中 - List outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper() - .eq(OutsideVehicles::getGoodsId, goodsId) - .gt(OutsideVehicles::getRemainNum, 0)); - List usedOutsideVehiclesList = new ArrayList<>(); - if (outsideVehiclesList != null && !outsideVehiclesList.isEmpty()) { - // 存在流转中的料箱 - for (OutsideVehicles outsideVehicle : outsideVehiclesList) { - if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 - break; - } - // 查询当前料箱当前物料的库存 - Stock stock = stockService.getOne(new LambdaQueryWrapper() - .eq(Stock::getVehicleId, outsideVehicle.getVehicleId()) - .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId) - .apply("goods_related ->> '$.remainNum' > 0") - .last("limit 1")); - if (stock == null) { - // 没有库存, - outsideVehicle.setRemainNum(BigDecimal.ZERO); - outsideVehiclesService.updateById(outsideVehicle); - } else { - if (outsideVehicle.getRemainNum().compareTo(needNum) > 0) { - // 当前箱子剩余物料数量多于需求数量 - needNum = BigDecimal.ZERO; - outsideVehicle.setRemainNum(outsideVehicle.getRemainNum().subtract(needNum)); - usedOutsideVehiclesList.add(outsideVehicle); + BigDecimal originNum = needNum;// 原始数量 + try { + // 判断当前物料是否在流转中 + List outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper() + .eq(OutsideVehicles::getGoodsId, goodsId) + .gt(OutsideVehicles::getRemainNum, 0) + .ne(OutsideVehicles::getOutStatus, 2)); + List usedOutsideVehiclesList = new ArrayList<>(); + if (outsideVehiclesList != null && !outsideVehiclesList.isEmpty()) { + // 存在流转中的料箱 + for (OutsideVehicles outsideVehicle : outsideVehiclesList) { + if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 break; - } else { - // 当前箱子物料剩余数量少于需求数量 - needNum = needNum.subtract(outsideVehicle.getRemainNum()); + } + // 查询当前料箱当前物料的库存 + Stock stock = stockService.getOne(new LambdaQueryWrapper() + .eq(Stock::getVehicleId, outsideVehicle.getVehicleId()) + .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId) + .apply("goods_related ->> '$.remainNum' > 0") + .last("limit 1")); + if (stock == null) { + // 没有库存, outsideVehicle.setRemainNum(BigDecimal.ZERO); - usedOutsideVehiclesList.add(outsideVehicle); + outsideVehiclesService.updateById(outsideVehicle); + } else { + if (outsideVehicle.getRemainNum().compareTo(needNum) > 0) { + // 当前箱子剩余物料数量多于需求数量 + needNum = BigDecimal.ZERO; + outsideVehicle.setRemainNum(outsideVehicle.getRemainNum().subtract(needNum)); + usedOutsideVehiclesList.add(outsideVehicle); + break; + } else { + // 当前箱子物料剩余数量少于需求数量 + needNum = needNum.subtract(outsideVehicle.getRemainNum()); + outsideVehicle.setRemainNum(BigDecimal.ZERO); + usedOutsideVehiclesList.add(outsideVehicle); + } } } + // 更新流转箱表 + outsideVehiclesService.updateBatchById(usedOutsideVehiclesList); + // 生成拣选任务 + List vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).distinct().toList(); + createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode()); } - // 更新流转箱表 - outsideVehiclesService.updateBatchById(usedOutsideVehiclesList); - // 生成拣选任务 - List vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).distinct().toList(); - createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode()); + return needNum; + } catch (Exception e) { + logger.error("呼叫物料时发生异常:{}", convertJsonString(e)); + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return originNum; } - return needNum; + } @Override + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation) { - // 查询库存,判断数量是否充足 - List stockList = stockService.list(new LambdaQueryWrapper() - .eq(Stock::getStockStatus, StockStatus.OK.getCode()) - .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId) - .orderByAsc(Stock::getCreateTime)); - if (stockList != null && !stockList.isEmpty()) { - List waitForOutStockList = new ArrayList<>(); - // 尝试生成出库任务 - for (Stock tempStock : stockList) { - if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 - break; - } - if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) { - // 当前箱子剩余物料数量多于需求数量 - needNum = BigDecimal.ZERO; - // 设置剩余数量 - StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); - goodsRelated.setRemainNum(goodsRelated.getRemainNum().subtract(needNum)); - tempStock.setGoodsRelated(goodsRelated); - waitForOutStockList.add(tempStock); - break; - } else { - // 当前箱子物料剩余数量少于需求数量 - needNum = needNum.subtract(tempStock.getGoodsRelated().getRemainNum()); - // 设置剩余数量 - StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); - goodsRelated.setRemainNum(BigDecimal.ZERO); - tempStock.setGoodsRelated(goodsRelated); - waitForOutStockList.add(tempStock); + BigDecimal originNum = needNum;// 原始数量 + try { + // 查询库存,判断数量是否充足 + List stockList = stockService.list(new LambdaQueryWrapper() + .eq(Stock::getStockStatus, StockStatus.OK.getCode()) + .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId) + .apply("goods_related ->> '$.remainNum' > 0") + .orderByAsc(Stock::getCreateTime)); + if (stockList != null && !stockList.isEmpty()) { + List waitForOutStockList = new ArrayList<>(); + // 尝试生成出库任务 + for (Stock tempStock : stockList) { + if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 + break; + } + if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) { + // 当前箱子剩余物料数量多于需求数量 + needNum = BigDecimal.ZERO; + // 设置剩余数量 + StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); + goodsRelated.setRemainNum(goodsRelated.getRemainNum().subtract(needNum)); + tempStock.setGoodsRelated(goodsRelated); + waitForOutStockList.add(tempStock); + break; + } else { + // 当前箱子物料剩余数量少于需求数量 + needNum = needNum.subtract(tempStock.getGoodsRelated().getRemainNum()); + // 设置剩余数量 + StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); + goodsRelated.setRemainNum(BigDecimal.ZERO); + tempStock.setGoodsRelated(goodsRelated); + waitForOutStockList.add(tempStock); + } } + createVehicleOutTaskAndPickTask(waitForOutStockList, workStation); } - createVehicleOutTaskAndPickTask(waitForOutStockList, workStation); + return needNum; + } catch (Exception ex) { + logger.error("呼叫库存时发生异常:{}", convertJsonString(ex)); + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + return originNum; } - return needNum; } /** @@ -478,7 +504,9 @@ public class WmsTaskServiceImplements implements IWmsTaskService { List tempPickVehicles = tempPickTasks.stream().map(PickTask::getVehicleId).distinct().toList(); // 拣选任务暂存列表 List pickTasks = new ArrayList<>(); - vehicleIds.forEach(vehicleId -> { + // 增加的拣选任务数量 + int addNum = 0; + for (String vehicleId : vehicleIds) { // 暂存拣选任务 PickTask tempPickTask = new PickTask(); tempPickTask.setPickTaskId(generateId("PICK_")); @@ -488,11 +516,16 @@ public class WmsTaskServiceImplements implements IWmsTaskService { tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode()); } else { tempPickTask.setPickStatus(pickStatus); + addNum++; } tempPickTask.setLastUpdateTime(LocalDateTime.now()); pickTasks.add(tempPickTask); - }); + } // 添加数据库 pickTaskService.saveBatch(pickTasks); + // 更新站台的拣选数量 + standService.update(new LambdaUpdateWrapper() + .setSql("pick_vehicle_count = pick_vehicle_count + " + addNum) + .eq(Stand::getStandId, workStation)); } } diff --git a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java index e41fd4f..2134daf 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java @@ -15,6 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.transaction.interceptor.TransactionAspectSupport; import java.math.BigDecimal; import java.time.LocalDateTime; @@ -48,6 +52,7 @@ public class WorkServiceImplements implements IWorkService { private final List workFinishingStations = new ArrayList<>();// 当前正在完成任务的站台 @Override + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void createWork(String workStation) throws Exception { if (workCreatingStations.contains(workStation)) { // 当前站台正在创建任务 @@ -163,7 +168,8 @@ public class WorkServiceImplements implements IWorkService { } } catch (Exception e) { logger.error("创建站台:{}工作发生异常:{}", workStation, convertJsonString(e)); - throw new Exception("创建站台:" + workStation + "工作发生异常!"); + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } finally { // 当前站台创建任务完成 workCreatingStations.remove(workStation); @@ -171,6 +177,7 @@ public class WorkServiceImplements implements IWorkService { } @Override + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void doWork(String workStation) throws Exception { if (workDoingStations.contains(workStation)) { // 当前站台正在创建任务 @@ -263,7 +270,8 @@ public class WorkServiceImplements implements IWorkService { .eq(KateOrders::getOrderStatus, 1)); } catch (Exception e) { logger.error("执行站台:{}工作发生异常:{}", workStation, convertJsonString(e)); - throw new Exception("执行站台:" + workStation + "工作发生异常!"); + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); } finally { // 当前站台创建任务完成 workDoingStations.remove(workStation); diff --git a/src/main/java/com/wms/utils/excel/listener/UploadBaseGoodsListener.java b/src/main/java/com/wms/utils/excel/listener/UploadBaseGoodsListener.java new file mode 100644 index 0000000..41ddbf0 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/listener/UploadBaseGoodsListener.java @@ -0,0 +1,113 @@ +package com.wms.utils.excel.listener; + +import cn.hutool.core.bean.BeanUtil; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.util.ListUtils; +import com.wms.entity.app.dto.extend.KanbanEntity; +import com.wms.entity.table.Goods; +import com.wms.service.GoodsService; +import com.wms.utils.StringUtils; +import com.wms.utils.excel.vo.BaseGoodsExcelVo; +import com.wms.utils.excel.vo.GoodsExcelVo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +/** + * 上传物料基本信息监听 + */ +public class UploadBaseGoodsListener implements ReadListener { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + /** + * 每隔5条存储数据库,实际使用中可以1000条,然后清理list ,方便内存回收 + */ + private static final int BATCH_COUNT = 1000; + /** + * 保存数据总数 + */ + private int SAVE_COUNT = 0; + private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + private final GoodsService goodsService;// 物料服务 + private final String uploadUser;// 用户 + public UploadBaseGoodsListener(GoodsService goodsService, String uploadUser) { + this.goodsService = goodsService; + this.uploadUser = uploadUser; + } + + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + int rowCount = context.readRowHolder().getRowIndex() + 1; + logger.error("处理物料数据发生异常,第{}行发生异常。", rowCount); + throw new Exception("第" + rowCount + "行数据异常。"); + } + + /** + * 这个每一条数据解析都会来调用 + * + * @param goodsExcelVo one row value. It is same as {@link AnalysisContext#readRowHolder()} + * @param analysisContext context + */ + @Override + public void invoke(BaseGoodsExcelVo goodsExcelVo, AnalysisContext analysisContext) { + if (StringUtils.isNotEmpty(goodsExcelVo.getGoodsId())) { + // 符合条件的数据 + cachedDataList.add(goodsExcelVo); + } + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); + saveData(); + // 存储完成清理 list + cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + } + } + + /** + * 所有数据解析完成了 都会来调用 + * + * @param analysisContext context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); + saveData(); + logger.info("此次共保存{}条数据。", SAVE_COUNT); + } + + /** + * 存储数据 + */ + private void saveData() { + // 开始存储数据 + List goodsList = new ArrayList<>(); + for (BaseGoodsExcelVo goodsExcelVo : cachedDataList) { + Goods tempGoods = new Goods(); + tempGoods.setGoodsId(goodsExcelVo.getGoodsId()); + tempGoods.setGoodsName(goodsExcelVo.getDescription()); + tempGoods.setGoodsUnit("PC"); + tempGoods.setGoodsType(goodsExcelVo.getGoodsType()); + tempGoods.setProviderType(goodsExcelVo.getProviderType()); + tempGoods.setWeight(goodsExcelVo.getWeight()); + tempGoods.setWeightUnit(goodsExcelVo.getWeightUnit()); + tempGoods.setQuantityPerBox(goodsExcelVo.getQuantityPerBox()); + tempGoods.setUnpackingType(goodsExcelVo.getUnpackingType()); + tempGoods.setVehicleType(goodsExcelVo.getVehicleType()); + tempGoods.setVehicleTypeDescription(goodsExcelVo.getPackageType()); + tempGoods.setGoodsInVehicleType(goodsExcelVo.getVehicleDescription()); + tempGoods.setFeedingType(goodsExcelVo.getFeedingType()); + tempGoods.setNeedInventory(goodsExcelVo.getNeedInventory()); + tempGoods.setHaveSled(goodsExcelVo.getHaveSled()); + tempGoods.setSledDays(goodsExcelVo.getSledDays()); + tempGoods.setLastUpdateTime(LocalDateTime.now()); + tempGoods.setLastUpdateUser(uploadUser); + goodsList.add(tempGoods); + } + goodsService.saveOrUpdateBatch(goodsList); + // 打印保存数量 + SAVE_COUNT += goodsList.size(); + } +} diff --git a/src/main/java/com/wms/utils/excel/listener/UploadKanbanListener.java b/src/main/java/com/wms/utils/excel/listener/UploadKanbanListener.java new file mode 100644 index 0000000..13f8ef8 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/listener/UploadKanbanListener.java @@ -0,0 +1,134 @@ +package com.wms.utils.excel.listener; + +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.read.listener.ReadListener; +import com.alibaba.excel.util.ListUtils; +import com.wms.entity.app.dto.extend.KanbanEntity; +import com.wms.entity.table.Goods; +import com.wms.entity.table.Kanban; +import com.wms.service.GoodsService; +import com.wms.service.KanbanService; +import com.wms.utils.StringUtils; +import com.wms.utils.excel.vo.KanbanGoodsExcelVo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static com.wms.utils.WmsUtils.generateId; + +/** + * 上传看板监听 + */ +public class UploadKanbanListener implements ReadListener { + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + /** + * 每隔5条存储数据库,实际使用中可以1000条,然后清理list ,方便内存回收 + */ + private static final int BATCH_COUNT = 1000; + /** + * 保存数据总数 + */ + private int SAVE_COUNT = 0; + private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + private final GoodsService goodsService;// Dbs服务 + private final KanbanService kanbanService;// 看板服务 + private final String uploadUser;// 用户 + private final Map goodsMap;// 物料清单 + private final Map oldKanbanMap;// 看板列表 + public UploadKanbanListener(GoodsService goodsService, Map goodsMap, KanbanService kanbanService, Map oldKanbanMap, String uploadUser) { + this.goodsService = goodsService; + this.goodsMap = goodsMap; + this.kanbanService = kanbanService; + this.oldKanbanMap = oldKanbanMap; + this.uploadUser = uploadUser; + } + + @Override + public void onException(Exception exception, AnalysisContext context) throws Exception { + int rowCount = context.readRowHolder().getRowIndex() + 1; + logger.error("处理物料数据发生异常,第{}行发生异常。", rowCount); + throw new Exception("第" + rowCount + "行数据异常。"); + } + + /** + * 这个每一条数据解析都会来调用 + * + * @param goodsExcelVo one row value. It is same as {@link AnalysisContext#readRowHolder()} + * @param analysisContext context + */ + @Override + public void invoke(KanbanGoodsExcelVo goodsExcelVo, AnalysisContext analysisContext) { + if (goodsMap.containsKey(goodsExcelVo.getGoodsId()) + && StringUtils.isNotEmpty(goodsExcelVo.getGoodsId())) { + // 符合条件的数据 + cachedDataList.add(goodsExcelVo); + } + // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM + if (cachedDataList.size() >= BATCH_COUNT) { + logger.info("导入{}条数据,开始存储数据库!", cachedDataList.size()); + saveData(); + // 存储完成清理 list + cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); + } + } + + /** + * 所有数据解析完成了 都会来调用 + * + * @param analysisContext context + */ + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + logger.info("导入{}条数据,开始存储数据库!", cachedDataList.size()); + saveData(); + logger.info("此次共保存{}条数据。", SAVE_COUNT); + } + + /** + * 存储数据 + */ + private void saveData() { + // 开始存储数据 + List goodsList = new ArrayList<>(); + List newKanbanList = new ArrayList<>(); + for (KanbanGoodsExcelVo goodsExcelVo : cachedDataList) { + Goods currentGoods = goodsMap.get(goodsExcelVo.getGoodsId()); + // 设置信息 + currentGoods.setHeat(goodsExcelVo.getHeat());// 热度 + currentGoods.setReleasePoint(goodsExcelVo.getReleasePoint());// 卸货点 + currentGoods.setFeedingValue(goodsExcelVo.getFeedingPoint());// 补货点 + currentGoods.setQuantityPerKanban(goodsExcelVo.getKanbanQty());// 每个看板物料数量 + currentGoods.setKanbanNum(goodsExcelVo.getNumberOfKanban());// 看板数量 + // 设置看板 + List kanbanList = goodsExcelVo.convertToKanbanList(); + currentGoods.setKanbanList(kanbanList); + currentGoods.setLastUpdateTime(LocalDateTime.now()); + currentGoods.setLastUpdateUser(uploadUser); + goodsList.add(currentGoods); + // 查询当前料所有的看板 + for (KanbanEntity kanbanEntity : kanbanList) { + if (!oldKanbanMap.containsKey(currentGoods.getGoodsId() + kanbanEntity.getKanbanId())) { + // 添加新看板 + Kanban newKanban = new Kanban(); + newKanban.setRecordId(generateId("KANBAN_")); + newKanban.setGoodsId(currentGoods.getGoodsId()); + newKanban.setKanbanId(kanbanEntity.getKanbanId()); + newKanban.setKanbanStatus(1);// 默认置满 + newKanban.setLastPullTime(LocalDateTime.now()); + newKanban.setLastPullUser(uploadUser); + newKanbanList.add(newKanban); + } + } + } + // 保存物料看板信息 + goodsService.saveOrUpdateBatch(goodsList); + // 保存看板需求信息 + kanbanService.saveOrUpdateBatch(newKanbanList); + // 打印保存数量 + SAVE_COUNT += goodsList.size(); + } +} diff --git a/src/main/java/com/wms/utils/excel/vo/BaseGoodsExcelVo.java b/src/main/java/com/wms/utils/excel/vo/BaseGoodsExcelVo.java new file mode 100644 index 0000000..69afcc9 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/BaseGoodsExcelVo.java @@ -0,0 +1,94 @@ +package com.wms.utils.excel.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 基本信息 + */ +@Data +public class BaseGoodsExcelVo { + /** + * 物料分类 + */ + @ExcelProperty("物料分类") + private String goodsType; + /** + * 供应商分类 + */ + @ExcelProperty("供应商分类") + private String providerType; + /** + * 料号 + */ + @ExcelProperty("料号") + private String goodsId; + /** + * 描述 + */ + @ExcelProperty("描述") + private String description; + /** + * 重量 + */ + @ExcelProperty("重量") + private BigDecimal weight; + /** + * 重量单位 + */ + @ExcelProperty("重量单位") + private String weightUnit; + /** + * 每盒数量 + */ + @ExcelProperty("每盒数量") + private BigDecimal quantityPerBox; + /** + * 来料包装 + */ + @ExcelProperty("来料包装") + private String packageType; + /** + * 料箱类型 + */ + @ExcelProperty("料箱类型") + private String vehicleType; + /** + * 料箱描述 + */ + @ExcelProperty("料箱描述") + private String vehicleDescription; + /** + * 盘点管理 + * YES + * NO + */ + @ExcelProperty("盘点管理") + private String needInventory; + /** + * SLED管理 + * YES + * NO + */ + @ExcelProperty("SLED管理") + private String haveSled; + /** + * SLED天数 + */ + @ExcelProperty("SLED天数") + private Integer SledDays; + /** + * 拆包方式 + */ + @ExcelProperty("拆包方式") + private String unpackingType; + /** + * 补料方式 + * PULL:有看板 + * PUSH:无看板 + */ + @ExcelProperty("补料方式") + private String feedingType; +} diff --git a/src/main/java/com/wms/utils/excel/vo/KanbanGoodsExcelVo.java b/src/main/java/com/wms/utils/excel/vo/KanbanGoodsExcelVo.java new file mode 100644 index 0000000..3bc9571 --- /dev/null +++ b/src/main/java/com/wms/utils/excel/vo/KanbanGoodsExcelVo.java @@ -0,0 +1,350 @@ +package com.wms.utils.excel.vo; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.wms.entity.app.dto.extend.KanbanEntity; +import com.wms.utils.StringUtils; +import lombok.Data; + +import java.lang.reflect.Field; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.List; + +/** + * 看板ExcelVO + */ +@Data +public class KanbanGoodsExcelVo { + /** + * 料号 + */ + @ExcelProperty("料号") + private String goodsId; + /** + * 热度 + */ + @ExcelProperty("热度") + private String heat; + /** + * 卸货点 + */ + @ExcelProperty("卸货点") + private String releasePoint; + /** + * 看板QTY + */ + @ExcelProperty("看板QTY") + private BigDecimal kanbanQty; + /** + * Number of Kanban + */ + @ExcelProperty("Number of Kanban") + private BigDecimal numberOfKanban; + /** + * 补货点 + */ + @ExcelProperty("补货点") + private BigDecimal feedingPoint; + /** + * KANBAN#1 + */ + @ExcelProperty("KANBAN#1") + private String KANBAN1; + /** + * KANBAN#2 + */ + @ExcelProperty("KANBAN#2") + private String KANBAN2; + /** + * KANBAN#3 + */ + @ExcelProperty("KANBAN#3") + private String KANBAN3; + /** + * KANBAN#4 + */ + @ExcelProperty("KANBAN#4") + private String KANBAN4; + /** + * KANBAN#5 + */ + @ExcelProperty("KANBAN#5") + private String KANBAN5; + /** + * KANBAN#6 + */ + @ExcelProperty("KANBAN#6") + private String KANBAN6; + /** + * KANBAN#7 + */ + @ExcelProperty("KANBAN#7") + private String KANBAN7; + /** + * KANBAN#8 + */ + @ExcelProperty("KANBAN#8") + private String KANBAN8; + /** + * KANBAN#9 + */ + @ExcelProperty("KANBAN#9") + private String KANBAN9; + /** + * KANBAN#10 + */ + @ExcelProperty("KANBAN#10") + private String KANBAN10; + /** + * KANBAN#11 + */ + @ExcelProperty("KANBAN#11") + private String KANBAN11; + /** + * KANBAN#12 + */ + @ExcelProperty("KANBAN#12") + private String KANBAN12; + /** + * KANBAN#13 + */ + @ExcelProperty("KANBAN#13") + private String KANBAN13; + /** + * KANBAN#14 + */ + @ExcelProperty("KANBAN#14") + private String KANBAN14; + /** + * KANBAN#15 + */ + @ExcelProperty("KANBAN#15") + private String KANBAN15; + /** + * KANBAN#16 + */ + @ExcelProperty("KANBAN#16") + private String KANBAN16; + /** + * KANBAN#17 + */ + @ExcelProperty("KANBAN#17") + private String KANBAN17; + /** + * KANBAN#18 + */ + @ExcelProperty("KANBAN#18") + private String KANBAN18; + /** + * KANBAN#19 + */ + @ExcelProperty("KANBAN#19") + private String KANBAN19; + /** + * KANBAN#20 + */ + @ExcelProperty("KANBAN#20") + private String KANBAN20; + /** + * KANBAN#21 + */ + @ExcelProperty("KANBAN#21") + private String KANBAN21; + /** + * KANBAN#22 + */ + @ExcelProperty("KANBAN#22") + private String KANBAN22; + /** + * KANBAN#23 + */ + @ExcelProperty("KANBAN#23") + private String KANBAN23; + /** + * KANBAN#24 + */ + @ExcelProperty("KANBAN#24") + private String KANBAN24; + /** + * KANBAN#25 + */ + @ExcelProperty("KANBAN#25") + private String KANBAN25; + /** + * KANBAN#26 + */ + @ExcelProperty("KANBAN#26") + private String KANBAN26; + /** + * KANBAN#27 + */ + @ExcelProperty("KANBAN#27") + private String KANBAN27; + /** + * KANBAN#28 + */ + @ExcelProperty("KANBAN#28") + private String KANBAN28; + /** + * KANBAN#29 + */ + @ExcelProperty("KANBAN#29") + private String KANBAN29; + /** + * KANBAN#30 + */ + @ExcelProperty("KANBAN#30") + private String KANBAN30; + /** + * KANBAN#31 + */ + @ExcelProperty("KANBAN#31") + private String KANBAN31; + /** + * KANBAN#32 + */ + @ExcelProperty("KANBAN#32") + private String KANBAN32; + /** + * KANBAN#33 + */ + @ExcelProperty("KANBAN#33") + private String KANBAN33; + /** + * KANBAN#34 + */ + @ExcelProperty("KANBAN#34") + private String KANBAN34; + /** + * KANBAN#35 + */ + @ExcelProperty("KANBAN#35") + private String KANBAN35; + /** + * KANBAN#36 + */ + @ExcelProperty("KANBAN#36") + private String KANBAN36; + /** + * KANBAN#37 + */ + @ExcelProperty("KANBAN#37") + private String KANBAN37; + /** + * KANBAN#38 + */ + @ExcelProperty("KANBAN#38") + private String KANBAN38; + /** + * KANBAN#39 + */ + @ExcelProperty("KANBAN#39") + private String KANBAN39; + /** + * KANBAN#40 + */ + @ExcelProperty("KANBAN#40") + private String KANBAN40; + /** + * KANBAN#41 + */ + @ExcelProperty("KANBAN#41") + private String KANBAN41; + /** + * KANBAN#42 + */ + @ExcelProperty("KANBAN#42") + private String KANBAN42; + /** + * KANBAN#43 + */ + @ExcelProperty("KANBAN#43") + private String KANBAN43; + /** + * KANBAN#44 + */ + @ExcelProperty("KANBAN#44") + private String KANBAN44; + /** + * KANBAN#45 + */ + @ExcelProperty("KANBAN#45") + private String KANBAN45; + /** + * KANBAN#46 + */ + @ExcelProperty("KANBAN#46") + private String KANBAN46; + /** + * KANBAN#47 + */ + @ExcelProperty("KANBAN#47") + private String KANBAN47; + /** + * KANBAN#48 + */ + @ExcelProperty("KANBAN#48") + private String KANBAN48; + /** + * KANBAN#49 + */ + @ExcelProperty("KANBAN#49") + private String KANBAN49; + /** + * KANBAN#50 + */ + @ExcelProperty("KANBAN#50") + private String KANBAN50; + + /** + * 设定看板 + * @param kanbanList 看板列表 + */ + public void setKanban(List kanbanList) { + for (Field field : this.getClass().getDeclaredFields()) { + if (field.getName().startsWith("KANBAN")) { + int sortNum = -1; + try { + // 获取id排序 + sortNum = Integer.parseInt(field.getName().split("KANBAN")[1]); + } catch (Exception e) { + continue; + } + if (sortNum != -1) { + try { + if (kanbanList.size() >= sortNum) { + field.setAccessible(true); + field.set(this, kanbanList.get(sortNum - 1).getKanbanId()); + } + } catch (IllegalAccessException e) { + // 捕捉异常 + System.out.println("设置看板发生异常:" + e.getMessage()); + } + } + } + } + } + + /** + * 设定看板 + */ + public List convertToKanbanList() { + List kanbanList = new ArrayList<>(); + for (Field field : this.getClass().getDeclaredFields()) { + if (field.getName().startsWith("KANBAN")) { + try { + field.setAccessible(true); + if (field.get(this) != null && StringUtils.isNotEmpty(String.valueOf(field.get(this)))) { + KanbanEntity kanbanEntity = new KanbanEntity(); + kanbanEntity.setKanbanId(String.valueOf(field.get(this))); + kanbanList.add(kanbanEntity); + } + } catch (IllegalAccessException e) { + // 捕捉异常 + System.out.println("转化看板数据配置时发生异常:" + e.getMessage()); + } + } + } + return kanbanList; + } +}