代码更新:

1. 需求看板改动
2. 修复改数量时未重新叫料问题
This commit is contained in:
梁州 2024-10-09 19:58:42 +08:00
parent 3ab306eaf4
commit 345a14d7ae
13 changed files with 1016 additions and 162 deletions

View File

@ -10,8 +10,6 @@ import com.wms.annotation.MyLog;
import com.wms.constants.enums.*; import com.wms.constants.enums.*;
import com.wms.entity.app.ResponseEntity; import com.wms.entity.app.ResponseEntity;
import com.wms.entity.app.dto.PageDto; 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.request.*;
import com.wms.entity.app.vo.FileVo; import com.wms.entity.app.vo.FileVo;
import com.wms.entity.app.vo.UploadRecordVo; import com.wms.entity.app.vo.UploadRecordVo;
@ -37,8 +35,6 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
@ -70,10 +66,11 @@ public class ExcelController {
private final WorkSummaryService workSummaryService;// 工作分析服务 private final WorkSummaryService workSummaryService;// 工作分析服务
private final KanbanService kanbanService;// 看板服务 private final KanbanService kanbanService;// 看板服务
private final List<String> uploadFileHashStringList = new ArrayList<>(); private final List<String> uploadFileHashStringList = new ArrayList<>();
/** /**
* 查询上传记录 * 查询上传记录
*
* @param uploadRecordQuery 查询参数 * @param uploadRecordQuery 查询参数
* @return 结果 * @return 结果
*/ */
@ -267,16 +264,16 @@ public class ExcelController {
} }
/** /**
* 导入看板 * 导入物料基本信息
* *
* @param file 文件 * @param file 文件
* @return 导入结果 * @return 导入结果
*/ */
@PostMapping("/uploadKanban") @PostMapping("/uploadBaseGoods")
@ResponseBody @ResponseBody
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public String uploadKanban(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) { public String uploadBaseGoods(@RequestPart("file") MultipartFile file, @RequestPart("obj") FileVo fileVo) {
logger.info("导入物料请求ip{},文件详情:{}", getIpAddr(servletRequest), convertJsonString(fileVo)); logger.info("导入物料基本信息请求ip{},文件详情:{}", getIpAddr(servletRequest), convertJsonString(fileVo));
ResponseEntity response = new ResponseEntity(); ResponseEntity response = new ResponseEntity();
try { try {
// 判断是否重复导入 // 判断是否重复导入
@ -287,20 +284,68 @@ public class ExcelController {
} }
uploadFileHashStringList.add(fileVo.getHash()); uploadFileHashStringList.add(fileVo.getHash());
// 导入excel // 导入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()); uploadFileHashStringList.remove(fileVo.getHash());
response.setCode(ResponseCode.OK.getCode()); response.setCode(ResponseCode.OK.getCode());
response.setMessage("导入物料成功。"); response.setMessage("导入物料基本信息成功。");
return convertJsonString(response); return convertJsonString(response);
} catch (Exception e) { } catch (Exception e) {
logger.error("导入物料异常:{}", e.getMessage()); logger.error("导入物料基本信息异常:{}", e.getMessage());
// 回滚事务 // 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
uploadFileHashStringList.remove(fileVo.getHash()); uploadFileHashStringList.remove(fileVo.getHash());
response.setCode(ResponseCode.ERROR.getCode()); 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<String, Goods> 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<String, Kanban> 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); return convertJsonString(response);
} }
} }
@ -377,36 +422,6 @@ public class ExcelController {
.doWrite(stockPoList.stream().map(StockExcelVo::of).toList()); .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<Kanban> KanbanList = kanbanService.list(new LambdaQueryWrapper<Kanban>()
// .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看板需求 * 导出CLC看板需求
* *
@ -414,7 +429,7 @@ public class ExcelController {
*/ */
@PostMapping("/downloadClcKanbanRequirementExcel") @PostMapping("/downloadClcKanbanRequirementExcel")
@ResponseBody @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)); logger.info("导出CLC看板需求筛选参数{}请求ip{}", convertJsonString(request), getIpAddr(servletRequest));
//设置响应格式 //设置响应格式
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); 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"); response.setHeader("Content-Disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 内容样式 // 内容样式
HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle(); HorizontalCellStyleStrategy horizontalCellStyleStrategy = ExcelContentStyle.getContentStyle();
// 获取导出结果 // 获取看板需求
List<ClcKanbanRequirementExcelVo> clcKanbanRequirementExcelVoList = new ArrayList<>(); LambdaQueryWrapper<Kanban> queryWrapper = new LambdaQueryWrapper<Kanban>()
// 查询物料库存信息 .like(StringUtils.isNotEmpty(request.getGoodsId()), Kanban::getGoodsId, request.getGoodsId())
List<StockOfGoodsDto> stockOfGoodsDtoList = stockService.selectSumOfGoods(""); .eq(request.getKanbanStatus() != null, Kanban::getKanbanStatus, request.getKanbanStatus());
if (stockOfGoodsDtoList == null || stockOfGoodsDtoList.isEmpty()) { if (request.getLastPullTime() != null) {
clcKanbanRequirementExcelVoList = Collections.emptyList(); // 设置收货
} else { queryWrapper.likeRight(Kanban::getLastPullTime, request.getLastPullTime().toString().substring(0, 10));
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<KanbanEntity> 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);
}
}
}
} }
List<Kanban> KanbanList = kanbanService.list(queryWrapper);
EasyExcel.write(response.getOutputStream(), ClcKanbanRequirementExcelVo.class) EasyExcel.write(response.getOutputStream(), ClcKanbanExcelVo.class)
.excelType(ExcelTypeEnum.XLSX) .excelType(ExcelTypeEnum.XLSX)
.registerWriteHandler(horizontalCellStyleStrategy) .registerWriteHandler(horizontalCellStyleStrategy)
.sheet("CLC看板需求") .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<ClcKanbanRequirementExcelVo> clcKanbanRequirementExcelVoList = new ArrayList<>();
// // 查询物料库存信息
// List<StockOfGoodsDto> 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<KanbanEntity> 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);
// }
/** /**
* 导出入库记录 * 导出入库记录
* *

View File

@ -133,7 +133,6 @@ public class JobComponent {
* 创建工作 * 创建工作
*/ */
@Scheduled(fixedDelay = 2000) @Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void createWork() { public void createWork() {
String createWork = configMap.get(ConfigMapKeyEnum.CREATE_WORK.getConfigKey()); String createWork = configMap.get(ConfigMapKeyEnum.CREATE_WORK.getConfigKey());
if (StringUtils.isEmpty(createWork) || !createWork.equals("1")) { if (StringUtils.isEmpty(createWork) || !createWork.equals("1")) {
@ -148,8 +147,6 @@ public class JobComponent {
// 创建工作 // 创建工作
workService.createWork(workStation.getStandId()); workService.createWork(workStation.getStandId());
} catch (Exception e) { } catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("创建工作时发生错误:{}", convertJsonString(e.getMessage())); logger.error("创建工作时发生错误:{}", convertJsonString(e.getMessage()));
} }
} }
@ -159,7 +156,6 @@ public class JobComponent {
* 执行工作 * 执行工作
*/ */
@Scheduled(fixedDelay = 2000) @Scheduled(fixedDelay = 2000)
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void doWork() { public void doWork() {
String startWork = configMap.get(ConfigMapKeyEnum.START_WORK.getConfigKey()); String startWork = configMap.get(ConfigMapKeyEnum.START_WORK.getConfigKey());
if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) { if (StringUtils.isEmpty(startWork) || !startWork.equals("1")) {
@ -174,8 +170,6 @@ public class JobComponent {
// 执行工作 // 执行工作
workService.doWork(workStation.getStandId()); workService.doWork(workStation.getStandId());
} catch (Exception e) { } catch (Exception e) {
// 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
logger.error("执行工作时发生错误:{}", convertJsonString(e.getMessage())); logger.error("执行工作时发生错误:{}", convertJsonString(e.getMessage()));
} }
} }

View File

@ -19,6 +19,7 @@ import com.wms.utils.StringUtils;
import com.wms.utils.excel.vo.ClcKanbanRequirementExcelVo; import com.wms.utils.excel.vo.ClcKanbanRequirementExcelVo;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.joda.time.LocalDate;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; 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<Kanban> page = request.toMpPage();
LambdaQueryWrapper<Kanban> queryWrapper = new LambdaQueryWrapper<Kanban>()
.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<Kanban> kanbanPage = kanbanService.page(page, queryWrapper);
PageDto<KanbanVo> 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);
}
}
/** /**
* 查询工作流 * 查询工作流
*/ */

