diff --git a/src/main/java/com/wms/config/InitLocalConfig.java b/src/main/java/com/wms/config/InitLocalConfig.java index dbf1e68..a1dc895 100644 --- a/src/main/java/com/wms/config/InitLocalConfig.java +++ b/src/main/java/com/wms/config/InitLocalConfig.java @@ -1,7 +1,9 @@ package com.wms.config; import com.wms.entity.table.Config; +import com.wms.entity.table.Location; import com.wms.service.ConfigService; +import com.wms.service.LocationService; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,6 +16,7 @@ import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Component @Order(1) @@ -23,8 +26,13 @@ public class InitLocalConfig implements ApplicationRunner { * 配置类 */ private final ConfigService configService; + /** + * 库位服务 + */ + private final LocationService locationService; protected final Logger logger = LoggerFactory.getLogger(this.getClass()); public static Map configMap = new HashMap(); + public static Map instantLocationMap = new HashMap<>(); @Override public void run(ApplicationArguments args) { List configs = configService.selectConfigs(""); @@ -34,5 +42,8 @@ public class InitLocalConfig implements ApplicationRunner { logger.info("导入系统配置成功---{}:{}", config.getConfigName(), config.getConfigValue()); } } + // 生成库位Map + instantLocationMap = locationService.list().stream().collect(Collectors.toMap(Location::getLocationId, location -> location)); + logger.info("生成库位Map成功"); } } diff --git a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java index 7f25554..8b943b6 100644 --- a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java +++ b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java @@ -10,6 +10,7 @@ public enum ConfigMapKeyEnum { CREATE_WORK("CREATE_WORK"), START_WORK("START_WORK"), SEND_TASK("SEND_TASK"), + SEND_PICK_OUT_TASK("SEND_PICK_OUT_TASK"), MAX_VEHICLE_NUMS("MAX_VEHICLE_NUMS"), MAX_WCS_ACCEPT_NUMS("MAX_WCS_ACCEPT_NUMS"), SLOC_FILTER_STRING("SLOC_FILTER_STRING"), diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java index dc6828a..08c2ca0 100644 --- a/src/main/java/com/wms/controller/ExcelController.java +++ b/src/main/java/com/wms/controller/ExcelController.java @@ -41,10 +41,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Objects; +import java.util.*; +import java.util.stream.Collectors; import static com.wms.constants.WmsConstants.MYSQL_JSON_CI; import static com.wms.utils.HttpUtils.getIpAddr; @@ -66,9 +64,7 @@ public class ExcelController { private final LocationService locationService;// 库位服务 private final UploadRecordService uploadRecordService;// 上传服务 private final KateDBSService kateDbsService;// Dbs服务 - private final KateDBSLastService kateDbsLastService;// Dbs上次记录服务 private final KateOrdersService kateOrdersService;// 工单服务 - private final KateOrdersLastService kateOrdersLastService;// 工单上次服务 private final GoodsService goodsService;// 物料服务 private final WorkStationConfigService workStationConfigService;// 工站配置服务 @@ -167,14 +163,10 @@ public class ExcelController { return convertJsonString(response); } uploadFileHashStringList.add(fileVo.getHash()); - // 先移除之前last表中的内容 - kateDbsLastService.remove(new LambdaQueryWrapper<>()); - // 将当前Dbs表的数据存进Last表 - kateDbsLastService.saveBatch(BeanUtil.copyToList(kateDbsService.list(), KateDBSLast.class)); - // 移库Dbs表中的内容 - kateDbsService.remove(new LambdaQueryWrapper<>()); + // 获取之前DBS表的内容 + Map kateDbsMap = kateDbsService.list().stream().collect(Collectors.toMap(KateDBS::getWorkOrder, kateDBS -> kateDBS)); // 导入excel - EasyExcel.read(file.getInputStream(), KateDbsExcelVo.class, new UploadDbsListener(kateDbsService, kateDbsLastService, fileVo.getUserName())).sheet().headRowNumber(8).doRead(); + EasyExcel.read(file.getInputStream(), KateDbsExcelVo.class, new UploadDbsListener(kateDbsService, kateDbsMap, fileVo.getUserName())).sheet().headRowNumber(8).doRead(); // 添加导入记录 uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "DBS")); uploadFileHashStringList.remove(fileVo.getHash()); @@ -212,16 +204,10 @@ public class ExcelController { return convertJsonString(response); } uploadFileHashStringList.add(fileVo.getHash()); - // 先移除之前last表中的内容 - kateOrdersLastService.remove(new LambdaQueryWrapper<>()); - // 将当前工单表的数据存进Last表 - List kateOrdersLastList = BeanUtil.copyToList(kateOrdersService.list(), KateOrdersLast.class); - kateOrdersLastService.saveBatch(kateOrdersLastList); - // 移库工单表中的内容 - kateOrdersService.remove(new LambdaQueryWrapper<>()); + // 获取之前工单表的内容 + Map kateOrdersMap = kateOrdersService.list().stream().collect(Collectors.toMap(kateOrders -> kateOrders.getWorkOrder() + kateOrders.getGoodsId() + kateOrders.getSupplyArea(), kateOrders -> kateOrders)); // 导入excel - // TODO - EasyExcel.read(file.getInputStream(), KateOrdersExcelVo.class, new UploadKateOrdersListener(kateOrdersLastList, kateOrdersService, fileVo.getUserName())).sheet().doRead(); + EasyExcel.read(file.getInputStream(), KateOrdersExcelVo.class, new UploadKateOrdersListener(kateOrdersService, kateOrdersMap, fileVo.getUserName())).sheet().doRead(); // 添加导入记录 uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "ORDERS")); uploadFileHashStringList.remove(fileVo.getHash()); @@ -299,7 +285,8 @@ public class ExcelController { } uploadFileHashStringList.add(fileVo.getHash()); // 导入excel - EasyExcel.read(file.getInputStream(), StationConfigExcelVo.class, new UploadStationConfigListener(workStationConfigService, fileVo.getUserName())).sheet("工站配置").doRead(); + Map oldWorkStationConfigMap = workStationConfigService.list().stream().collect(Collectors.toMap(WorkStationConfig::getSmallBox, workStationConfig -> workStationConfig)); + EasyExcel.read(file.getInputStream(), StationConfigExcelVo.class, new UploadStationConfigListener(workStationConfigService, oldWorkStationConfigMap, fileVo.getUserName())).sheet("工站配置").doRead(); // 添加导入记录 uploadRecordService.save(UploadRecord.ofFileVo(fileVo, "STATION-CONFIG_")); uploadFileHashStringList.remove(fileVo.getHash()); diff --git a/src/main/java/com/wms/controller/JobComponent.java b/src/main/java/com/wms/controller/JobComponent.java index 72c3210..7cdefed 100644 --- a/src/main/java/com/wms/controller/JobComponent.java +++ b/src/main/java/com/wms/controller/JobComponent.java @@ -63,6 +63,26 @@ public class JobComponent { } } + /** + * 向Wcs下发站台拣选出库任务 + * 每2秒执行一次 + */ + @Scheduled(fixedDelay = 2000) + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) + public void sendPickOutTasks() { + String sendTask = configMap.get(ConfigMapKeyEnum.SEND_PICK_OUT_TASK.getConfigKey()); + if (StringUtils.isEmpty(sendTask) || !sendTask.equals("1")) { + return; + } + try { + // 发送站台拣选出库任务 + wmsJobService.sendPickOutTasks(); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + } + } + /** * 拣选任务 * 每2秒执行一次 diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index 2bb419b..e4f3213 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -605,6 +605,7 @@ public class TaskController { .set(Task::getDestination, nextLocationId) .set(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()) .eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo()) + .eq(Task::getTaskType, TaskType.IN.getCode()) .eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode()); if (!taskService.update(lambdaUpdateWrapperOfTask)) { // 回退库位锁定 @@ -900,7 +901,7 @@ public class TaskController { if (pickTask == null || StringUtils.isEmpty(pickTask.getVehicleId())) { logger.error("当前站台查不到正在拣选的箱子"); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("当前站台查不到正在拣选的箱子"); + response.setMessage("当前站台查不到正在拣选的箱子,请尝试拣选界面修改当前料箱状态。"); return convertJsonString(response); } String vehicleId = pickTask.getVehicleId(); @@ -912,7 +913,7 @@ public class TaskController { if (stock == null || StringUtils.isEmpty(stock.getStockId()) || stock.getGoodsRelated() == null) { logger.error("请求料号:{}与正在拣选的箱子:{}无对应关系", workQuery.getGoodsId(), vehicleId); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("请求料号:" + workQuery.getGoodsId() + "与正在拣选的箱子:" + vehicleId + "无对应关系"); + response.setMessage("请求料号:" + workQuery.getGoodsId() + "与正在拣选的箱子:" + vehicleId + "无对应关系,请扫描其他料号或者按按钮。"); return convertJsonString(response); } // 查一下物料信息 @@ -930,7 +931,7 @@ public class TaskController { if (workFlows == null || workFlows.isEmpty()) { logger.error("当前站台当前物料查询不到对应的工作"); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("当前站台当前物料查询不到对应的工作"); + response.setMessage("当前站台当前物料查询不到对应的工作,请扫描其他料号或者按按钮。"); return convertJsonString(response); } // 亮灯 @@ -1027,26 +1028,8 @@ public class TaskController { standPickVo.setPlanPickNum(originNum.subtract(realNum)); standPickVo.setRemainNumOrigin(realNum); standPickVo.setRemainNumReal(realNum); - try { - // 获取当前站台已完成数量 - List allWorkFlows = workFlowService.list(); - int finishingRows = 0; - BigDecimal finishedCounts = BigDecimal.ZERO; - BigDecimal allCounts = BigDecimal.ZERO; - for (WorkFlow workFlow : allWorkFlows) { - if (workFlow.getWorkStatus() == 2) { - finishingRows++; - } - finishedCounts = finishedCounts.add(workFlow.getPickedNum()); - allCounts = allCounts.add(workFlow.getNeedNum()); - } - standPickVo.setFinishedRows(finishingRows); - standPickVo.setTotalRows(allWorkFlows.size()); - standPickVo.setFinishedCounts(finishedCounts); - standPickVo.setTotalCounts(allCounts); - } catch (Exception e) { - logger.error("获取已完成数据报表失败,可能存在类型转换错误"); - } + // 获取完成工作信息 + getFinishedInfo(standId, standPickVo); standPickVo.setRemark(goodsInfo != null ? goodsInfo.getUnpackingType() : ""); // 返回成功 response.setCode(ResponseCode.OK.getCode()); @@ -1103,6 +1086,8 @@ public class TaskController { // 返回成功 StandPickVo standPickVo = new StandPickVo(); standPickVo.setTip(targetStand.getPickTip()); + // 获取完成工作信息 + getFinishedInfo(targetStand.getStandId(), standPickVo); response.setCode(ResponseCode.OK.getCode()); response.setMessage("当前物料拣货完成。"); response.setReturnData(standPickVo); @@ -1139,6 +1124,33 @@ public class TaskController { } } + /** + * 获取已完成行数信息 + * @param standPickVo 查询 + */ + public void getFinishedInfo(String workStation, StandPickVo standPickVo) { + try { + // 获取当前站台所有的工作流信息 + List allWorkFlows = workFlowService.list(new LambdaQueryWrapper().eq(WorkFlow::getWorkStation, workStation)); + int finishingRows = 0; + BigDecimal finishedCounts = BigDecimal.ZERO; + BigDecimal allCounts = BigDecimal.ZERO; + for (WorkFlow workFlow : allWorkFlows) { + if (workFlow.getWorkStatus() == 2) { + finishingRows++; + } + finishedCounts = finishedCounts.add(workFlow.getPickedNum()); + allCounts = allCounts.add(workFlow.getNeedNum()); + } + standPickVo.setFinishedRows(finishingRows); + standPickVo.setTotalRows(allWorkFlows.size()); + standPickVo.setFinishedCounts(finishedCounts); + standPickVo.setTotalCounts(allCounts); + } catch (Exception e) { + logger.error("获取已完成数据报表失败,可能存在类型转换错误"); + } + } + /** * 获取电子标签反馈 * @@ -1192,11 +1204,12 @@ public class TaskController { GoodsToStation goodsToStation = goodsToStationService.getOne(new LambdaQueryWrapper() .eq(GoodsToStation::getWorkStation, workFlow.getWorkStation()) .eq(GoodsToStation::getGoodsId, workFlow.getGoodsId()) - .lt(GoodsToStation::getDistributeStatus, 2) +// .lt(GoodsToStation::getDistributeStatus, 2) .last("limit 1")); if (goodsToStation != null) { // 更新站台要料数量 - goodsToStation.setDistributedNum(goodsToStation.getDistributedNum().subtract(BigDecimal.valueOf(diffNum))); + BigDecimal newDistributeNum = goodsToStation.getDistributedNum().subtract(BigDecimal.valueOf(diffNum)); + goodsToStation.setDistributedNum(newDistributeNum.compareTo(BigDecimal.ZERO) <= 0 ? BigDecimal.ZERO : newDistributeNum); goodsToStation.setDistributeStatus(1); goodsToStationService.updateById(goodsToStation); } @@ -1842,49 +1855,52 @@ public class TaskController { // 生成料箱出库任务 int needNum = callEmptyVehicleRequest.getNeedNum(); - List vehicleOutTasks = new ArrayList<>(); - // TODO - while (needNum > 0) { - // 先找空箱 - Vehicle emptyVehicle = vehicleService.getOne(new LambdaQueryWrapper() - .eq(StringUtils.isNotEmpty(callEmptyVehicleRequest.getVehicleType1()), Vehicle::getVehicleType, callEmptyVehicleRequest.getVehicleType1()) - .eq(Vehicle::getIsEmpty, 1) - .eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) - .orderByAsc(Vehicle::getLastInTime) - .last("limit 1")); - if (emptyVehicle != null) {// 有可用的空箱 - // 创建一个空箱出库任务 - Task emptyVehicleTask = new Task(); - emptyVehicleTask.setTaskId(generateId("VCK_")); - emptyVehicleTask.setTaskType(TaskType.OUT.getCode()); - emptyVehicleTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); - emptyVehicleTask.setOrigin(emptyVehicle.getCurrentLocation()); - emptyVehicleTask.setDestination(""); - emptyVehicleTask.setTaskPriority(1); - emptyVehicleTask.setTaskGroup(generateId("")); - emptyVehicleTask.setVehicleId(emptyVehicle.getVehicleId()); - emptyVehicleTask.setWeight(BigDecimal.ZERO); - emptyVehicleTask.setVehicleSize(1); - emptyVehicleTask.setCreateTime(LocalDateTime.now()); - emptyVehicleTask.setUserName(callEmptyVehicleRequest.getUserName()); - emptyVehicleTask.setIsPicking(0); - vehicleOutTasks.add(emptyVehicleTask); - // 更新料箱信息 - emptyVehicle.setVehicleStatus(VehicleStatus.OUT.getCode()); - vehicleService.updateById(emptyVehicle); - needNum--; - } else {// 已经没有空箱可用了 - // TODO 这里后续增加出不出带料箱子的配置 + List vehicleOutTasks = new ArrayList<>();// 任务列表 + List outVehicleIds = new ArrayList<>();// 料箱列表 + // 查询出需求数量的空箱 + List emptyVehicles = vehicleService.list(new LambdaQueryWrapper() + .eq(StringUtils.isNotEmpty(callEmptyVehicleRequest.getVehicleType1()), Vehicle::getVehicleType, callEmptyVehicleRequest.getVehicleType1()) + .eq(Vehicle::getIsEmpty, 1) + .eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) + .orderByAsc(Vehicle::getLastInTime) + .last("limit " + needNum)); + for (Vehicle emptyVehicle : emptyVehicles) { + if (needNum <= 0) { break; } + // 创建一个空箱出库任务 + Task emptyVehicleTask = new Task(); + emptyVehicleTask.setTaskId(generateId("VCK_")); + emptyVehicleTask.setTaskType(TaskType.OUT.getCode()); + emptyVehicleTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + emptyVehicleTask.setOrigin(emptyVehicle.getCurrentLocation()); + emptyVehicleTask.setDestination(""); + emptyVehicleTask.setTaskPriority(1); + emptyVehicleTask.setTaskGroup(generateId("")); + emptyVehicleTask.setVehicleId(emptyVehicle.getVehicleId()); + emptyVehicleTask.setWeight(BigDecimal.ZERO); + emptyVehicleTask.setVehicleSize(1); + emptyVehicleTask.setCreateTime(LocalDateTime.now()); + emptyVehicleTask.setUserName(callEmptyVehicleRequest.getUserName()); + emptyVehicleTask.setIsPicking(0); + vehicleOutTasks.add(emptyVehicleTask); + // 出库料箱表 + outVehicleIds.add(emptyVehicle.getVehicleId()); + needNum--; } + // 保存任务 taskService.saveBatch(vehicleOutTasks); + // 更新料箱表 + vehicleService.update(new LambdaUpdateWrapper() + .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) + .in(Vehicle::getVehicleId, outVehicleIds) + .ne(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())); if (needNum <= 0) { response.setCode(ResponseCode.OK.getCode()); response.setMessage("呼叫空箱成功,请等待箱子出库。"); } else if (needNum < callEmptyVehicleRequest.getNeedNum()) { response.setCode(ResponseCode.OK.getCode()); - response.setMessage("已呼叫空箱,但库中空箱数量不足。需求" + callEmptyVehicleRequest.getNeedNum() + "个,实际呼叫" + (callEmptyVehicleRequest.getNeedNum() - needNum) + "个。"); + response.setMessage("已呼叫空箱,但库中空箱数量不足。需求" + callEmptyVehicleRequest.getNeedNum() + "个,实际呼叫" + vehicleOutTasks.size() + "个。"); } else { response.setCode(ResponseCode.ERROR.getCode()); response.setMessage("库中没有空箱了。"); @@ -2273,7 +2289,7 @@ public class TaskController { } else { logger.info("没有可亮灯的数据。"); response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("没有可亮灯的数据。"); + response.setMessage("没有可亮灯的数据,请按按钮。"); } return convertJsonString(response); } catch (Exception e) { @@ -2513,6 +2529,14 @@ public class TaskController { response.setMessage("请求缺少必须参数,箱号、料号、数量不可缺少。"); return convertJsonString(response); } + // 验证载具号是否重复入库 + if (vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, pickNumQuery.getVehicleId()) + .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) { + logger.error("当前箱子{}已在库中,无法回库。", pickNumQuery.getVehicleId()); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("当前箱子" + pickNumQuery.getVehicleId() + "已在库中,无法回库。"); + return convertJsonString(response); + } // 更新库存 Stock existStock = stockService.getOne(new LambdaQueryWrapper() .apply("goods_related ->> '$.goodsId' = {0}" + MYSQL_JSON_CI, pickNumQuery.getGoodsId()) @@ -2522,10 +2546,23 @@ public class TaskController { if (existStock != null && existStock.getGoodsRelated() != null) { Stock originStock = BeanUtil.copyProperties(existStock, Stock.class); StockDetailInfo goodsDetail = existStock.getGoodsRelated(); - goodsDetail.setRemainNum(goodsDetail.getRemainNum().subtract(pickNumQuery.getRealPickNum())); + // 设置剩余库存 + if (pickNumQuery.getRemainNum() != null) { + goodsDetail.setRemainNum(pickNumQuery.getRemainNum()); + } else { + BigDecimal calRemainNum = goodsDetail.getRemainNum().subtract(pickNumQuery.getRealPickNum()); + if (calRemainNum.compareTo(BigDecimal.ZERO) <= 0) { + logger.error("系统计算领料后库存为0,请界面输入剩余数量后再确认回库。"); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("系统计算领料后库存为0,请界面输入剩余数量后再确认回库。"); + return convertJsonString(response); + } else { + goodsDetail.setRemainNum(calRemainNum); + } + } existStock.setGoodsRelated(goodsDetail); stockService.updateById(existStock); - stockUpdateRecordService.addStockUpdateRecord(originStock, existStock, "直接物料非计划领料确认回库", pickNumQuery.getUserName()); + stockUpdateRecordService.addStockUpdateRecord(originStock, existStock, "直接物料非计划领料确认回库更新", pickNumQuery.getUserName()); } // 判断这个箱子是否还有拣选任务 boolean hasPickTasks = pickTaskService.exists(new LambdaQueryWrapper() @@ -2537,14 +2574,6 @@ public class TaskController { .eq(Task::getTaskType, TaskType.IN.getCode()) .likeRight(Task::getTaskId, "HK_")); if (!hasBackTask) { - // 验证载具号是否重复入库 - if (vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, pickNumQuery.getVehicleId()) - .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode())))) { - logger.error("当前箱子{}已在库中,无法回库。", pickNumQuery.getVehicleId()); - response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("当前箱子" + pickNumQuery.getVehicleId() + "已在库中,无法回库。"); - return convertJsonString(response); - } // 判断当前载具是否有入库任务 boolean hasInTask = taskService.exists(new LambdaQueryWrapper() .eq(Task::getVehicleId, pickNumQuery.getVehicleId()) @@ -2552,64 +2581,19 @@ public class TaskController { .eq(Task::getTaskStatus, WmsTaskStatus.TEMP.getCode()) .likeRight(Task::getTaskId, "RK_")); if (!hasInTask) { - // 寻找库位 - String nextLocationId = ""; - for (int i = 0; i < locationService.count(new LambdaQueryWrapper().eq(Location::getLocationStatus, LocationStatus.EMPTY.getCode())); i++) { - Map resultMap = locationService.getOneLocation("", ""); - if (resultMap.isEmpty() || !resultMap.containsKey("nextLocationId")) { - logger.error("暂无可用库位"); - response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("暂无可用库位!"); - return convertJsonString(response); - } else { - Location nextLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, resultMap.get("nextLocationId")).last("limit 1")); - LambdaUpdateWrapper updateLocationWrapper = new LambdaUpdateWrapper() - .set(Location::getLocationStatus, LocationStatus.OCCUPY.getCode()) - .set(Location::getVehicleId, pickNumQuery.getVehicleId()) - .eq(Location::getLocationId, nextLocation.getLocationId()) - .eq(Location::getLocationStatus, LocationStatus.EMPTY.getCode()); - if (locationService.update(updateLocationWrapper)) { - nextLocationId = resultMap.get("nextLocationId"); - break; - } - } - } - if (Objects.equals(nextLocationId, "")) { - logger.error("暂无可用库位"); - response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("暂无可用库位!"); - return convertJsonString(response); - } // 生成回库任务 Task backTask = new Task(); backTask.setTaskId(generateId("HK_")); backTask.setTaskGroup(generateId("")); backTask.setTaskType(TaskType.IN.getCode()); - backTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + backTask.setTaskStatus(WmsTaskStatus.TEMP.getCode()); backTask.setVehicleId(pickNumQuery.getVehicleId()); - backTask.setDestination(nextLocationId); backTask.setVehicleSize(1); backTask.setWeight(BigDecimal.ZERO); backTask.setTaskPriority(1); backTask.setUserName(pickNumQuery.getUserName()); backTask.setCreateTime(LocalDateTime.now()); - if (taskService.save(backTask)) { - // 设置库存状态为回库中 - stockService.update(new LambdaUpdateWrapper() - .set(Stock::getStockStatus, StockStatus.BACK.getCode()) - .eq(Stock::getVehicleId, pickNumQuery.getVehicleId())); - } else { - // 回退库位锁定 - locationService.update(new LambdaUpdateWrapper() - .set(Location::getLocationStatus, LocationStatus.EMPTY.getCode()) - .set(Location::getVehicleId, "") - .eq(Location::getLocationId, nextLocationId) - .eq(Location::getLocationStatus, LocationStatus.OCCUPY.getCode())); - logger.error("生成回库任务失败,箱号:{}", pickNumQuery.getVehicleId()); - response.setCode(ResponseCode.ERROR.getCode()); - response.setMessage("生成回库任务失败。"); - return convertJsonString(response); - } + taskService.save(backTask); } } logger.info("确认回库成功。"); diff --git a/src/main/java/com/wms/entity/app/request/PickNumQuery.java b/src/main/java/com/wms/entity/app/request/PickNumQuery.java index 02113cb..93bf975 100644 --- a/src/main/java/com/wms/entity/app/request/PickNumQuery.java +++ b/src/main/java/com/wms/entity/app/request/PickNumQuery.java @@ -27,4 +27,9 @@ public class PickNumQuery extends PageQuery{ */ @JsonProperty("realPickNum") private BigDecimal realPickNum; + /** + * 剩余数量 + */ + @JsonProperty("remainNum") + private BigDecimal remainNum; } diff --git a/src/main/java/com/wms/service/business/IWmsJobService.java b/src/main/java/com/wms/service/business/IWmsJobService.java index 40e3851..6b5dfcc 100644 --- a/src/main/java/com/wms/service/business/IWmsJobService.java +++ b/src/main/java/com/wms/service/business/IWmsJobService.java @@ -10,6 +10,12 @@ public interface IWmsJobService { */ void sendCommonTasks() throws Exception; + /** + * 下发拣选出库任务 + * @throws Exception 异常 + */ + void sendPickOutTasks() throws Exception; + /** * 发送拣选任务 * @throws Exception 异常用于回滚事务 diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java index 48f1a00..8c01615 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java @@ -27,6 +27,7 @@ import java.time.LocalDateTime; import java.util.*; import static com.wms.config.InitLocalConfig.configMap; +import static com.wms.config.InitLocalConfig.instantLocationMap; import static com.wms.utils.StringUtils.convertJsonString; /** @@ -53,43 +54,16 @@ public class WmsJobServiceImplements implements IWmsJobService { .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()); List allTasks = taskService.list(waitForDistributeTaskQuery); if (!allTasks.isEmpty()) { - String max_vehicle_nums = configMap.get(ConfigMapKeyEnum.MAX_VEHICLE_NUMS.getConfigKey()); String max_wcs_accept_nums = configMap.get(ConfigMapKeyEnum.MAX_WCS_ACCEPT_NUMS.getConfigKey()); - if (StringUtils.isEmpty(max_vehicle_nums) || StringUtils.isEmpty(max_wcs_accept_nums)) { + if (StringUtils.isEmpty(max_wcs_accept_nums)) { logger.error("配置未生成"); return; } - int maxVehicleNums = Integer.parseInt(max_vehicle_nums); int maxWcsAcceptNums = Integer.parseInt(max_wcs_accept_nums); - List outsideVehicles = outsideVehiclesService.selectDistinctVehicles(); - if (outsideVehicles == null || outsideVehicles.isEmpty()) { - outsideVehicles = Collections.emptyList(); - } - int remainVehicleNums = maxVehicleNums - outsideVehicles.size(); - // 需要发送给wcs的任务列表 List request = new ArrayList<>(); // 已经下发的任务组列表 List taskGroupIds = new ArrayList<>(); - // 本次生成的环线任务 - List pickVehicleIds = new ArrayList<>(); - // 查找所有已经出库的站台拣选任务 - List standPickTasks = pickTaskService.list(); - // 生成一个Map,计算每个站台已经出库的拣选任务 - Map outPickTaskMap = new HashMap<>(); - // 轮询工作站台,判断是否需要下发任务 - List stands = standService.list(new LambdaQueryWrapper() - .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0) - .eq(Stand::getStandType, 2)); - for (Stand workStation : stands) { - outPickTaskMap.put(workStation.getStandId(), 0); - } - standPickTasks.forEach(pickTask -> { - if (!Objects.equals(pickTask.getPickStatus(), PickTaskStatusEnum.TEMP.getCode())) { - outPickTaskMap.put(pickTask.getStandId(), - outPickTaskMap.getOrDefault(pickTask.getStandId(), 0) + 1); - } - }); // 这里单独处理站台拣选出库以外的任务 for (Task task : allTasks) { if (taskGroupIds.size() >= maxWcsAcceptNums) { @@ -128,91 +102,6 @@ public class WmsJobServiceImplements implements IWmsJobService { // 已经发送过的任务组 taskGroupIds.add(task.getTaskGroup()); } - // 处理站台拣选出库任务 - while (taskGroupIds.size() < maxWcsAcceptNums && pickVehicleIds.size() < remainVehicleNums) { - // 先找出目前数量最少的站台 - String standId = outPickTaskMap.entrySet().stream() - .min(Comparator.comparingInt(Map.Entry::getValue)) - .map(Map.Entry::getKey) - .orElse(""); - List vehicleIds; - if (StringUtils.isNotEmpty(standId)) { - // 查找这个站台未下发的料箱 - vehicleIds = standPickTasks.stream() - .filter(pickTask -> pickTask.getStandId().equals(standId) && pickTask.getPickStatus().equals(PickTaskStatusEnum.TEMP.getCode()) && !pickVehicleIds.contains(pickTask.getVehicleId())) - .map(PickTask::getVehicleId) - .distinct() - .toList(); - if (vehicleIds.isEmpty()) { - outPickTaskMap.remove(standId); - continue; - } - } else { - vehicleIds = standPickTasks.stream() - .filter(pickTask -> pickTask.getPickStatus().equals(PickTaskStatusEnum.TEMP.getCode()) && !pickVehicleIds.contains(pickTask.getVehicleId())) - .map(PickTask::getVehicleId) - .distinct() - .toList(); - if (vehicleIds.isEmpty()) { - break; - } - } - // 生成箱子-站台数量的Map - Map vehicleStandsMap = new HashMap<>(); - standPickTasks.forEach(pickTask -> { - if (vehicleIds.contains(pickTask.getVehicleId())) { - vehicleStandsMap.put(pickTask.getVehicleId(), - vehicleStandsMap.getOrDefault(pickTask.getVehicleId(), 0) + 1); - } - }); - // 先找出目前数量最多的料箱 - String vehicleId = vehicleStandsMap.entrySet().stream() - .max(Comparator.comparingInt(Map.Entry::getValue)) - .map(Map.Entry::getKey) - .orElse(""); - if (StringUtils.isEmpty(vehicleId)) { - continue; - } - // 更新每个站台的拣选箱数量 - List standIds = standPickTasks.stream() - .filter(pickTask -> pickTask.getVehicleId().equals(vehicleId)) - .map(PickTask::getStandId) - .distinct() - .toList(); - if (!standIds.isEmpty()) { - standIds.forEach(tempStandId -> outPickTaskMap.put(tempStandId, outPickTaskMap.getOrDefault(tempStandId, 0) + 1)); - } - // 找到这个箱子的任务 - List outPickTasks = allTasks.stream().filter(task -> - task.getVehicleId().equals(vehicleId) && Objects.equals(task.getTaskType(), TaskType.OUT.getCode()) - && task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand())).toList(); - for (Task task : outPickTasks) { - if (taskGroupIds.contains(task.getTaskGroup())) { - // 该任务组已经下发 - continue; - } - if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 - // 查询一下前置的任务有没有存在,存在则不下发 - if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { - continue; - } - } - // 创建发送的任务 - WcsTaskRequest tempTask = new WcsTaskRequest(); - tempTask.setTaskId(task.getTaskGroup()); - tempTask.setTaskType(task.getTaskType()); - tempTask.setOrigin(task.getOrigin()); - tempTask.setDestination(task.getDestination()); - tempTask.setVehicleNo(task.getVehicleId()); - tempTask.setVehicleSize(task.getVehicleSize()); - tempTask.setWeight(task.getWeight()); - tempTask.setPriority(task.getTaskPriority()); - request.add(tempTask); - // 已经发送过的任务组 - taskGroupIds.add(task.getTaskGroup()); - } - pickVehicleIds.add(vehicleId); - } if (request.size() == 0) { // 没有新任务发送 return; @@ -236,12 +125,6 @@ public class WmsJobServiceImplements implements IWmsJobService { .set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode()) .in(Task::getTaskGroup, taskGroupIds) .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode())); - // 流转载具状态变更 - if (!pickVehicleIds.isEmpty()) { - outsideVehiclesService.update(new LambdaUpdateWrapper() - .set(OutsideVehicles::getOutStatus, 1) - .in(OutsideVehicles::getVehicleId, pickVehicleIds)); - } } else { // 判断returnData的数据 if (result.getReturnData() != null) { @@ -268,6 +151,220 @@ public class WmsJobServiceImplements implements IWmsJobService { } } + @Override + public void sendPickOutTasks() throws Exception { + try { + // 检索任务表---新建未下发的任务 + LambdaQueryWrapper waitForDistributeTaskQuery = new LambdaQueryWrapper() + .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()) + .eq(Task::getTaskType, TaskType.OUT.getCode()); + List allTasks = taskService.list(waitForDistributeTaskQuery); + if (!allTasks.isEmpty()) { + // 需要发送给wcs的任务列表 + List request = new ArrayList<>(); + // 已经下发的任务组列表 + List taskGroupIds = new ArrayList<>(); + // 本次生成的环线任务 + List pickVehicleIds = new ArrayList<>(); + // 查找所有站台拣选任务 + List standPickTasks = pickTaskService.list(); + // 生成一个Map,计算每个站台已经出库的拣选任务 + Map outPickTaskMap = new HashMap<>(); + // 轮询工作站台,判断是否需要下发任务 + List stands = standService.list(new LambdaQueryWrapper() + .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0) + .eq(Stand::getStandType, 2)); + for (Stand workStation : stands) { + outPickTaskMap.put(workStation.getStandId(), 0); + } + standPickTasks.forEach(pickTask -> { + if (!Objects.equals(pickTask.getPickStatus(), PickTaskStatusEnum.TEMP.getCode())) { + outPickTaskMap.put(pickTask.getStandId(), + outPickTaskMap.getOrDefault(pickTask.getStandId(), 0) + 1); + } + }); + // 轮询堆垛机状态 + List stackerList = standService.list(new LambdaQueryWrapper() + .eq(Stand::getIsLock, 0).eq(Stand::getStandStatus, 0) + .eq(Stand::getStandType, 3)); + List stackRunningTasks = taskService.list(new LambdaQueryWrapper() + .eq(Task::getTaskType, TaskType.OUT.getCode()) + .eq(Task::getTaskStatus, WmsTaskStatus.RUN.getCode())); + Map runningTaskNumToEquipmentMap = new HashMap<>(); + Map> newTaskToEquipmentMap = new HashMap<>(); + for (Stand stacker : stackerList) { + // 找这台堆垛机正在执行的拣选出库任务数量 + runningTaskNumToEquipmentMap.put(stacker.getEquipmentId(), 0); + // 查询每台堆垛机还没有下发的任务 + List stackNewTasks = allTasks.stream().filter(task -> + task.getIsPicking() == 1 && StringUtils.isNotEmpty(task.getPickStand()) + && Objects.equals(stacker.getEquipmentId(), instantLocationMap.get(task.getOrigin()).getEquipmentId()) + ).toList(); + newTaskToEquipmentMap.put(stacker.getEquipmentId(), stackNewTasks); + } + stackRunningTasks.forEach(task -> { + if (instantLocationMap.containsKey(task.getOrigin())) { + int key = instantLocationMap.get(task.getOrigin()).getEquipmentId(); + runningTaskNumToEquipmentMap.put(key, runningTaskNumToEquipmentMap.get(key) + 1); + } + }); + for (Stand stacker : stackerList) { + int availableTaskNum = 2 - runningTaskNumToEquipmentMap.get(stacker.getEquipmentId()); + while (availableTaskNum > 0) { + // 可以继续发任务 + List currentStackerTasks = newTaskToEquipmentMap.get(stacker.getEquipmentId()); + // 从这些任务里面找到最适合的任务下发 + if (!currentStackerTasks.isEmpty()) { + // 先找出目前数量最少的站台 + String standId = outPickTaskMap.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .map(Map.Entry::getKey) + .orElse(""); + List vehicleIds; + List currentStackerVehicleIds = currentStackerTasks.stream().map(Task::getVehicleId).distinct().toList(); + if (StringUtils.isNotEmpty(standId)) { + // 查找这个站台未下发的料箱 + vehicleIds = standPickTasks.stream() + .filter(pickTask -> pickTask.getStandId().equals(standId) && pickTask.getPickStatus().equals(PickTaskStatusEnum.TEMP.getCode()) + && !pickVehicleIds.contains(pickTask.getVehicleId()) && currentStackerVehicleIds.contains(pickTask.getVehicleId())) + .map(PickTask::getVehicleId) + .distinct() + .toList(); + if (vehicleIds.isEmpty()) { + outPickTaskMap.remove(standId); + continue; + } + } else { + vehicleIds = standPickTasks.stream() + .filter(pickTask -> pickTask.getPickStatus().equals(PickTaskStatusEnum.TEMP.getCode()) + && !pickVehicleIds.contains(pickTask.getVehicleId()) && currentStackerVehicleIds.contains(pickTask.getVehicleId())) + .map(PickTask::getVehicleId) + .distinct() + .toList(); + if (vehicleIds.isEmpty()) { + break; + } + } + // 生成箱子-站台数量的Map + Map vehicleStandsMap = new HashMap<>(); + standPickTasks.forEach(pickTask -> { + if (vehicleIds.contains(pickTask.getVehicleId())) { + vehicleStandsMap.put(pickTask.getVehicleId(), + vehicleStandsMap.getOrDefault(pickTask.getVehicleId(), 0) + 1); + } + }); + // 先找出适合的料箱 + String vehicleId = vehicleStandsMap.entrySet().stream() + .min(Comparator.comparingInt(Map.Entry::getValue)) + .map(Map.Entry::getKey) + .orElse(""); + if (StringUtils.isEmpty(vehicleId)) { + continue; + } + // 更新每个站台的拣选箱数量 + List standIds = standPickTasks.stream() + .filter(pickTask -> pickTask.getVehicleId().equals(vehicleId)) + .map(PickTask::getStandId) + .distinct() + .toList(); + if (!standIds.isEmpty()) { + standIds.forEach(tempStandId -> outPickTaskMap.put(tempStandId, outPickTaskMap.getOrDefault(tempStandId, 0) + 1)); + } + // 找到这个箱子的任务 + List outPickTasks = currentStackerTasks.stream().filter(task -> task.getVehicleId().equals(vehicleId)).toList(); + for (Task task : outPickTasks) { + if (taskGroupIds.contains(task.getTaskGroup())) { + // 该任务组已经下发 + currentStackerTasks.remove(task); + continue; + } + if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 + // 查询一下前置的任务有没有存在,存在则不下发 + if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { + continue; + } + } + // 创建发送的任务 + WcsTaskRequest tempTask = new WcsTaskRequest(); + tempTask.setTaskId(task.getTaskGroup()); + tempTask.setTaskType(task.getTaskType()); + tempTask.setOrigin(task.getOrigin()); + tempTask.setDestination(task.getDestination()); + tempTask.setVehicleNo(task.getVehicleId()); + tempTask.setVehicleSize(task.getVehicleSize()); + tempTask.setWeight(task.getWeight()); + tempTask.setPriority(task.getTaskPriority()); + request.add(tempTask); + // 已经发送过的任务组 + taskGroupIds.add(task.getTaskGroup()); + } + // 已经发送过的vehicleId + pickVehicleIds.add(vehicleId); + // 移除已经发送过的任务 + currentStackerTasks.removeIf(task -> task.getVehicleId().equals(vehicleId)); + newTaskToEquipmentMap.replace(stacker.getEquipmentId(), currentStackerTasks); + } else { + break; + } + // 可用数量-1 + availableTaskNum--; + } + } + if (request.size() == 0) { + // 没有新任务发送 + return; + } + // 发送任务 + String url = configMap.get(ConfigMapKeyEnum.URL_WCS_TASK.getConfigKey()); + if (url != null) { + logger.info("向WCS发送拣选出库任务,地址:{},请求详情:{}", url, convertJsonString(request)); + ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(request)), ResponseEntity.class); + try { + logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送任务", "SetStackerTask", JSON.toJSONString(request), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS")); + } catch (Exception e) { + logger.error("插入日志错误。"); + } + if (result == null) { + logger.error("发送拣选出库任务异常。"); + } else { + if (Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { + logger.info("发送WCS拣选出库任务成功。"); + taskService.update(new LambdaUpdateWrapper() + .set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode()) + .in(Task::getTaskGroup, taskGroupIds) + .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode())); + // 流转载具状态变更 + if (!pickVehicleIds.isEmpty()) { + outsideVehiclesService.update(new LambdaUpdateWrapper() + .set(OutsideVehicles::getOutStatus, 1) + .in(OutsideVehicles::getVehicleId, pickVehicleIds)); + } + } else { + // 判断returnData的数据 + if (result.getReturnData() != null) { + List errorTasks = JSON.parseArray(result.getReturnData().toString(), WcsTaskRequest.class); + if (!errorTasks.isEmpty()) { + List failedTaskIds = errorTasks.stream().map(WcsTaskRequest::getTaskId).distinct().toList(); + // 更新任务状态为异常 + taskService.update(new LambdaUpdateWrapper() + .set(Task::getTaskStatus, WmsTaskStatus.EXCEPTION.getCode()) + .in(Task::getTaskGroup, failedTaskIds) + .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode())); + } + } + logger.error("发送拣选出库任务错误:{}", convertJsonString(result)); + } + } + } else { + logger.error("WCS发送任务地址为空。"); + } + } + } catch (Exception exception) { + logger.error("向WCS发送拣选出库任务时发生异常:{}", convertJsonString(exception)); + throw new Exception("向WCS发送拣选出库任务时发生异常。"); + } + } + /** * 发送拣选任务 */ 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 ab38714..5d4e206 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java @@ -92,7 +92,7 @@ public class WorkServiceImplements implements IWorkService { workOrderList.add(tempWorkflow.getWorkOrder()); } // 添加盒子配置 - String boxNo = tempWorkflow.getWorkOrder() + "-" + tempWorkflow.getWorkCenter(); + String boxNo = tempWorkflow.getWorkOrder() + "@" + tempWorkflow.getWorkCenter(); if (!boxNoList.contains(boxNo)) { boxNoList.add(boxNo); } @@ -147,8 +147,8 @@ public class WorkServiceImplements implements IWorkService { if (!boxNoList.isEmpty()) { String tempBoxNo = boxNoList.get(0); ELocationConfig eLocationConfig = new ELocationConfig(); - eLocationConfig.setWorkOrder(tempBoxNo.split("-")[0]); - eLocationConfig.setWorkCenter(tempBoxNo.split("-")[1]); + eLocationConfig.setWorkOrder(tempBoxNo.split("@")[0]); + eLocationConfig.setWorkCenter(tempBoxNo.split("@")[1]); eLocationConfig.setWorkStation(workStation); eLocationConfig.setELocationId(eTagLocation.getELocationId()); eLocationConfig.setOrderBoxNo(tempBoxNo); @@ -327,7 +327,7 @@ public class WorkServiceImplements implements IWorkService { workSummaryList.add(summary); // 更新工单表 kateOrdersService.update(new LambdaUpdateWrapper() - .set(KateOrders::getOrderStatus, 2) + .set(KateOrders::getOrderStatus, 4) .set(KateOrders::getFinishTime, LocalDateTime.now()) .set(KateOrders::getPickedQuantity, workFlow.getPickedNum()) .set(KateOrders::getLackQuantity, workFlow.getNeedNum().subtract(workFlow.getPickedNum())) diff --git a/src/main/java/com/wms/utils/excel/listener/UploadDbsListener.java b/src/main/java/com/wms/utils/excel/listener/UploadDbsListener.java index 3561826..27f6341 100644 --- a/src/main/java/com/wms/utils/excel/listener/UploadDbsListener.java +++ b/src/main/java/com/wms/utils/excel/listener/UploadDbsListener.java @@ -3,10 +3,7 @@ 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.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wms.entity.table.KateDBS; -import com.wms.entity.table.KateDBSLast; -import com.wms.service.KateDBSLastService; import com.wms.service.KateDBSService; import com.wms.utils.StringUtils; import com.wms.utils.excel.vo.KateDbsExcelVo; @@ -14,8 +11,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.time.LocalDateTime; -import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static com.wms.utils.WmsUtils.generateId; @@ -28,17 +26,14 @@ public class UploadDbsListener implements ReadListener { * 每隔5条存储数据库,实际使用中可以100条,然后清理list ,方便内存回收 */ private static final int BATCH_COUNT = 100; - /** - * 保存数据总数 - */ - private int SAVE_COUNT = 0; private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); private final KateDBSService kateDBSService;// Dbs服务 - private final KateDBSLastService kateDBSLastService;// DbsLast服务 private final String uploadUser;// 用户 - public UploadDbsListener(KateDBSService kateDBSService, KateDBSLastService kateDBSLastService, String uploadUser) { + private final Map oldKateDBSMap;// 旧的DBS数据 + private final Map newKateDBSMap = new HashMap<>();// 新的DBS数据 + public UploadDbsListener(KateDBSService kateDBSService, Map oldKateDBSMap, String uploadUser) { this.kateDBSService = kateDBSService; - this.kateDBSLastService = kateDBSLastService; + this.oldKateDBSMap = oldKateDBSMap; this.uploadUser = uploadUser; } @@ -66,7 +61,6 @@ public class UploadDbsListener implements ReadListener { } // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { - logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); @@ -80,38 +74,34 @@ public class UploadDbsListener implements ReadListener { */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { + // 再做一次数据处理 saveData(); - logger.info("此次共保存{}条数据。", SAVE_COUNT); + // 在这里统一保存数据 + insertIntoDb(); + } /** * 存储数据 */ private void saveData() { - List kateDbsList = new ArrayList<>(); for (KateDbsExcelVo kateDbsExcelVo : cachedDataList) { - if (kateDBSService.exists(new LambdaQueryWrapper() - .eq(KateDBS::getWorkOrder, kateDbsExcelVo.getWorkOrder()) - .or().eq(KateDBS::getWorkSequence, kateDbsExcelVo.getWorkSequence()))) { - // 工单号或者序号重复,那么跳过这条DBS + if (newKateDBSMap.containsKey(kateDbsExcelVo.getWorkOrder())) { + // 新的数据工单号重复,那么跳过这条DBS continue; } - KateDBSLast kateDbsLast = kateDBSLastService.getOne(new LambdaQueryWrapper() - .eq(KateDBSLast::getWorkOrder, kateDbsExcelVo.getWorkOrder())); - if (kateDbsLast != null) { - // 之前存在过 - KateDBS oldKateDbs = new KateDBS(); - oldKateDbs.setDbsId(kateDbsLast.getDbsId()); + if (oldKateDBSMap.containsKey(kateDbsExcelVo.getWorkOrder())) { + // 之前有 + KateDBS oldKateDbs = oldKateDBSMap.get(kateDbsExcelVo.getWorkOrder()); oldKateDbs.setWorkSequence(kateDbsExcelVo.getWorkSequence()); oldKateDbs.setMachineNo(kateDbsExcelVo.getMachineNo()); - oldKateDbs.setWorkOrder(kateDbsExcelVo.getWorkOrder()); oldKateDbs.setPlanStartDate(kateDbsExcelVo.getPlanStartDate()); - oldKateDbs.setDbsStatus(kateDbsLast.getDbsStatus()); oldKateDbs.setLastUpdateTime(LocalDateTime.now()); oldKateDbs.setLastUpdateUser(uploadUser); - kateDbsList.add(oldKateDbs); + // 替换 + newKateDBSMap.put(kateDbsExcelVo.getWorkOrder(), oldKateDbs); } else { - // 之前没存在过 + // 之前没有 KateDBS newKateDbs = new KateDBS(); newKateDbs.setDbsId(generateId("DBS_")); newKateDbs.setWorkSequence(kateDbsExcelVo.getWorkSequence()); @@ -121,10 +111,19 @@ public class UploadDbsListener implements ReadListener { newKateDbs.setDbsStatus(0); newKateDbs.setLastUpdateTime(LocalDateTime.now()); newKateDbs.setLastUpdateUser(uploadUser); - kateDbsList.add(newKateDbs); + // 添加 + newKateDBSMap.put(kateDbsExcelVo.getWorkOrder(), newKateDbs); } } - kateDBSService.saveOrUpdateBatch(kateDbsList); - SAVE_COUNT += kateDbsList.size(); + } + + /** + * 保存数据库 + */ + private void insertIntoDb() { + logger.info("此次共导入{}条数据。", newKateDBSMap.size()); + // 保存数据 + kateDBSService.saveOrUpdateBatch(newKateDBSMap.values(), BATCH_COUNT); + logger.info("保存成功{}条数据。", newKateDBSMap.size()); } } diff --git a/src/main/java/com/wms/utils/excel/listener/UploadGoodsListener.java b/src/main/java/com/wms/utils/excel/listener/UploadGoodsListener.java index 6049243..3ce4123 100644 --- a/src/main/java/com/wms/utils/excel/listener/UploadGoodsListener.java +++ b/src/main/java/com/wms/utils/excel/listener/UploadGoodsListener.java @@ -72,6 +72,7 @@ public class UploadGoodsListener implements ReadListener { */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { + logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); saveData(); logger.info("此次共保存{}条数据。", SAVE_COUNT); } diff --git a/src/main/java/com/wms/utils/excel/listener/UploadKateOrdersListener.java b/src/main/java/com/wms/utils/excel/listener/UploadKateOrdersListener.java index e3a0ccc..9044733 100644 --- a/src/main/java/com/wms/utils/excel/listener/UploadKateOrdersListener.java +++ b/src/main/java/com/wms/utils/excel/listener/UploadKateOrdersListener.java @@ -25,27 +25,19 @@ public class UploadKateOrdersListener implements ReadListener /** * 每隔5条存储数据库,实际使用中可以1000条,然后清理list ,方便内存回收 */ - private static final int BATCH_COUNT = 5000; - /** - * 保存数据总数 - */ - private int SAVE_COUNT = 0; + private static final int BATCH_COUNT = 1000; private List cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); /** - * 优化导入速度的变量---开始 - */ - private int MAP_INDEX = 0; - private int LAST_SHOT_INDEX = 0; - private final Map> doneMap = new HashMap<>(); - private final List kateOrdersLastList;// 所有之前的工单列表; - /** - * 优化导入速度的变量---结束 + * 筛选工单字符串 */ + private final String slocFilterString = configMap.get(ConfigMapKeyEnum.SLOC_FILTER_STRING.getConfigKey()); private final KateOrdersService kateOrdersService;// Dbs服务 private final String uploadUser;// 用户 - public UploadKateOrdersListener(List kateOrdersLastList, KateOrdersService kateOrdersService, String uploadUser) { - this.kateOrdersLastList = kateOrdersLastList; + private final Map oldKateOrdersMap;// 旧的工单数据 + private final Map newKateOrdersMap = new HashMap<>();// 新的工单数据 + public UploadKateOrdersListener(KateOrdersService kateOrdersService, Map oldKateOrdersMap, String uploadUser) { this.kateOrdersService = kateOrdersService; + this.oldKateOrdersMap = oldKateOrdersMap; this.uploadUser = uploadUser; } @@ -64,7 +56,6 @@ public class UploadKateOrdersListener implements ReadListener */ @Override public void invoke(KateOrdersExcelVo kateOrdersExcelVo, AnalysisContext analysisContext) { - String slocFilterString = configMap.get(ConfigMapKeyEnum.SLOC_FILTER_STRING.getConfigKey()); if (StringUtils.isNotEmpty(slocFilterString) && Objects.equals(kateOrdersExcelVo.getSortString(), slocFilterString)) { // 符合筛选字符串 if (StringUtils.isNotEmpty(kateOrdersExcelVo.getWorkOrder()) @@ -78,7 +69,6 @@ public class UploadKateOrdersListener implements ReadListener } // 达到BATCH_COUNT了,需要去存储一次数据库,防止数据几万条数据在内存,容易OOM if (cachedDataList.size() >= BATCH_COUNT) { - logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); @@ -92,91 +82,28 @@ public class UploadKateOrdersListener implements ReadListener */ @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { + // 再做一次数据处理 saveData(); - logger.info("此次共保存{}条数据。", SAVE_COUNT); + // 在这里统一保存数据 + insertIntoDb(); } /** * 存储数据 */ private void saveData() { - List kateOrdersList = new ArrayList<>(); - Map tempDoneMap = new HashMap<>(); for (KateOrdersExcelVo kateOrdersExcelVo : cachedDataList) { - // 查看当前List中是否有该工单 - List currentOrdersList = kateOrdersList.stream().filter(kateOrders -> - Objects.equals(kateOrders.getWorkOrder(), kateOrdersExcelVo.getWorkOrder()) - && Objects.equals(kateOrders.getGoodsId(), kateOrdersExcelVo.getGoodsId()) - && Objects.equals(kateOrders.getSupplyArea(), kateOrdersExcelVo.getSupplyArea()) - ).toList(); - if (!currentOrdersList.isEmpty()) { - KateOrders currentOrder = currentOrdersList.get(0); + String key = kateOrdersExcelVo.getWorkOrder() + kateOrdersExcelVo.getGoodsId() + kateOrdersExcelVo.getSupplyArea(); + if (newKateOrdersMap.containsKey(key)) { + KateOrders currentOrder = newKateOrdersMap.get(key); // 设定数量 currentOrder.setRequirementQuantity(currentOrder.getRequirementQuantity().add(kateOrdersExcelVo.getRequirementQuantity())); currentOrder.setLackQuantity(currentOrder.getLackQuantity().add(kateOrdersExcelVo.getRequirementQuantity())); - // 先移除 - kateOrdersList.removeIf(kateOrders -> - Objects.equals(kateOrders.getWorkOrder(), kateOrdersExcelVo.getWorkOrder()) - && Objects.equals(kateOrders.getGoodsId(), kateOrdersExcelVo.getGoodsId()) - && Objects.equals(kateOrders.getSupplyArea(), kateOrdersExcelVo.getSupplyArea())); - // 再添加 - kateOrdersList.add(currentOrder); + newKateOrdersMap.replace(key, currentOrder); continue; } // 查询数据库是否存在重复数据 - KateOrders existsKateOrder = null; - String key = kateOrdersExcelVo.getWorkOrder() + kateOrdersExcelVo.getGoodsId() + kateOrdersExcelVo.getSupplyArea(); - if (LAST_SHOT_INDEX > 0) { - if (doneMap.get(LAST_SHOT_INDEX).containsKey(key)) { - existsKateOrder = doneMap.get(LAST_SHOT_INDEX).get(key); - System.out.println("命中"); - } - } else { - for (Integer keyIndex : doneMap.keySet()) { - if (doneMap.get(keyIndex).containsKey(key)) { - LAST_SHOT_INDEX = keyIndex; - existsKateOrder = doneMap.get(keyIndex).get(key); - System.out.println("命中"); - break; - } - } - } - if (existsKateOrder != null) { - // 数据重复 - existsKateOrder.setRequirementQuantity(existsKateOrder.getRequirementQuantity().add(kateOrdersExcelVo.getRequirementQuantity())); - existsKateOrder.setLackQuantity(existsKateOrder.getLackQuantity().add(kateOrdersExcelVo.getRequirementQuantity())); - kateOrdersList.add(existsKateOrder); - continue; - } - List kateOrdersLastList = this.kateOrdersLastList.stream().filter(kateOrdersLast -> - Objects.equals(kateOrdersExcelVo.getWorkOrder(), kateOrdersLast.getWorkOrder()) - && Objects.equals(kateOrdersExcelVo.getGoodsId(), kateOrdersLast.getGoodsId()) - && Objects.equals(kateOrdersExcelVo.getSupplyArea(), kateOrdersLast.getSupplyArea()) - ).toList(); - if (!kateOrdersLastList.isEmpty()) { - // 之前存在过 - KateOrdersLast kateOrdersLast = kateOrdersLastList.get(0); - KateOrders oldKateOrders = new KateOrders(); - oldKateOrders.setOrderId(kateOrdersLast.getOrderId()); - oldKateOrders.setWorkOrder(kateOrdersExcelVo.getWorkOrder()); - oldKateOrders.setGoodsId(kateOrdersExcelVo.getGoodsId()); - oldKateOrders.setItem(kateOrdersExcelVo.getItem()); - oldKateOrders.setDescription(kateOrdersExcelVo.getDescription()); - oldKateOrders.setSLoc(kateOrdersExcelVo.getSLoc()); - oldKateOrders.setType(kateOrdersExcelVo.getType()); - oldKateOrders.setOriginStatus(kateOrdersExcelVo.getOriginStatus()); - oldKateOrders.setSupplyArea(kateOrdersExcelVo.getSupplyArea()); - oldKateOrders.setSortString(kateOrdersExcelVo.getSortString()); - oldKateOrders.setRequirementQuantity(kateOrdersExcelVo.getRequirementQuantity()); - oldKateOrders.setGoodsUnit(kateOrdersExcelVo.getGoodsUnit()); - oldKateOrders.setOrderStatus(kateOrdersLast.getOrderStatus()); - oldKateOrders.setLackQuantity(kateOrdersLast.getLackQuantity()); - oldKateOrders.setPickedQuantity(kateOrdersLast.getPickedQuantity()); - oldKateOrders.setFinishTime(kateOrdersLast.getFinishTime()); - oldKateOrders.setUserName(uploadUser); - kateOrdersList.add(oldKateOrders); - tempDoneMap.put(kateOrdersExcelVo.getWorkOrder() + kateOrdersExcelVo.getGoodsId() + kateOrdersExcelVo.getSupplyArea(), oldKateOrders); - } else { + if (!oldKateOrdersMap.containsKey(key)) { // 之前没存在过 KateOrders newKateOrders = new KateOrders(); newKateOrders.setOrderId(generateId("ORDER_")); @@ -195,12 +122,18 @@ public class UploadKateOrdersListener implements ReadListener newKateOrders.setLackQuantity(kateOrdersExcelVo.getRequirementQuantity()); newKateOrders.setPickedQuantity(BigDecimal.ZERO); newKateOrders.setUserName(uploadUser); - kateOrdersList.add(newKateOrders); - tempDoneMap.put(kateOrdersExcelVo.getWorkOrder() + kateOrdersExcelVo.getGoodsId() + kateOrdersExcelVo.getSupplyArea(), newKateOrders); + newKateOrdersMap.put(key, newKateOrders); } } - kateOrdersService.saveOrUpdateBatch(kateOrdersList); - SAVE_COUNT += kateOrdersList.size(); - doneMap.put(MAP_INDEX++, tempDoneMap); + } + + /** + * 保存数据库 + */ + private void insertIntoDb() { + logger.info("此次共导入{}条数据。", newKateOrdersMap.size()); + // 保存数据 + kateOrdersService.saveOrUpdateBatch(newKateOrdersMap.values(), BATCH_COUNT); + logger.info("保存成功{}条数据。", newKateOrdersMap.size()); } } diff --git a/src/main/java/com/wms/utils/excel/listener/UploadStationConfigListener.java b/src/main/java/com/wms/utils/excel/listener/UploadStationConfigListener.java index ac09036..b9adb56 100644 --- a/src/main/java/com/wms/utils/excel/listener/UploadStationConfigListener.java +++ b/src/main/java/com/wms/utils/excel/listener/UploadStationConfigListener.java @@ -14,7 +14,9 @@ import org.slf4j.LoggerFactory; import java.time.LocalDateTime; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import static com.wms.utils.WmsUtils.generateId; @@ -27,15 +29,14 @@ public class UploadStationConfigListener implements ReadListener cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); private final WorkStationConfigService workStationConfigService;// 工站配置服务 private final String uploadUser;// 用户 - public UploadStationConfigListener(WorkStationConfigService workStationConfigService, String uploadUser) { + private final Map oldWorkStationConfigMap;// 旧配置 + private final Map newWorkStationConfigMap = new HashMap<>();// 新配置 + public UploadStationConfigListener(WorkStationConfigService workStationConfigService, Map oldWorkStationConfigMap, String uploadUser) { this.workStationConfigService = workStationConfigService; + this.oldWorkStationConfigMap = oldWorkStationConfigMap; this.uploadUser = uploadUser; } @@ -59,9 +60,8 @@ public class UploadStationConfigListener implements ReadListener= BATCH_COUNT) { - logger.info("已经导入{}条数据,开始存储数据库!", cachedDataList.size()); saveData(); // 存储完成清理 list cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_COUNT); @@ -75,8 +75,10 @@ public class UploadStationConfigListener implements ReadListener stationConfigList = new ArrayList<>(); for (StationConfigExcelVo stationConfigExcelVo : cachedDataList) { - WorkStationConfig oldConfig = workStationConfigService.getOne(new LambdaQueryWrapper() - .eq(WorkStationConfig::getSmallBox, stationConfigExcelVo.getSmallBox()) - .last("limit 1")); - if (oldConfig != null) { + String key = stationConfigExcelVo.getSmallBox(); + if (oldWorkStationConfigMap.containsKey(key)) { + WorkStationConfig oldConfig = oldWorkStationConfigMap.get(key); oldConfig.setOrderQuantity(stationConfigExcelVo.getOrderQuantity()); oldConfig.setWorkStation(stationConfigExcelVo.getWorkStation()); oldConfig.setVehicle(stationConfigExcelVo.getVehicle()); @@ -100,17 +100,24 @@ public class UploadStationConfigListener implements ReadListener { */ private void saveData() { List stockList = new ArrayList<>(); + // TODO 下个项目优化 for (StockExcelVo stockExcelVo : cachedDataList) { Stock oldStock = stockService.getOne(new LambdaQueryWrapper() .eq(Stock::getVehicleId, stockExcelVo.getVehicleId())