View File

@ -377,7 +377,7 @@ public class TaskController {
List<Kanban> kanbanList = kanbanService.list(new LambdaQueryWrapper<Kanban>() List<Kanban> kanbanList = kanbanService.list(new LambdaQueryWrapper<Kanban>()
.eq(Kanban::getGoodsId, goods.getGoodsId()) .eq(Kanban::getGoodsId, goods.getGoodsId())
.eq(Kanban::getKanbanStatus, 0) .eq(Kanban::getKanbanStatus, 0)
.orderByAsc(Kanban::getLastPullTime)); .orderByAsc(Kanban::getLastRequestTime));
for (Kanban kanban : kanbanList) { for (Kanban kanban : kanbanList) {
if (kanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) { if (kanbanQuantity.compareTo(BigDecimal.ZERO) <= 0) {
break; break;
@ -1239,6 +1239,22 @@ public class TaskController {
goodsToStation.setDistributeStatus(1); goodsToStation.setDistributeStatus(1);
goodsToStationService.updateById(goodsToStation); goodsToStationService.updateById(goodsToStation);
} }
// 查询当前站台的拣货任务
PickTask pickTask = pickTaskService.getOne(new LambdaQueryWrapper<PickTask>()
.eq(PickTask::getStandId, workFlow.getWorkStation())
.eq(PickTask::getPickStatus, PickTaskStatusEnum.FINISH.getCode())
.last("limit 1"));
if (pickTask != null) {
// 更新当前的outsideVehicles状态为一个新状态拉取任务时不拉取它
List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
.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.setLightStatus(0);// 未亮灯
workFlow.setWorkStatus(1);// 正在做 workFlow.setWorkStatus(1);// 正在做
} else { } else {

View File

@ -1,8 +1,10 @@
package com.wms.entity.app.request; package com.wms.entity.app.request;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -38,6 +40,8 @@ public class KanbanRequest extends PageQuery {
* 上次补货时间 * 上次补货时间
*/ */
@JsonProperty("lastPullTime") @JsonProperty("lastPullTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastPullTime; private LocalDateTime lastPullTime;
/** /**
* 上次补货人员 * 上次补货人员
@ -48,6 +52,8 @@ public class KanbanRequest extends PageQuery {
* 上次请求看板时间 * 上次请求看板时间
*/ */
@JsonProperty("lastRequestTime") @JsonProperty("lastRequestTime")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime lastRequestTime; private LocalDateTime lastRequestTime;
/** /**
* 上次请求看板用户 * 上次请求看板用户

View File

@ -9,7 +9,6 @@ import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -145,4 +144,23 @@ public class Goods {
*/ */
@TableField("release_point") @TableField("release_point")
private String releasePoint; 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;
} }

View File

@ -37,6 +37,7 @@ public class OutsideVehicles {
* 状态 * 状态
* 0未出库完成 * 0未出库完成
* 1已出库完成 * 1已出库完成
* 2: 不可使用
*/ */
@TableField("out_status") @TableField("out_status")
private Integer outStatus; private Integer outStatus;

View File

@ -17,6 +17,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; 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.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -42,6 +46,7 @@ public class WmsTaskServiceImplements implements IWmsTaskService {
private final GoodsService goodsService;// 物料服务 private final GoodsService goodsService;// 物料服务
private final OutsideVehiclesService outsideVehiclesService;// 流转中的箱子服务 private final OutsideVehiclesService outsideVehiclesService;// 流转中的箱子服务
private final PickTaskService pickTaskService;// 拣选任务服务 private final PickTaskService pickTaskService;// 拣选任务服务
private final StandService standService;// 站台服务
/** /**
@ -299,88 +304,109 @@ public class WmsTaskServiceImplements implements IWmsTaskService {
} }
@Override @Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public BigDecimal callGoods(String goodsId, BigDecimal needNum, String workStation) { public BigDecimal callGoods(String goodsId, BigDecimal needNum, String workStation) {
// 判断当前物料是否在流转中 BigDecimal originNum = needNum;// 原始数量
List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>() try {
.eq(OutsideVehicles::getGoodsId, goodsId) // 判断当前物料是否在流转中
.gt(OutsideVehicles::getRemainNum, 0)); List<OutsideVehicles> outsideVehiclesList = outsideVehiclesService.list(new LambdaQueryWrapper<OutsideVehicles>()
List<OutsideVehicles> usedOutsideVehiclesList = new ArrayList<>(); .eq(OutsideVehicles::getGoodsId, goodsId)
if (outsideVehiclesList != null && !outsideVehiclesList.isEmpty()) { .gt(OutsideVehicles::getRemainNum, 0)
// 存在流转中的料箱 .ne(OutsideVehicles::getOutStatus, 2));
for (OutsideVehicles outsideVehicle : outsideVehiclesList) { List<OutsideVehicles> usedOutsideVehiclesList = new ArrayList<>();
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 if (outsideVehiclesList != null && !outsideVehiclesList.isEmpty()) {
break; // 存在流转中的料箱
} for (OutsideVehicles outsideVehicle : outsideVehiclesList) {
// 查询当前料箱当前物料的库存 if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0
Stock stock = stockService.getOne(new LambdaQueryWrapper<Stock>()
.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);
break; break;
} else { }
// 当前箱子物料剩余数量少于需求数量 // 查询当前料箱当前物料的库存
needNum = needNum.subtract(outsideVehicle.getRemainNum()); Stock stock = stockService.getOne(new LambdaQueryWrapper<Stock>()
.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); 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<String> vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).distinct().toList();
createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode());
} }
// 更新流转箱表 return needNum;
outsideVehiclesService.updateBatchById(usedOutsideVehiclesList); } catch (Exception e) {
// 生成拣选任务 logger.error("呼叫物料时发生异常:{}", convertJsonString(e));
List<String> vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).distinct().toList(); // 回滚事务
createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode()); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
return originNum;
} }
return needNum;
} }
@Override @Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation) { public BigDecimal callStocks(String goodsId, BigDecimal needNum, String workStation) {
// 查询库存判断数量是否充足 BigDecimal originNum = needNum;// 原始数量
List<Stock> stockList = stockService.list(new LambdaQueryWrapper<Stock>() try {
.eq(Stock::getStockStatus, StockStatus.OK.getCode()) // 查询库存判断数量是否充足
.apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId) List<Stock> stockList = stockService.list(new LambdaQueryWrapper<Stock>()
.orderByAsc(Stock::getCreateTime)); .eq(Stock::getStockStatus, StockStatus.OK.getCode())
if (stockList != null && !stockList.isEmpty()) { .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, goodsId)
List<Stock> waitForOutStockList = new ArrayList<>(); .apply("goods_related ->> '$.remainNum' > 0")
// 尝试生成出库任务 .orderByAsc(Stock::getCreateTime));
for (Stock tempStock : stockList) { if (stockList != null && !stockList.isEmpty()) {
if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0 List<Stock> waitForOutStockList = new ArrayList<>();
break; // 尝试生成出库任务
} for (Stock tempStock : stockList) {
if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) { if (needNum.compareTo(BigDecimal.ZERO) <= 0) {// 需求数量小于等于0
// 当前箱子剩余物料数量多于需求数量 break;
needNum = BigDecimal.ZERO; }
// 设置剩余数量 if (tempStock.getGoodsRelated().getRemainNum().compareTo(needNum) > 0) {
StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); // 当前箱子剩余物料数量多于需求数量
goodsRelated.setRemainNum(goodsRelated.getRemainNum().subtract(needNum)); needNum = BigDecimal.ZERO;
tempStock.setGoodsRelated(goodsRelated); // 设置剩余数量
waitForOutStockList.add(tempStock); StockDetailInfo goodsRelated = tempStock.getGoodsRelated();
break; goodsRelated.setRemainNum(goodsRelated.getRemainNum().subtract(needNum));
} else { tempStock.setGoodsRelated(goodsRelated);
// 当前箱子物料剩余数量少于需求数量 waitForOutStockList.add(tempStock);
needNum = needNum.subtract(tempStock.getGoodsRelated().getRemainNum()); break;
// 设置剩余数量 } else {
StockDetailInfo goodsRelated = tempStock.getGoodsRelated(); // 当前箱子物料剩余数量少于需求数量
goodsRelated.setRemainNum(BigDecimal.ZERO); needNum = needNum.subtract(tempStock.getGoodsRelated().getRemainNum());
tempStock.setGoodsRelated(goodsRelated); // 设置剩余数量
waitForOutStockList.add(tempStock); 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<String> tempPickVehicles = tempPickTasks.stream().map(PickTask::getVehicleId).distinct().toList(); List<String> tempPickVehicles = tempPickTasks.stream().map(PickTask::getVehicleId).distinct().toList();
// 拣选任务暂存列表 // 拣选任务暂存列表
List<PickTask> pickTasks = new ArrayList<>(); List<PickTask> pickTasks = new ArrayList<>();
vehicleIds.forEach(vehicleId -> { // 增加的拣选任务数量
int addNum = 0;
for (String vehicleId : vehicleIds) {
// 暂存拣选任务 // 暂存拣选任务
PickTask tempPickTask = new PickTask(); PickTask tempPickTask = new PickTask();
tempPickTask.setPickTaskId(generateId("PICK_")); tempPickTask.setPickTaskId(generateId("PICK_"));
@ -488,11 +516,16 @@ public class WmsTaskServiceImplements implements IWmsTaskService {
tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode()); tempPickTask.setPickStatus(PickTaskStatusEnum.TEMP.getCode());
} else { } else {
tempPickTask.setPickStatus(pickStatus); tempPickTask.setPickStatus(pickStatus);
addNum++;
} }
tempPickTask.setLastUpdateTime(LocalDateTime.now()); tempPickTask.setLastUpdateTime(LocalDateTime.now());
pickTasks.add(tempPickTask); pickTasks.add(tempPickTask);
}); }
// 添加数据库 // 添加数据库
pickTaskService.saveBatch(pickTasks); pickTaskService.saveBatch(pickTasks);
// 更新站台的拣选数量
standService.update(new LambdaUpdateWrapper<Stand>()
.setSql("pick_vehicle_count = pick_vehicle_count + " + addNum)
.eq(Stand::getStandId, workStation));
} }
} }

View File

@ -15,6 +15,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; 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.math.BigDecimal;
import java.time.LocalDateTime; import java.time.LocalDateTime;
@ -48,6 +52,7 @@ public class WorkServiceImplements implements IWorkService {
private final List<String> workFinishingStations = new ArrayList<>();// 当前正在完成任务的站台 private final List<String> workFinishingStations = new ArrayList<>();// 当前正在完成任务的站台
@Override @Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void createWork(String workStation) throws Exception { public void createWork(String workStation) throws Exception {
if (workCreatingStations.contains(workStation)) { if (workCreatingStations.contains(workStation)) {
// 当前站台正在创建任务 // 当前站台正在创建任务
@ -163,7 +168,8 @@ public class WorkServiceImplements implements IWorkService {
} }
} catch (Exception e) { } catch (Exception e) {
logger.error("创建站台:{}工作发生异常:{}", workStation, convertJsonString(e)); logger.error("创建站台:{}工作发生异常:{}", workStation, convertJsonString(e));
throw new Exception("创建站台:" + workStation + "工作发生异常!"); // 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally { } finally {
// 当前站台创建任务完成 // 当前站台创建任务完成
workCreatingStations.remove(workStation); workCreatingStations.remove(workStation);
@ -171,6 +177,7 @@ public class WorkServiceImplements implements IWorkService {
} }
@Override @Override
@Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED)
public void doWork(String workStation) throws Exception { public void doWork(String workStation) throws Exception {
if (workDoingStations.contains(workStation)) { if (workDoingStations.contains(workStation)) {
// 当前站台正在创建任务 // 当前站台正在创建任务
@ -263,7 +270,8 @@ public class WorkServiceImplements implements IWorkService {
.eq(KateOrders::getOrderStatus, 1)); .eq(KateOrders::getOrderStatus, 1));
} catch (Exception e) { } catch (Exception e) {
logger.error("执行站台:{}工作发生异常:{}", workStation, convertJsonString(e)); logger.error("执行站台:{}工作发生异常:{}", workStation, convertJsonString(e));
throw new Exception("执行站台:" + workStation + "工作发生异常!"); // 回滚事务
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally { } finally {
// 当前站台创建任务完成 // 当前站台创建任务完成
workDoingStations.remove(workStation); workDoingStations.remove(workStation);

View File

@ -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<BaseGoodsExcelVo> {
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<BaseGoodsExcelVo> 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<Goods> 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();
}
}

View File

@ -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<KanbanGoodsExcelVo> {
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<KanbanGoodsExcelVo> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT);
private final GoodsService goodsService;// Dbs服务
private final KanbanService kanbanService;// 看板服务
private final String uploadUser;// 用户
private final Map<String, Goods> goodsMap;// 物料清单
private final Map<String, Kanban> oldKanbanMap;// 看板列表
public UploadKanbanListener(GoodsService goodsService, Map<String, Goods> goodsMap, KanbanService kanbanService, Map<String, Kanban> 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<Goods> goodsList = new ArrayList<>();
List<Kanban> 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<KanbanEntity> 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();
}
}

View File

@ -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;
}

View File

@ -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<KanbanEntity> 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<KanbanEntity> convertToKanbanList() {
List<KanbanEntity> 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;
}
}