From e27702f8cefe5398109fa9139c1d83127440c9de Mon Sep 17 00:00:00 2001 From: liangzhou <594755172@qq.com> Date: Fri, 19 Jul 2024 16:50:18 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 + .../java/com/wms/config/PageHelperConfig.java | 3 + .../wms/constants/enums/ConfigMapKeyEnum.java | 3 +- .../constants/enums/PickTaskStatusEnum.java | 25 + .../com/wms/controller/ExcelController.java | 57 +- .../java/com/wms/controller/JobComponent.java | 327 ++-------- .../com/wms/controller/TaskController.java | 606 +++--------------- .../com/wms/entity/app/request/TaskQuery.java | 44 ++ .../java/com/wms/entity/app/vo/TaskVO.java | 82 +++ .../java/com/wms/entity/table/PickTask.java | 2 +- .../service/business/IValidateService.java | 36 ++ .../wms/service/business/IWmsJobService.java | 24 + .../wms/service/business/IWmsTaskService.java | 37 ++ .../ValidateServiceImplements.java | 198 +++++- .../WmsJobServiceImplements.java | 253 ++++++++ .../WmsTaskServiceImplements.java | 298 +++++++++ .../WorkServiceImplements.java | 18 +- .../wms/webSocket/client/WebSocketClient.java | 19 + .../wms/webSocket/config/WebSocketConfig.java | 16 + .../webSocket/service/WebSocketService.java | 12 + 20 files changed, 1252 insertions(+), 815 deletions(-) create mode 100644 src/main/java/com/wms/constants/enums/PickTaskStatusEnum.java create mode 100644 src/main/java/com/wms/entity/app/request/TaskQuery.java create mode 100644 src/main/java/com/wms/entity/app/vo/TaskVO.java create mode 100644 src/main/java/com/wms/service/business/IWmsJobService.java create mode 100644 src/main/java/com/wms/service/business/IWmsTaskService.java create mode 100644 src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java create mode 100644 src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java create mode 100644 src/main/java/com/wms/webSocket/client/WebSocketClient.java create mode 100644 src/main/java/com/wms/webSocket/config/WebSocketConfig.java create mode 100644 src/main/java/com/wms/webSocket/service/WebSocketService.java diff --git a/pom.xml b/pom.xml index 6974927..128400b 100644 --- a/pom.xml +++ b/pom.xml @@ -157,6 +157,7 @@ spring-boot-starter-aop 3.2.1 + javax.mail mail @@ -167,6 +168,12 @@ ews-java-api 2.0 + + + org.springframework.boot + spring-boot-starter-websocket + + diff --git a/src/main/java/com/wms/config/PageHelperConfig.java b/src/main/java/com/wms/config/PageHelperConfig.java index 2bed06f..b58988b 100644 --- a/src/main/java/com/wms/config/PageHelperConfig.java +++ b/src/main/java/com/wms/config/PageHelperConfig.java @@ -7,6 +7,9 @@ import org.springframework.context.annotation.Configuration; import java.util.Properties; +/** + * 分页配置 + */ @SpringBootConfiguration public class PageHelperConfig { @Bean diff --git a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java index 11f85d0..c1c7bde 100644 --- a/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java +++ b/src/main/java/com/wms/constants/enums/ConfigMapKeyEnum.java @@ -3,7 +3,8 @@ package com.wms.constants.enums; public enum ConfigMapKeyEnum { MAX_WEIGHT("MAX_WEIGHT"), URL_WCS_TASK("URL_WCS_TASK"), - URL_NEW_DESTINATION("URL_NEW_DESTINATION"); + URL_NEW_DESTINATION("URL_NEW_DESTINATION"), + URL_WCS_PICK_TASK("URL_WCS_PICK_TASK"); private final String configKey; ConfigMapKeyEnum(String configKey) { this.configKey = configKey; diff --git a/src/main/java/com/wms/constants/enums/PickTaskStatusEnum.java b/src/main/java/com/wms/constants/enums/PickTaskStatusEnum.java new file mode 100644 index 0000000..a55490f --- /dev/null +++ b/src/main/java/com/wms/constants/enums/PickTaskStatusEnum.java @@ -0,0 +1,25 @@ +package com.wms.constants.enums; + +public enum PickTaskStatusEnum { + TEMP(-1, "暂存"), + NEW(0, "初始化"), + SEND(1, "已发送"), + FINISH(2, "已完成"); + + private final Integer code; + + private final String value; + + PickTaskStatusEnum(Integer code, String value) { + this.code = code; + this.value = value; + } + + public Integer getCode() { + return code; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/com/wms/controller/ExcelController.java b/src/main/java/com/wms/controller/ExcelController.java index 6eb4bde..37d4977 100644 --- a/src/main/java/com/wms/controller/ExcelController.java +++ b/src/main/java/com/wms/controller/ExcelController.java @@ -1,13 +1,22 @@ package com.wms.controller; +import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wms.constants.enums.*; import com.wms.entity.app.ResponseEntity; +import com.wms.entity.app.dto.LocationDto; import com.wms.entity.app.dto.StockDto; import com.wms.entity.app.dto.TaskRecordDto; +import com.wms.entity.app.dto.VehicleDto; +import com.wms.entity.app.request.LocationQuery; import com.wms.entity.app.request.StockQuery; import com.wms.entity.app.request.TaskRecordQuery; +import com.wms.entity.app.request.VehicleQuery; +import com.wms.entity.table.Location; +import com.wms.entity.table.Vehicle; import com.wms.service.*; +import com.wms.utils.StringUtils; import com.wms.utils.excel.ExcelUtils; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; @@ -23,6 +32,7 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import java.util.Collections; import java.util.List; import static com.wms.utils.HttpUtils.getIpAddr; @@ -36,10 +46,12 @@ import static com.wms.utils.StringUtils.convertJsonString; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) @RequestMapping(value = "/wms/excel") public class ExcelController { - private final Logger logger = LoggerFactory.getLogger(this.getClass()); + private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志 private final StockService stockService;// 库存服务 private final HttpServletRequest servletRequest;// 请求服务 private final TaskRecordService taskRecordService;// 任务记录服务 + private final VehicleService vehicleService;// 载具服务 + private final LocationService locationService;// 库位服务 /** * 导入库存信息 @@ -54,6 +66,7 @@ public class ExcelController { logger.info("导入库存,请求ip:{}", getIpAddr(servletRequest)); ResponseEntity response = new ResponseEntity(); try { + List stocksDto = ExcelUtils.readMultipartFile(file, StockDto.class); response.setCode(ResponseCode.OK.getCode()); response.setMessage("导入库存成功"); response.setReturnData(file); @@ -118,4 +131,46 @@ public class ExcelController { List inventoryRecord = taskRecordService.selectInventoryTaskRecord(query.toTaskRecordPO()); ExcelUtils.export(response, "盘点记录报表", inventoryRecord, TaskRecordDto.class); } + + /** + * 导出载具记录 + * + * @param response 请求 + */ + @GetMapping("/downloadVehicleExcel") + @ResponseBody + public void downloadVehicleExcel(@RequestParam("vehicleQuery") VehicleQuery vehicleQuery, HttpServletResponse response) { + logger.info("导出载具记录,查询参数:{},请求ip:{}", convertJsonString(vehicleQuery), getIpAddr(servletRequest)); + List vehicles = vehicleService.list(new LambdaQueryWrapper() + .like(StringUtils.isNotEmpty(vehicleQuery.getVehicleId()), Vehicle::getVehicleId, vehicleQuery.getVehicleId()) + .like(StringUtils.isNotEmpty(vehicleQuery.getCurrentLocation()), Vehicle::getCurrentLocation, vehicleQuery.getCurrentLocation()) + .eq(vehicleQuery.getIsEmpty() != null, Vehicle::getIsEmpty, vehicleQuery.getIsEmpty()) + .eq(vehicleQuery.getVehicleStatus() != null, Vehicle::getVehicleStatus, vehicleQuery.getVehicleStatus())); + if (vehicles == null || vehicles.isEmpty()) { + ExcelUtils.export(response, "载具报表", Collections.emptyList(), VehicleDto.class); + } else { + ExcelUtils.export(response, "载具报表", BeanUtil.copyToList(vehicles, VehicleDto.class), VehicleDto.class); + } + } + + /** + * 导出库位详情 + * + * @param response 请求 + */ + @GetMapping("/downloadLocationsExcel") + @ResponseBody + public void downloadLocationsExcel(@RequestParam("locationQuery") LocationQuery locationQuery, HttpServletResponse response) { + logger.info("导出库位详情,查询参数:{},请求ip:{}", convertJsonString(locationQuery), getIpAddr(servletRequest)); + List locations = locationService.list(new LambdaQueryWrapper() + .like(StringUtils.isNotEmpty(locationQuery.getLocationId()), Location::getLocationId, locationQuery.getLocationId()) + .eq(locationQuery.getAreaId() != null, Location::getAreaId, locationQuery.getAreaId()) + .eq(locationQuery.getIsLock() != null, Location::getIsLock, locationQuery.getIsLock()) + .eq(locationQuery.getLocationStatus() != null, Location::getLocationStatus, locationQuery.getLocationStatus())); + if (locations == null || locations.isEmpty()) { + ExcelUtils.export(response, "库位报表", Collections.emptyList(), LocationDto.class); + } else { + ExcelUtils.export(response, "库位报表", BeanUtil.copyToList(locations, LocationDto.class), LocationDto.class); + } + } } \ No newline at end of file diff --git a/src/main/java/com/wms/controller/JobComponent.java b/src/main/java/com/wms/controller/JobComponent.java index 10b6824..9bdcb8c 100644 --- a/src/main/java/com/wms/controller/JobComponent.java +++ b/src/main/java/com/wms/controller/JobComponent.java @@ -1,20 +1,10 @@ package com.wms.controller; -import cn.hutool.core.bean.BeanUtil; -import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.wms.constants.enums.*; -import com.wms.entity.app.ResponseEntity; -import com.wms.entity.app.dto.TaskDto; -import com.wms.entity.app.wcs.WcsTaskRequest; import com.wms.entity.table.Stand; -import com.wms.entity.table.Task; -import com.wms.entity.table.WmsLog; import com.wms.service.*; +import com.wms.service.business.IWmsJobService; import com.wms.service.business.IWorkService; -import com.wms.utils.HttpUtils; -import com.wms.utils.StringUtils; -import com.wms.utils.WmsUtils; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,11 +18,8 @@ import org.springframework.transaction.interceptor.TransactionAspectSupport; import static com.wms.utils.StringUtils.convertJsonString; -import java.time.LocalDateTime; import java.util.*; -import static com.wms.config.InitLocalConfig.configMap; - /** * 定期任务类 */ @@ -41,21 +28,9 @@ import static com.wms.config.InitLocalConfig.configMap; public class JobComponent { private final Logger logger = LoggerFactory.getLogger(this.getClass()); /** - * 任务服务 + * WMS定时任务服务 */ - private final TaskService taskService; - /** - * 库存服务 - */ - private final StockService stockService; - /** - * 任务记录服务 - */ - private final TaskRecordService taskRecordService; - /** - * 日志服务 - */ - private final LogService logService; + private final IWmsJobService wmsJobService; /** * 站台服务 */ @@ -70,60 +45,61 @@ public class JobComponent { * 向Wcs下发任务 * 每2秒执行一次 */ -// @Scheduled(fixedDelay = 2000) + @Scheduled(fixedDelay = 2000) + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void executeTasks() { - // 发送正常任务 - sendCommonTasks(); - // 发送拣选任务 - sendPickTasks(); - // 针对重复入库的任务,发送新的目的地 - solveDuplicateTask(); + try { + // 发送正常任务 + wmsJobService.sendCommonTasks(); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + } + try { + // 发送拣选任务 + wmsJobService.sendPickTasks(); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + } + try { + // 针对重复入库的任务,发送新的目的地 + wmsJobService.solveDuplicateTask(); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + } } /** * 检测工作 */ -// @Scheduled(fixedDelay = 2000) + @Scheduled(fixedDelay = 2000) @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) public void detectWork() { - try { - // 轮询工作站台,判断是否需要下发任务 - List stands = standService.list(new LambdaQueryWrapper() - .eq(Stand::getStandType, 2)); - for (Stand workStation : stands) { + // 轮询工作站台,判断是否需要下发任务 + List stands = standService.list(new LambdaQueryWrapper() + .eq(Stand::getStandType, 2)); + for (Stand workStation : stands) { + try { // 创建工作 workService.createWork(workStation.getStandId()); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + logger.error("创建工作时发生错误:{}", convertJsonString(e)); + } + try { // 执行工作 workService.doWork(workStation.getStandId()); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + logger.error("执行工作时发生错误:{}", convertJsonString(e)); } - } catch (Exception e) { - // 回滚事务 - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - logger.error("检测工作时发生错误:{}", convertJsonString(e)); } } -// /** -// * 每天查询一次是否有过期的库存 -// * 每天晚上8点执行一次 -// */ -//// @Scheduled(cron = "0 0 20 * * ?") -// public void detectOutOfDateStock() { -// logger.info("执行定时任务:查询过期库存"); -// List outOfDateStocks = stockService.selStockOutOfDate(); -// if (outOfDateStocks.size() > 0) { -// logger.info("过期库存数量不为0,准备更新过期库存"); -// for (StockDto outOfDateStock : outOfDateStocks) { -// try { -// outOfDateStock.setGoodsStatus(GoodsStatus.OVERDUE.getCode()); -// stockService.modifyStock(outOfDateStock); -// logger.info("过期库存更新成功"); -// } catch (Exception e) { -// logger.error("过期库存更新异常:{}", e.getMessage()); -// } -// } -// } -// } // // /** // * 每天查询一次是否有入库后长期未使用的库存 @@ -161,223 +137,4 @@ public class JobComponent { // logger.info("删除过期日志数据失败"); // } // } - - /** - * 发送正常的任务 - */ - private void sendCommonTasks() { - try { - // 检索任务表---新建未下发的任务 - LambdaQueryWrapper waitForDistributeTaskQuery = new LambdaQueryWrapper() - .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()); - List allTasks = BeanUtil.copyToList(taskService.list(waitForDistributeTaskQuery), TaskDto.class); - // 需要发送给wcs的任务列表 - List request = new ArrayList<>(); - // 已经下发的任务组列表 - List taskGroupIds = new ArrayList<>(); - if (!allTasks.isEmpty()) { - for (TaskDto task : allTasks) { - if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 - // 查询一下前置的任务有没有存在,存在则不下发 - if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { - continue; - } - } - if (taskGroupIds.contains(task.getTaskGroup())) { - // 已经发送过的任务组,直接设置状态 - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - } - // 创建发送的任务 - WcsTaskRequest tempTask = new WcsTaskRequest(); - tempTask.setTaskId(task.getTaskGroup()); - if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) { - tempTask.setTaskType(TaskType.OUT.getCode()); - } else { - 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); - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - // 已经发送过的任务组 - taskGroupIds.add(task.getTaskGroup()); - } - 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 && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { - taskService.saveBatch(BeanUtil.copyToList(allTasks, Task.class)); - } else { - if (result != null) { - logger.error("存在错误:{}", result.getMessage()); - } else { - logger.error("请求无返回"); - } - } - } else { - logger.error("WCS发送任务地址为空"); - } - } - } catch (Exception exception) { - logger.error("向Wcs发送任务时发生异常:{}", convertJsonString(exception)); - } - } - - /** - * 发送拣选任务 - */ - private void sendPickTasks() { - try { - // 检索任务表---新建未下发的任务 - LambdaQueryWrapper waitForDistributeTaskQuery = new LambdaQueryWrapper() - .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()); - List allTasks = BeanUtil.copyToList(taskService.list(waitForDistributeTaskQuery), TaskDto.class); - // 需要发送给wcs的任务列表 - List request = new ArrayList<>(); - // 已经下发的任务组列表 - List taskGroupIds = new ArrayList<>(); - if (!allTasks.isEmpty()) { - for (TaskDto task : allTasks) { - if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 - // 查询一下前置的任务有没有存在,存在则不下发 - if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { - continue; - } - } - if (taskGroupIds.contains(task.getTaskGroup())) { - // 已经发送过的任务组,直接设置状态 - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - } - // 创建发送的任务 - WcsTaskRequest tempTask = new WcsTaskRequest(); - tempTask.setTaskId(task.getTaskGroup()); - if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) { - tempTask.setTaskType(TaskType.OUT.getCode()); - } else { - 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); - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - // 已经发送过的任务组 - taskGroupIds.add(task.getTaskGroup()); - } - 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 && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { - taskService.saveBatch(BeanUtil.copyToList(allTasks, Task.class)); - } else { - if (result != null) { - logger.error("存在错误:{}", result.getMessage()); - } else { - logger.error("请求无返回"); - } - } - } else { - logger.error("WCS发送任务地址为空"); - } - } - } catch (Exception exception) { - logger.error("向Wcs发送任务时发生异常:{}", convertJsonString(exception)); - } - } - - /** - * 处理重复入库的任务 - */ - private void solveDuplicateTask() { - try { - // 检索任务表---新建未下发的任务 - LambdaQueryWrapper duplicateTaskQueryWrapper = new LambdaQueryWrapper() - .eq(Task::getTaskType, TaskType.IN.getCode()) - .eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode()); - List duplicateTasks = BeanUtil.copyToList(taskService.list(duplicateTaskQueryWrapper), TaskDto.class); - // 需要发送给wcs的任务列表 - List request = new ArrayList<>(); - // 已经下发的任务组列表 - List taskGroupIds = new ArrayList<>(); - if (!duplicateTasks.isEmpty()) { - for (TaskDto task : duplicateTasks) { - if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 - // 查询一下前置的任务有没有存在,存在则不下发 - if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { - continue; - } - } - if (taskGroupIds.contains(task.getTaskGroup())) { - // 已经发送过的任务组,直接设置状态 - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - } - // 创建发送的任务 - WcsTaskRequest tempTask = new WcsTaskRequest(); - tempTask.setTaskId(task.getTaskGroup()); - tempTask.setDestination(task.getDestination()); - tempTask.setVehicleNo(task.getVehicleId()); - request.add(tempTask); - task.setTaskStatus(WmsTaskStatus.WAIT.getCode()); - // 已经发送过的任务组 - taskGroupIds.add(task.getTaskGroup()); - } - if (request.size() == 0) { - return; - } - // 发送任务 - String url = configMap.get(ConfigMapKeyEnum.URL_NEW_DESTINATION.getConfigKey()); - if (url != null) { - logger.info("向WCS发送新目的地,地址:{},请求详情:{}", url, convertJsonString(request)); - request.forEach(wcsTaskRequest -> { - ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(wcsTaskRequest)), ResponseEntity.class); - try { - logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送新目的地", "setStackerTaskNewDestination", JSON.toJSONString(wcsTaskRequest), JSON.toJSONString(result), url, LocalDateTime.now(), "WMS")); - } catch (Exception e) { - logger.error("插入日志错误"); - } - if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { - taskService.saveBatch(BeanUtil.copyToList(duplicateTasks, Task.class)); - } else { - if (result != null) { - logger.error("存在错误:{}", result.getMessage()); - } else { - logger.error("请求无返回"); - } - } - }); - } else { - logger.error("向WCS发送新目的地的地址为空"); - } - } - } catch (Exception exception) { - logger.error("向WCS发送新目的地时发生异常:{}", convertJsonString(exception)); - } - } } \ No newline at end of file diff --git a/src/main/java/com/wms/controller/TaskController.java b/src/main/java/com/wms/controller/TaskController.java index 6880e28..2b6df8c 100644 --- a/src/main/java/com/wms/controller/TaskController.java +++ b/src/main/java/com/wms/controller/TaskController.java @@ -4,22 +4,24 @@ import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson2.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.wms.annotation.MyLog; import com.wms.constants.enums.*; import com.wms.entity.app.*; +import com.wms.entity.app.dto.PageDto; import com.wms.entity.app.dto.extend.StockDetailInfo; -import com.wms.entity.app.dto.extend.TaskDetailInfo; -import com.wms.entity.app.request.GoodsInRequest; import com.wms.entity.app.request.TaskInRequest; import com.wms.entity.app.request.TaskOutRequest; +import com.wms.entity.app.request.TaskQuery; +import com.wms.entity.app.vo.TaskVO; import com.wms.entity.app.wcs.WcsTaskResultRequest; import com.wms.entity.app.wcs.WcsVehicleInRequest; import com.wms.entity.table.*; import com.wms.service.*; +import com.wms.service.business.IValidateService; +import com.wms.service.business.IWmsTaskService; import com.wms.utils.HttpUtils; import com.wms.utils.StringUtils; -import io.swagger.annotations.Api; -import io.swagger.annotations.ApiOperation; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import org.slf4j.Logger; @@ -32,11 +34,9 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.web.bind.annotation.*; -import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.*; -import static com.wms.config.InitLocalConfig.configMap; import static com.wms.utils.StringUtils.convertJsonString; import static com.wms.utils.WmsUtils.generateId; @@ -68,22 +68,26 @@ public class TaskController { * 任务记录服务 */ private final TaskRecordService taskRecordService; - /** - * 站台服务 - */ - private final StandService standService; - /** - * 物料服务 - */ - private final GoodsService goodsService; /** * 载具服务 */ private final VehicleService vehicleService; + /** + * 拣选任务服务 + */ + private final PickTaskService pickTaskService; /** * 请求头部信息 */ private final HttpServletRequest servletRequest; + /** + * WMS任务服务 + */ + private final IWmsTaskService wmsTaskService; + /** + * 验证服务 + */ + private final IValidateService validateService; /** * 接收入库任务请求 @@ -101,7 +105,7 @@ public class TaskController { ResponseEntity response = new ResponseEntity(); try { // 验证入库请求 - String validationInfo = validateTaskInRequest(taskInRequest); + String validationInfo = validateService.validateTaskInRequest(taskInRequest); if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) { logger.error("入库请求验证错误!{}", validationInfo); response.setCode(ResponseCode.ERROR.getCode()); @@ -111,9 +115,9 @@ public class TaskController { // 生成入库任务 String saveTaskResult; if (taskInRequest.getGoodsList() == null || taskInRequest.getGoodsList().isEmpty()) {// 空托入库 - saveTaskResult = genEmptyInTask(taskInRequest); + saveTaskResult = wmsTaskService.genEmptyInTask(taskInRequest); } else {// 带料入库 - saveTaskResult = genGoodsInTask(taskInRequest); + saveTaskResult = wmsTaskService.genGoodsInTask(taskInRequest); } if (!saveTaskResult.equals("")) { // 返回失败 @@ -138,149 +142,6 @@ public class TaskController { } } - /** - * 添加空入库任务 - * - * @param taskInRequest 入库请求 - * @return 添加结果 - */ - private String genEmptyInTask(TaskInRequest taskInRequest) { - String result = ""; - Task tempInTask = new Task(); - tempInTask.setTaskId(generateId("RK_")); - tempInTask.setTaskType(TaskType.IN.getCode()); - tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode()); - tempInTask.setTaskGroup(generateId("")); - tempInTask.setTaskPriority(1); - tempInTask.setVehicleId(taskInRequest.getVehicleId()); - tempInTask.setVehicleSize(1); - tempInTask.setWeight(taskInRequest.getTotalWeight()); - tempInTask.setCreateTime(LocalDateTime.now()); - tempInTask.setUserName(taskInRequest.getUserName()); - try { - if (!taskService.save(tempInTask)) { - return "添加空入库任务失败"; - } - } catch (Exception e) { - logger.error("添加空入库任务异常:{}", convertJsonString(e)); - return "添加空入库任务失败"; - } - return result; - } - - /** - * 添加入库任务 - * - * @param taskInRequest 入库请求 - * @return 添加结果 - */ - private String genGoodsInTask(TaskInRequest taskInRequest) { - String result = ""; - String taskGroupId = generateId(""); - List tempTasks = new ArrayList<>(); - for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) { - Task tempInTask = new Task(); - tempInTask.setTaskId(generateId("RK_")); - tempInTask.setTaskType(TaskType.IN.getCode()); - tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode()); - tempInTask.setTaskGroup(taskGroupId); - tempInTask.setTaskPriority(1); - tempInTask.setVehicleId(taskInRequest.getVehicleId()); - tempInTask.setVehicleSize(1); - tempInTask.setWeight(taskInRequest.getTotalWeight()); - tempInTask.setCreateTime(LocalDateTime.now()); - tempInTask.setUserName(taskInRequest.getUserName()); - // 物料相关信息 - TaskDetailInfo goodsRelatedInfo = new TaskDetailInfo(); - // TODO 物料信息需要完善 - goodsRelatedInfo.setGoodsId(goodsInRequest.getGoodsId()); - goodsRelatedInfo.setGoodsName(""); - goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum()); - goodsRelatedInfo.setOriginNum(BigDecimal.ZERO); - tempInTask.setGoodsRelated(goodsRelatedInfo); - - tempTasks.add(tempInTask); - } - - try { - if (!taskService.saveBatch(tempTasks)) { - return "添加入库任务失败"; - } - } catch (Exception e) { - logger.error("添加入库任务异常:{}", convertJsonString(e)); - return "添加入库任务失败"; - } - return result; - } - - /** - * 验证入库请求 - * - * @param taskInRequest 入库请求 - * @return 验证结果---空为验证通过,否则输出错误信息 - */ - private String validateTaskInRequest(TaskInRequest taskInRequest) { - // 验证任务请求 - if (taskInRequest == null) { - return TaskInValidationEnum.NO_REQUEST_BODY.getErrorMessage(); - } - // 验证载具号 - if (StringUtils.isEmpty(taskInRequest.getVehicleId())) { - return TaskInValidationEnum.NO_VEHICLE_ID.getErrorMessage(); - } - // 验证载具号是否重复入库 - if (vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskInRequest.getVehicleId()) - .and(wrapper -> wrapper.eq(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) - .or().eq(Vehicle::getVehicleStatus, VehicleStatus.MOVE.getCode())))) { - return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage(); - } - // 验证当前载具是否已经有入库任务 - if (taskService.exists(new LambdaQueryWrapper().eq(Task::getVehicleId, taskInRequest.getVehicleId()) - .and(wrapper -> wrapper.eq(Task::getTaskType, TaskType.IN.getCode())))) { - return TaskInValidationEnum.DUPLICATE_VEHICLE_ID.getErrorMessage(); - } - // 验证重量 - if (taskInRequest.getTotalWeight() == null) { - return TaskInValidationEnum.NO_WEIGHT.getErrorMessage(); - } - BigDecimal max_weight = BigDecimal.valueOf(10000000); - try { - max_weight = new BigDecimal(configMap.get(ConfigMapKeyEnum.MAX_WEIGHT.getConfigKey())); - } catch (Exception e) { - logger.error("转换配置项---最大承重,发生错误"); - } - if (taskInRequest.getTotalWeight().compareTo(max_weight) > 0) { - // 超重 - return TaskInValidationEnum.OVER_WEIGHT.getErrorMessage(); - } - // 验证起点 - if (StringUtils.isEmpty(taskInRequest.getOriginPoint())) { - return TaskInValidationEnum.NO_IN_POINT.getErrorMessage(); - } else { - if (!standService.validateStand(taskInRequest.getOriginPoint(), TaskType.IN.getCode())) { - return TaskInValidationEnum.ERROR_IN_POINT.getErrorMessage(); - } - } - // 验证物料信息 - if (taskInRequest.getGoodsList() != null && !taskInRequest.getGoodsList().isEmpty()) { - for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) { - // 验证物料编号 - if (StringUtils.isEmpty(goodsInRequest.getGoodsId())) { - return TaskInValidationEnum.NO_GOODS_ID.getErrorMessage(); - } else { - if (!goodsService.validateGoodsId(goodsInRequest.getGoodsId())) { - return TaskInValidationEnum.ERROR_GOODS_ID.getErrorMessage(); - } - } - // 验证数量 - if (goodsInRequest.getGoodsNum() == null || goodsInRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) { - return TaskInValidationEnum.ERROR_GOODS_NUM.getErrorMessage(); - } - } - } - return TaskInValidationEnum.OK.getErrorMessage(); - } - /** * 接收出库任务请求 * @@ -297,7 +158,7 @@ public class TaskController { ResponseEntity response = new ResponseEntity(); try { // 验证出库请求 - String validationInfo = validateTaskOutRequest(taskOutRequest); + String validationInfo = validateService.validateTaskOutRequest(taskOutRequest); if (!Objects.equals(validationInfo, TaskInValidationEnum.OK.getErrorMessage())) { logger.error("出库请求验证错误!{}", validationInfo); response.setCode(ResponseCode.ERROR.getCode()); @@ -307,9 +168,9 @@ public class TaskController { // 没有物料,单纯载具或者库位出库 String genResult; if (StringUtils.isEmpty(taskOutRequest.getGoodsId())) { - genResult = genVehicleLocationOutTask(taskOutRequest); + genResult = wmsTaskService.genVehicleLocationOutTask(taskOutRequest); } else { - genResult = genGoodsOutTask(taskOutRequest); + genResult = wmsTaskService.genGoodsOutTask(taskOutRequest); } if (!genResult.equals("")) { logger.error("出库错误!{}", genResult); @@ -333,253 +194,6 @@ public class TaskController { } } - - /** - * 生成载具或库位出库任务 - * - * @param taskOutRequest 出库请求 - * @return 结果 - */ - private String genVehicleLocationOutTask(TaskOutRequest taskOutRequest) { - // 查询对应载具 - if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) { - Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); - // 创建空出库任务 - Task vehicleOutTask = new Task(); - vehicleOutTask.setTaskId(generateId("CK_")); - vehicleOutTask.setTaskType(TaskType.OUT.getCode()); - vehicleOutTask.setTaskGroup(generateId("")); - vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); - vehicleOutTask.setTaskPriority(1); - vehicleOutTask.setVehicleId(taskOutRequest.getVehicleId()); - vehicleOutTask.setUserName(taskOutRequest.getUserName()); - vehicleOutTask.setOrigin(currentVehicle.getCurrentLocation()); - vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); - vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); - vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); - vehicleOutTask.setCreateTime(LocalDateTime.now()); - taskService.save(vehicleOutTask); - // 对应载具所有库存上锁 - stockService.update(new LambdaUpdateWrapper() - .set(Stock::getStockStatus, StockStatus.OUT.getCode()) - .eq(Stock::getVehicleId, taskOutRequest.getVehicleId())); - // 对应载具状态设置 - vehicleService.update(new LambdaUpdateWrapper() - .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) - .eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); - } else { - // 查找对应库位 - Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint())); - // 创建空出库任务 - Task vehicleOutTask = new Task(); - vehicleOutTask.setTaskId(generateId("CK_")); - vehicleOutTask.setTaskType(TaskType.OUT.getCode()); - vehicleOutTask.setTaskGroup(generateId("")); - vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); - vehicleOutTask.setTaskPriority(1); - vehicleOutTask.setVehicleId(currentLocation.getVehicleId()); - vehicleOutTask.setUserName(taskOutRequest.getUserName()); - vehicleOutTask.setOrigin(currentLocation.getLocationId()); - vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); - vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); - vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); - vehicleOutTask.setCreateTime(LocalDateTime.now()); - taskService.save(vehicleOutTask); - // 对应库位所有库存上锁 - stockService.update(new LambdaUpdateWrapper() - .set(Stock::getStockStatus, StockStatus.OUT.getCode()) - .eq(Stock::getLocationId, taskOutRequest.getOriginPoint())); - // 对应库位状态设置 - vehicleService.update(new LambdaUpdateWrapper() - .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) - .eq(Vehicle::getCurrentLocation, taskOutRequest.getOriginPoint())); - } - return ""; - } - - /** - * 生成物料出库任务 - * - * @param taskOutRequest 出库请求 - * @return 结果 - */ - private String genGoodsOutTask(TaskOutRequest taskOutRequest) { - // 查询库存 - LambdaQueryWrapper stockQueryWrapper = new LambdaQueryWrapper() - .apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId()) - .apply("goods_related -> '$.remainNum' > 0") - .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId()) - .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint()); - List stocks = stockService.list(stockQueryWrapper); - List goodsOutTasks = new ArrayList<>(); - BigDecimal needNum = taskOutRequest.getGoodsNum(); - for (Stock stock : stocks) { - if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {// 库存状态正常的情况 - // 悲观锁,锁定库存状态---同一载具下的库存 - boolean lockStocksFlag = stockService.update(new LambdaUpdateWrapper() - .set(Stock::getStockStatus, StockStatus.OUT.getCode()) - .eq(Stock::getVehicleId, stock.getVehicleId()) - .eq(Stock::getStockStatus, StockStatus.OK.getCode())); - - // 锁定载具状态 - boolean lockVehicleFlag = vehicleService.update(new LambdaUpdateWrapper() - .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) - .eq(Vehicle::getVehicleId, stock.getVehicleId()) - .eq(Vehicle::getVehicleStatus, VehicleStatus.ON)); - if (!lockStocksFlag || !lockVehicleFlag) { - // 释放锁 - stockService.update(new LambdaUpdateWrapper() - .set(Stock::getStockStatus, StockStatus.OK.getCode()) - .eq(Stock::getVehicleId, stock.getVehicleId()) - .eq(Stock::getStockStatus, StockStatus.OK.getCode())); - vehicleService.update(new LambdaUpdateWrapper() - .set(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) - .eq(Vehicle::getVehicleId, stock.getVehicleId())); - continue; - } - // 创建出库任务 - Task vehicleOutTask = new Task(); - vehicleOutTask.setTaskId(generateId("CK_")); - vehicleOutTask.setTaskType(TaskType.OUT.getCode()); - vehicleOutTask.setTaskGroup(generateId("")); - vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); - vehicleOutTask.setTaskPriority(1); - vehicleOutTask.setVehicleId(stock.getVehicleId()); - vehicleOutTask.setUserName(taskOutRequest.getUserName()); - vehicleOutTask.setOrigin(stock.getLocationId()); - vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); - vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); - vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); - vehicleOutTask.setCreateTime(LocalDateTime.now()); - // TODO 设定物料相关信息 需要完善 - TaskDetailInfo taskDetailInfo = new TaskDetailInfo(); - taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId()); - taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName()); - taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum); - taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum()); - vehicleOutTask.setGoodsRelated(taskDetailInfo); - goodsOutTasks.add(vehicleOutTask); - needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum()); - } else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) { - // 查询到当前当前载具对应的任务,并同步 - Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper() - .eq(Task::getVehicleId, stock.getVehicleId())); - // 创建出库任务 - Task vehicleOutTask = new Task(); - vehicleOutTask.setTaskId(generateId("CK_")); - vehicleOutTask.setTaskType(TaskType.OUT.getCode()); - if (sameVehicleTask != null) { - vehicleOutTask.setTaskGroup(sameVehicleTask.getTaskGroup()); - vehicleOutTask.setTaskStatus(sameVehicleTask.getTaskStatus()); - vehicleOutTask.setTaskPriority(sameVehicleTask.getTaskPriority()); - vehicleOutTask.setPreTask(sameVehicleTask.getPreTask()); - } else { - vehicleOutTask.setTaskGroup(generateId("")); - vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); - vehicleOutTask.setTaskPriority(1); - } - vehicleOutTask.setVehicleId(stock.getVehicleId()); - vehicleOutTask.setUserName(taskOutRequest.getUserName()); - vehicleOutTask.setOrigin(stock.getLocationId()); - vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); - vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); - vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); - vehicleOutTask.setCreateTime(LocalDateTime.now()); - // TODO 设定物料相关信息 需要完善 - TaskDetailInfo taskDetailInfo = new TaskDetailInfo(); - taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId()); - taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName()); - taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum); - taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum()); - vehicleOutTask.setGoodsRelated(taskDetailInfo); - goodsOutTasks.add(vehicleOutTask); - needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum()); - } - // 盘点,移库,锁定状态不可使用 - if (needNum.compareTo(BigDecimal.ZERO) <= 0) { - // 库存足够,跳出循环 - break; - } - } - // 添加任务记录表 - taskService.saveBatch(goodsOutTasks); - return ""; - } - - /** - * 验证出库请求 - * - * @param taskOutRequest 出库请求 - * @return 验证结果---空为验证通过,否则输出错误信息 - */ - private String validateTaskOutRequest(TaskOutRequest taskOutRequest) { - // 验证任务 - if (taskOutRequest == null) { - return TaskOutValidationEnum.NO_REQUEST_BODY.getErrorMessage(); - } - // 验证是否包含请求信息 - if (StringUtils.isEmpty(taskOutRequest.getGoodsId()) - && StringUtils.isEmpty(taskOutRequest.getVehicleId()) - && StringUtils.isEmpty(taskOutRequest.getOriginPoint())) { - return TaskOutValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage(); - } - // 验证载具号 - if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId()) - && vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()))) { - return TaskOutValidationEnum.ERROR_VEHICLE_ID.getErrorMessage(); - } - // 验证库位 - if (StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()) - && locationService.exists(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint()))) { - return TaskOutValidationEnum.ERROR_ORIGIN_POINT.getErrorMessage(); - } - // 验证终点站台 - if (taskOutRequest.getIsPicking() == 0) {// 出库 - if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 2)) { - return TaskOutValidationEnum.ERROR_DESTINATION_POINT.getErrorMessage(); - } - } else {// 拣选出库 - if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 3)) { - return TaskOutValidationEnum.ERROR_PICK_STAND.getErrorMessage(); - } - } - // 验证物料信息 - if (StringUtils.isNotEmpty(taskOutRequest.getGoodsId())) { - if (taskOutRequest.getGoodsNum() == null || taskOutRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) { - return TaskOutValidationEnum.ERROR_GOODS_NUM.getErrorMessage(); - } - // 查询库存信息 - LambdaQueryWrapper stockQueryWrapper = new LambdaQueryWrapper() - .apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId()) - .apply("goods_related -> '$.remainNum' > 0") - .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId()) - .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint()); - if (!stockService.exists(stockQueryWrapper)) { - return TaskOutValidationEnum.NO_STOCK.getErrorMessage(); - } - } else { - if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) { - Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); - Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, currentVehicle.getCurrentLocation())); - if (!Objects.equals(currentVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) { - return TaskOutValidationEnum.ERROR_VEHICLE_STATUS.getErrorMessage(); - } - if (!Objects.equals(currentLocation.getIsLock(), 1)) { - return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage(); - } - } else { - Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint())); - if (!Objects.equals(currentLocation.getIsLock(), 1)) { - return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage(); - } - if (!Objects.equals(currentLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode())) { - return TaskOutValidationEnum.ERROR_ORIGIN_POINT_STATUS.getErrorMessage(); - } - } - } - return TaskOutValidationEnum.OK.getErrorMessage(); - } - /** * 接收任务反馈 * @@ -595,7 +209,7 @@ public class TaskController { // 创建响应信息 ResponseEntity response = new ResponseEntity(); try { - String validateInfo = validateTaskResult(wcsTaskResultRequest); + String validateInfo = validateService.validateTaskResult(wcsTaskResultRequest); if (!Objects.equals(validateInfo, TaskResultValidationEnum.OK.getErrorMessage())) { logger.error("任务反馈请求验证失败:{}", validateInfo); // 返回其他异常 @@ -730,10 +344,6 @@ public class TaskController { continue; } if (outTask.getIsPicking() == 1) { - // 拣选任务,更新任务状态 - taskService.update(new LambdaUpdateWrapper() - .set(Task::getTaskStatus, WmsTaskStatus.PICKING.getCode()) - .eq(Task::getTaskId, outTask.getTaskId())); // 当前载具上所有库存状态设置为拣选 stockService.update(new LambdaUpdateWrapper() .set(Stock::getStockStatus, StockStatus.PICKING.getCode()) @@ -744,18 +354,23 @@ public class TaskController { .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) .eq(Vehicle::getVehicleId, outTask.getVehicleId()) .ne(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode())); - } else { - // 添加任务记录 - outTask.setTaskStatus(WmsTaskStatus.FINISH.getCode()); - outTask.setFinishTime(LocalDateTime.now()); - taskRecordService.save(BeanUtil.copyProperties(outTask, TaskRecord.class)); - // 删除移库任务 - taskService.remove(new LambdaQueryWrapper().eq(Task::getTaskId, outTask.getTaskId())); + // 将该载具对应的拣选任务设置为可发送状态 + pickTaskService.update(new LambdaUpdateWrapper() + .set(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode()) + .eq(PickTask::getVehicleId, outTask.getVehicleId()) + .eq(PickTask::getPickStatus, PickTaskStatusEnum.TEMP.getCode())); + } else {// 代表整出 // 删除当前载具上所有库存 stockService.remove(new LambdaQueryWrapper().eq(Stock::getVehicleId, outTask.getVehicleId())); // 删除载具 vehicleService.remove(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, outTask.getVehicleId())); } + // 添加任务记录 + outTask.setTaskStatus(WmsTaskStatus.FINISH.getCode()); + outTask.setFinishTime(LocalDateTime.now()); + taskRecordService.save(BeanUtil.copyProperties(outTask, TaskRecord.class)); + // 删除出库任务 + taskService.remove(new LambdaQueryWrapper().eq(Task::getTaskId, outTask.getTaskId())); // 释放原来的库位 locationService.update(new LambdaUpdateWrapper() .set(Location::getLocationStatus, LocationStatus.EMPTY.getCode()) @@ -825,40 +440,6 @@ public class TaskController { } } - /** - * 验证任务反馈的请求信息 - * - * @param wcsTaskResultRequest 任务反馈的请求 - * @return 验证结果 - */ - private String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest) { - // 验证请求体是否为空 - if (wcsTaskResultRequest == null) { - return TaskResultValidationEnum.NO_REQUEST_BODY.getErrorMessage(); - } - // 验证是否缺少必须信息 - if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || StringUtils.isEmpty(wcsTaskResultRequest.getVehicleId()) - || wcsTaskResultRequest.getTaskStatus() == null) { - return TaskResultValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage(); - } - // 验证反馈的任务号是否正确 - if (!taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskGroup, wcsTaskResultRequest.getTaskId()))) { - return TaskResultValidationEnum.ERROR_TASK_GROUP.getErrorMessage(); - } - // 验证反馈的任务状态枚举是否正确 - boolean isValidWcsTaskStatus = false; - for (WcsTaskStatus wcsTaskStatus : WcsTaskStatus.values()) { - if (Objects.equals(wcsTaskStatus.getCode(), wcsTaskResultRequest.getTaskStatus())) { - isValidWcsTaskStatus = true; - break; - } - } - if (!isValidWcsTaskStatus) { - return TaskResultValidationEnum.ERROR_TASK_STATUS.getErrorMessage(); - } - return TaskResultValidationEnum.OK.getErrorMessage(); - } - /** * Wcs请求载具入库 * @@ -875,7 +456,7 @@ public class TaskController { ResponseEntity response = new ResponseEntity(); try { // 验证入库请求 - String validationInfo = validateVehicleRequest(wcsVehicleInRequest); + String validationInfo = validateService.validateVehicleRequest(wcsVehicleInRequest); if (!Objects.equals(validationInfo, "")) { logger.error("请求载具入库发生错误:{}", validationInfo); response.setCode(ResponseCode.ERROR.getCode()); @@ -944,31 +525,6 @@ public class TaskController { } } - /** - * 验证载具入库请求的正确性 - * @param wcsVehicleInRequest 载具入库请求 - * @return 验证结果 - */ - private String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest) { - // 判断请求信息 - if (wcsVehicleInRequest == null) { - return "请求信息为空"; - } - // 判断是否缺少载具号 - if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) { - return "缺少载具号"; - } - // 判断当前载具号是否存在任务 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() - .eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo()) - .eq(Task::getTaskType, TaskType.IN.getCode()); - if (!taskService.exists(queryWrapper)) { - return "当前载具没有入库或回库任务"; - } - - return ""; - } - /** * Wcs反馈重复入库问题 * @@ -985,7 +541,7 @@ public class TaskController { ResponseEntity response = new ResponseEntity(); try { // 验证入库请求 - String validationInfo = validateDuplicateLocationRequest(duplicateLocationRequest); + String validationInfo = validateService.validateDuplicateLocationRequest(duplicateLocationRequest); if (!Objects.equals(validationInfo, "")) { logger.error("反馈重复入库错误:{}", validationInfo); response.setCode(ResponseCode.ERROR.getCode()); @@ -1057,32 +613,68 @@ public class TaskController { } /** - * 验证重复入库问题反馈的请求 - * @param duplicateLocationRequest 请求信息 - * @return 验证结果 + * 查找所有物料 */ - private String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest) { - // 判断请求信息 - if (duplicateLocationRequest == null) { - return "请求信息为空"; - } - // 判断是否缺少任务号 - if (StringUtils.isEmpty(duplicateLocationRequest.getTaskId())) { - return "缺少任务号"; - } - // 判断是否缺少载具号 - if (StringUtils.isEmpty(duplicateLocationRequest.getVehicleId())) { - return "缺少载具号"; - } - // 判断当前载具号是否存在任务 - LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() - .eq(Task::getTaskGroup, duplicateLocationRequest.getTaskId()) - .eq(Task::getVehicleId, duplicateLocationRequest.getVehicleId()) - .eq(Task::getTaskType, TaskType.IN.getCode()); - if (!taskService.exists(queryWrapper)) { - return "当前反馈的重复入库任务不存在"; + @PostMapping("/getTasksByPage") + @ResponseBody + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) + public String getTasksByPage(@RequestBody TaskQuery taskQuery) { + ResponseEntity response = new ResponseEntity(); + try { + Page page = taskQuery.toMpPage(); + //更新条件 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() + .eq(taskQuery.getTaskType() != null, Task::getTaskType, taskQuery.getTaskType()) + .eq(taskQuery.getTaskStatus() != null, Task::getTaskStatus, taskQuery.getTaskStatus()) + .like(StringUtils.isNotEmpty(taskQuery.getVehicleId()), Task::getVehicleId, taskQuery.getVehicleId()) + .apply(StringUtils.isNotEmpty(taskQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", taskQuery.getGoodsId()) + .apply(StringUtils.isNotEmpty(taskQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", taskQuery.getGoodsName()); + Page tasksPage = taskService.page(page, lambdaQueryWrapper); + // 生成数据 + PageDto pageDto = PageDto.of(tasksPage, tasks -> BeanUtil.copyProperties(tasks, TaskVO.class)); + response.setCode(ResponseCode.OK.getCode()); + response.setMessage("查询成功"); + response.setReturnData(pageDto); + return convertJsonString(response); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + logger.error("查询任务发生异常"); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("查询任务发生异常"); + return convertJsonString(response); } + } - return ""; + /** + * 根据 + */ + @PostMapping("/getTasks") + @ResponseBody + @Transactional(isolation = Isolation.REPEATABLE_READ, propagation = Propagation.REQUIRED) + public String getTasks(@RequestBody TaskQuery taskQuery) { + ResponseEntity response = new ResponseEntity(); + try { + //更新条件 + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper() + .eq(taskQuery.getTaskType() != null, Task::getTaskType, taskQuery.getTaskType()) + .eq(taskQuery.getTaskStatus() != null, Task::getTaskStatus, taskQuery.getTaskStatus()) + .eq(taskQuery.getIsPicking() != null, Task::getIsPicking, taskQuery.getIsPicking()) + .like(StringUtils.isNotEmpty(taskQuery.getVehicleId()), Task::getVehicleId, taskQuery.getVehicleId()) + .apply(StringUtils.isNotEmpty(taskQuery.getGoodsId()), "goods_related ->> '$.goodsId' like concat('%', {0}, '%')", taskQuery.getGoodsId()) + .apply(StringUtils.isNotEmpty(taskQuery.getGoodsName()), "goods_related ->> '$.goodsName' like concat('%', {0}, '%')", taskQuery.getGoodsName()); + List tasks = taskService.list(lambdaQueryWrapper); + response.setCode(ResponseCode.OK.getCode()); + response.setMessage("查询成功"); + response.setReturnData(tasks.isEmpty() ? new ArrayList() : tasks); + return convertJsonString(response); + } catch (Exception e) { + // 回滚事务 + TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); + logger.error("查询任务发生异常"); + response.setCode(ResponseCode.ERROR.getCode()); + response.setMessage("查询任务发生异常"); + return convertJsonString(response); + } } } \ No newline at end of file diff --git a/src/main/java/com/wms/entity/app/request/TaskQuery.java b/src/main/java/com/wms/entity/app/request/TaskQuery.java new file mode 100644 index 0000000..67bd48e --- /dev/null +++ b/src/main/java/com/wms/entity/app/request/TaskQuery.java @@ -0,0 +1,44 @@ +package com.wms.entity.app.request; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.wms.entity.app.dto.extend.TaskDetailInfo; +import com.wms.entity.table.Task; +import com.wms.utils.StringUtils; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(callSuper = true) +public class TaskQuery extends PageQuery { + @JsonProperty("taskType") + private Integer taskType; + @JsonProperty("vehicleId") + private String vehicleId; + @JsonProperty("goodsId") + private String goodsId; + @JsonProperty("goodsName") + private String goodsName; + @JsonProperty("taskStatus") + private Integer taskStatus; + @JsonProperty("isPicking") + private Integer isPicking; + + /** + * 根据客户端查询生成数据库查询条件 + * @return 数据库PO + */ + public Task toTaskPO() { + Task taskPO = new Task(); + taskPO.setTaskType(taskType);// 任务类型 + taskPO.setVehicleId(vehicleId);// 载具号 + taskPO.setIsPicking(isPicking); + if (StringUtils.isNotEmpty(goodsId) || StringUtils.isNotEmpty(goodsName)) {// 包含物料详细信息 + TaskDetailInfo goodsRelatedPO = new TaskDetailInfo(); + goodsRelatedPO.setGoodsId(goodsId); + goodsRelatedPO.setGoodsName(goodsName); + taskPO.setGoodsRelated(goodsRelatedPO); + } + + return taskPO; + } +} diff --git a/src/main/java/com/wms/entity/app/vo/TaskVO.java b/src/main/java/com/wms/entity/app/vo/TaskVO.java new file mode 100644 index 0000000..b346d71 --- /dev/null +++ b/src/main/java/com/wms/entity/app/vo/TaskVO.java @@ -0,0 +1,82 @@ +package com.wms.entity.app.vo; + +import com.wms.entity.app.dto.extend.TaskDetailInfo; +import lombok.Data; + +import java.math.BigDecimal; +import java.time.LocalDateTime; + +/** + * 任务记录VO + */ +@Data +public class TaskVO { + /** + * 任务号 + */ + private String taskId; + /** + * 任务类型 + */ + private Integer taskType; + /** + * 任务状态 + */ + private Integer taskStatus; + /** + * 起点 + */ + private String origin; + /** + * 终点 + */ + private String destination; + /** + * 任务优先级 + */ + private Integer taskPriority; + /** + * 任务组 + */ + private String taskGroup; + /** + * 载具号 + */ + private String vehicleId; + /** + * 重量 + */ + private BigDecimal weight; + /** + * 载具尺寸 + */ + private Integer vehicleSize; + /** + * 创建时间 + */ + private LocalDateTime createTime; + /** + * 完成时间 + */ + private LocalDateTime finishTime; + /** + * 用户名 + */ + private String userName; + /** + * 物料相关 + */ + private TaskDetailInfo goodsRelated; + /** + * 前置任务号 + */ + private String preTask; + /** + * 是否拣选 + */ + private Integer isPicking; + /** + * 拣选站台 + */ + private String pickStand; +} diff --git a/src/main/java/com/wms/entity/table/PickTask.java b/src/main/java/com/wms/entity/table/PickTask.java index adeff81..c1502e4 100644 --- a/src/main/java/com/wms/entity/table/PickTask.java +++ b/src/main/java/com/wms/entity/table/PickTask.java @@ -30,7 +30,7 @@ public class PickTask { private String standId; /** * 拣选任务状态 - * -1:已取消 + * -1:暂时不可发送 * 0:初始化 * 1:已发送 * 2:已完成 diff --git a/src/main/java/com/wms/service/business/IValidateService.java b/src/main/java/com/wms/service/business/IValidateService.java index 6da236f..84c148b 100644 --- a/src/main/java/com/wms/service/business/IValidateService.java +++ b/src/main/java/com/wms/service/business/IValidateService.java @@ -1,10 +1,46 @@ package com.wms.service.business; import com.wms.entity.app.request.TaskInRequest; +import com.wms.entity.app.request.TaskOutRequest; +import com.wms.entity.app.wcs.WcsTaskResultRequest; +import com.wms.entity.app.wcs.WcsVehicleInRequest; /** * 验证服务接口 */ public interface IValidateService { + /** + * 验证入库请求 + * @param taskInRequest 入库请求 + * @return 验证结果 + */ String validateTaskInRequest(TaskInRequest taskInRequest); + + /** + * 验证出库请求 + * @param taskOutRequest 出库请求 + * @return 验证结果 + */ + String validateTaskOutRequest(TaskOutRequest taskOutRequest); + + /** + * 验证任务结果反馈请求 + * @param wcsTaskResultRequest 任务结果反馈请求 + * @return 验证结果 + */ + String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest); + + /** + * 验证载具入库请求 + * @param wcsVehicleInRequest 载具入库请求 + * @return 验证结果 + */ + String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest); + + /** + * 验证重复入库请求 + * @param duplicateLocationRequest 重复入库请求 + * @return 验证结果 + */ + String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest); } diff --git a/src/main/java/com/wms/service/business/IWmsJobService.java b/src/main/java/com/wms/service/business/IWmsJobService.java new file mode 100644 index 0000000..0d8d1b6 --- /dev/null +++ b/src/main/java/com/wms/service/business/IWmsJobService.java @@ -0,0 +1,24 @@ +package com.wms.service.business; + +/** + * Wms定时任务服务接口 + */ +public interface IWmsJobService { + /** + * 执行普通任务 + * @throws Exception 异常用于回滚事务 + */ + void sendCommonTasks() throws Exception; + + /** + * 发送拣选任务 + * @throws Exception 异常用于回滚事务 + */ + void sendPickTasks() throws Exception; + + /** + * 发送重复入库修正后的任务 + * @throws Exception 异常用于回滚 + */ + void solveDuplicateTask() throws Exception; +} diff --git a/src/main/java/com/wms/service/business/IWmsTaskService.java b/src/main/java/com/wms/service/business/IWmsTaskService.java new file mode 100644 index 0000000..39c7d00 --- /dev/null +++ b/src/main/java/com/wms/service/business/IWmsTaskService.java @@ -0,0 +1,37 @@ +package com.wms.service.business; + +import com.wms.entity.app.request.TaskInRequest; +import com.wms.entity.app.request.TaskOutRequest; + +/** + * WMS任务服务接口 + */ +public interface IWmsTaskService { + /** + * 创建载具入库任务 + * @param taskInRequest 入库请求 + * @return 结果 + */ + String genEmptyInTask(TaskInRequest taskInRequest); + + /** + * 创建物料入库任务 + * @param taskInRequest 入库请求 + * @return 结果 + */ + String genGoodsInTask(TaskInRequest taskInRequest); + + /** + * 创建载具或库位出库任务 + * @param taskOutRequest 出库请求 + * @return 结果 + */ + String genVehicleLocationOutTask(TaskOutRequest taskOutRequest); + + /** + * 创建物料出库任务 + * @param taskOutRequest 出库请求 + * @return 结果 + */ + String genGoodsOutTask(TaskOutRequest taskOutRequest); +} diff --git a/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java index 610826a..fbbeafe 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/ValidateServiceImplements.java @@ -1,18 +1,17 @@ package com.wms.service.business.serviceImplements; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.wms.constants.enums.ConfigMapKeyEnum; -import com.wms.constants.enums.TaskInValidationEnum; -import com.wms.constants.enums.TaskType; -import com.wms.constants.enums.VehicleStatus; +import com.wms.constants.enums.*; import com.wms.entity.app.request.GoodsInRequest; import com.wms.entity.app.request.TaskInRequest; +import com.wms.entity.app.request.TaskOutRequest; +import com.wms.entity.app.wcs.WcsTaskResultRequest; +import com.wms.entity.app.wcs.WcsVehicleInRequest; +import com.wms.entity.table.Location; +import com.wms.entity.table.Stock; import com.wms.entity.table.Task; import com.wms.entity.table.Vehicle; -import com.wms.service.GoodsService; -import com.wms.service.StandService; -import com.wms.service.TaskService; -import com.wms.service.VehicleService; +import com.wms.service.*; import com.wms.service.business.IValidateService; import com.wms.utils.StringUtils; import lombok.RequiredArgsConstructor; @@ -22,6 +21,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; +import java.util.Objects; import static com.wms.config.InitLocalConfig.configMap; @@ -32,10 +32,18 @@ import static com.wms.config.InitLocalConfig.configMap; @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class ValidateServiceImplements implements IValidateService { private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志 - private final VehicleService vehicleService; - private final TaskService taskService; - private final StandService standService; - private final GoodsService goodsService; + private final VehicleService vehicleService;// 载具服务 + private final TaskService taskService;// 任务服务 + private final StandService standService;// 站台服务 + private final GoodsService goodsService;// 物料服务 + private final LocationService locationService;// 库位服务 + private final StockService stockService;// 库存服务 + + /** + * 验证入库请求 + * @param taskInRequest 入库请求 + * @return 验证结果 + */ @Override public String validateTaskInRequest(TaskInRequest taskInRequest) { if (taskInRequest == null) { @@ -97,4 +105,170 @@ public class ValidateServiceImplements implements IValidateService { } return TaskInValidationEnum.OK.getErrorMessage(); } + + /** + * 验证出库请求 + * @param taskOutRequest 出库请求 + * @return 验证结果 + */ + @Override + public String validateTaskOutRequest(TaskOutRequest taskOutRequest) { + // 验证任务 + if (taskOutRequest == null) { + return TaskOutValidationEnum.NO_REQUEST_BODY.getErrorMessage(); + } + // 验证是否包含请求信息 + if (StringUtils.isEmpty(taskOutRequest.getGoodsId()) + && StringUtils.isEmpty(taskOutRequest.getVehicleId()) + && StringUtils.isEmpty(taskOutRequest.getOriginPoint())) { + return TaskOutValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage(); + } + // 验证载具号 + if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId()) + && vehicleService.exists(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId()))) { + return TaskOutValidationEnum.ERROR_VEHICLE_ID.getErrorMessage(); + } + // 验证库位 + if (StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()) + && locationService.exists(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint()))) { + return TaskOutValidationEnum.ERROR_ORIGIN_POINT.getErrorMessage(); + } + // 验证终点站台 + if (taskOutRequest.getIsPicking() == 0) {// 出库 + if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 2)) { + return TaskOutValidationEnum.ERROR_DESTINATION_POINT.getErrorMessage(); + } + } else {// 拣选出库 + if (!standService.validateStand(taskOutRequest.getDestinationPoint(), 3)) { + return TaskOutValidationEnum.ERROR_PICK_STAND.getErrorMessage(); + } + } + // 验证物料信息 + if (StringUtils.isNotEmpty(taskOutRequest.getGoodsId())) { + if (taskOutRequest.getGoodsNum() == null || taskOutRequest.getGoodsNum().compareTo(BigDecimal.ZERO) <= 0) { + return TaskOutValidationEnum.ERROR_GOODS_NUM.getErrorMessage(); + } + // 查询库存信息 + LambdaQueryWrapper stockQueryWrapper = new LambdaQueryWrapper() + .apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId()) + .apply("goods_related -> '$.remainNum' > 0") + .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId()) + .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint()); + if (!stockService.exists(stockQueryWrapper)) { + return TaskOutValidationEnum.NO_STOCK.getErrorMessage(); + } + } else { + if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) { + Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); + Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, currentVehicle.getCurrentLocation())); + if (!Objects.equals(currentVehicle.getVehicleStatus(), VehicleStatus.ON.getCode())) { + return TaskOutValidationEnum.ERROR_VEHICLE_STATUS.getErrorMessage(); + } + if (!Objects.equals(currentLocation.getIsLock(), 1)) { + return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage(); + } + } else { + Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint())); + if (!Objects.equals(currentLocation.getIsLock(), 1)) { + return TaskOutValidationEnum.LOCKED_LOCATION.getErrorMessage(); + } + if (!Objects.equals(currentLocation.getLocationStatus(), LocationStatus.OCCUPY.getCode())) { + return TaskOutValidationEnum.ERROR_ORIGIN_POINT_STATUS.getErrorMessage(); + } + } + } + return TaskOutValidationEnum.OK.getErrorMessage(); + } + + /** + * 验证任务反馈的请求信息 + * + * @param wcsTaskResultRequest 任务反馈的请求 + * @return 验证结果 + */ + @Override + public String validateTaskResult(WcsTaskResultRequest wcsTaskResultRequest) { + // 验证请求体是否为空 + if (wcsTaskResultRequest == null) { + return TaskResultValidationEnum.NO_REQUEST_BODY.getErrorMessage(); + } + // 验证是否缺少必须信息 + if (StringUtils.isEmpty(wcsTaskResultRequest.getTaskId()) || StringUtils.isEmpty(wcsTaskResultRequest.getVehicleId()) + || wcsTaskResultRequest.getTaskStatus() == null) { + return TaskResultValidationEnum.LACK_REQUIRED_PARAM.getErrorMessage(); + } + // 验证反馈的任务号是否正确 + if (!taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskGroup, wcsTaskResultRequest.getTaskId()))) { + return TaskResultValidationEnum.ERROR_TASK_GROUP.getErrorMessage(); + } + // 验证反馈的任务状态枚举是否正确 + boolean isValidWcsTaskStatus = false; + for (WcsTaskStatus wcsTaskStatus : WcsTaskStatus.values()) { + if (Objects.equals(wcsTaskStatus.getCode(), wcsTaskResultRequest.getTaskStatus())) { + isValidWcsTaskStatus = true; + break; + } + } + if (!isValidWcsTaskStatus) { + return TaskResultValidationEnum.ERROR_TASK_STATUS.getErrorMessage(); + } + return TaskResultValidationEnum.OK.getErrorMessage(); + } + + /** + * 验证载具入库请求的正确性 + * @param wcsVehicleInRequest 载具入库请求 + * @return 验证结果 + */ + @Override + public String validateVehicleRequest(WcsVehicleInRequest wcsVehicleInRequest) { + // 判断请求信息 + if (wcsVehicleInRequest == null) { + return "请求信息为空"; + } + // 判断是否缺少载具号 + if (StringUtils.isEmpty(wcsVehicleInRequest.getVehicleNo())) { + return "缺少载具号"; + } + // 判断当前载具号是否存在任务 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(Task::getVehicleId, wcsVehicleInRequest.getVehicleNo()) + .eq(Task::getTaskType, TaskType.IN.getCode()); + if (!taskService.exists(queryWrapper)) { + return "当前载具没有入库或回库任务"; + } + + return ""; + } + + /** + * 验证重复入库问题反馈的请求 + * @param duplicateLocationRequest 请求信息 + * @return 验证结果 + */ + @Override + public String validateDuplicateLocationRequest(WcsTaskResultRequest duplicateLocationRequest) { + // 判断请求信息 + if (duplicateLocationRequest == null) { + return "请求信息为空"; + } + // 判断是否缺少任务号 + if (StringUtils.isEmpty(duplicateLocationRequest.getTaskId())) { + return "缺少任务号"; + } + // 判断是否缺少载具号 + if (StringUtils.isEmpty(duplicateLocationRequest.getVehicleId())) { + return "缺少载具号"; + } + // 判断当前载具号是否存在任务 + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper() + .eq(Task::getTaskGroup, duplicateLocationRequest.getTaskId()) + .eq(Task::getVehicleId, duplicateLocationRequest.getVehicleId()) + .eq(Task::getTaskType, TaskType.IN.getCode()); + if (!taskService.exists(queryWrapper)) { + return "当前反馈的重复入库任务不存在"; + } + + return ""; + } } diff --git a/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java new file mode 100644 index 0000000..8b596f5 --- /dev/null +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsJobServiceImplements.java @@ -0,0 +1,253 @@ +package com.wms.service.business.serviceImplements; + +import com.alibaba.fastjson2.JSON; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.wms.constants.enums.*; +import com.wms.entity.app.ResponseEntity; +import com.wms.entity.app.request.TaskInRequest; +import com.wms.entity.app.wcs.WcsStandTaskRequest; +import com.wms.entity.app.wcs.WcsTaskRequest; +import com.wms.entity.table.PickTask; +import com.wms.entity.table.Task; +import com.wms.entity.table.WmsLog; +import com.wms.service.LogService; +import com.wms.service.PickTaskService; +import com.wms.service.TaskService; +import com.wms.service.business.IWmsJobService; +import com.wms.utils.HttpUtils; +import com.wms.utils.StringUtils; +import com.wms.utils.WmsUtils; +import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.*; + +import static com.wms.config.InitLocalConfig.configMap; +import static com.wms.utils.StringUtils.convertJsonString; +import static com.wms.utils.WmsUtils.generateId; + +/** + * Wms定时任务服务实现 + */ +@Service +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class WmsJobServiceImplements implements IWmsJobService { + private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志 + private final LogService logService;// 日志服务 + private final TaskService taskService;// 任务服务 + private final PickTaskService pickTaskService;// 拣选任务服务 + /** + * 发送正常的任务 + */ + public void sendCommonTasks() throws Exception { + try { + // 检索任务表---新建未下发的任务 + LambdaQueryWrapper waitForDistributeTaskQuery = new LambdaQueryWrapper() + .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode()); + List allTasks = taskService.list(waitForDistributeTaskQuery); + // 需要发送给wcs的任务列表 + List request = new ArrayList<>(); + // 已经下发的任务组列表 + List taskGroupIds = new ArrayList<>(); + if (!allTasks.isEmpty()) { + for (Task task : allTasks) { + if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 + // 查询一下前置的任务有没有存在,存在则不下发 + if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { + continue; + } + } + if (taskGroupIds.contains(task.getTaskGroup())) { + continue; + } + // 创建发送的任务 + WcsTaskRequest tempTask = new WcsTaskRequest(); + tempTask.setTaskId(task.getTaskGroup()); + if (Objects.equals(task.getTaskType(), TaskType.INVENTORY.getCode())) { + tempTask.setTaskType(TaskType.OUT.getCode()); + } else { + 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()); + } + 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 && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { + taskService.update(new LambdaUpdateWrapper() + .set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode()) + .in(Task::getTaskGroup, taskGroupIds) + .eq(Task::getTaskStatus, WmsTaskStatus.NEW.getCode())); + } else { + logger.error("发送任务错误:{}", convertJsonString(result)); + } + } else { + logger.error("WCS发送任务地址为空"); + } + } + } catch (Exception exception) { + logger.error("向WCS发送任务时发生异常:{}", convertJsonString(exception)); + throw new Exception("向WCS发送任务时发生异常"); + } + } + + /** + * 发送拣选任务 + */ + public void sendPickTasks() throws Exception { + try { + // 检索任务表---新建未下发的拣选任务 + LambdaQueryWrapper waitForDistributePickTaskQuery = new LambdaQueryWrapper() + .eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode()); + List allPickTasks = pickTaskService.list(waitForDistributePickTaskQuery); + if (allPickTasks == null || allPickTasks.isEmpty()) { + return; + } + // 需要发送给wcs的拣选任务列表 + List request = new ArrayList<>(); + // 载具对应站台列表 + Map> vehicleAndStansMap = new HashMap<>(); + // 循环生成载具对应站台列表 + for (PickTask pickTask : allPickTasks) { + // 当前载具已经添加过站台 + if (vehicleAndStansMap.containsKey(pickTask.getVehicleId())) { + List oldStandIds = vehicleAndStansMap.get(pickTask.getVehicleId()); + oldStandIds.add(pickTask.getStandId()); + vehicleAndStansMap.replace(pickTask.getVehicleId(), oldStandIds); + } else {// 新载具 + List newStandIds = new ArrayList<>(); + newStandIds.add(pickTask.getStandId()); + vehicleAndStansMap.put(pickTask.getVehicleId(), newStandIds); + } + } + // 循环生成Wcs任务请求 + for (String vehicleId : vehicleAndStansMap.keySet()) { + WcsStandTaskRequest requestSingle = new WcsStandTaskRequest(); + requestSingle.setTaskGroup(WmsUtils.generateId(vehicleId)); + requestSingle.setTaskType(1); + requestSingle.setVehicleNo(vehicleId); + requestSingle.setLocation(vehicleAndStansMap.get(vehicleId)); + requestSingle.setRemark("站台拣选任务"); + request.add(requestSingle); + } + if (!request.isEmpty()) { + // 发送任务 + String url = configMap.get(ConfigMapKeyEnum.URL_WCS_PICK_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发送拣选任务", "setConveyTask", convertJsonString(request), convertJsonString(result), url, LocalDateTime.now(), "WMS")); + } catch (Exception e) { + logger.error("插入日志错误"); + } + if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { + pickTaskService.update(new LambdaUpdateWrapper() + .set(PickTask::getPickStatus, PickTaskStatusEnum.SEND.getCode()) + .in(PickTask::getVehicleId, vehicleAndStansMap.keySet()) + .eq(PickTask::getPickStatus, PickTaskStatusEnum.NEW.getCode())); + } else { + logger.error("发送拣选任务错误:{}", convertJsonString(result)); + } + } else { + logger.error("WCS发送拣选任务地址为空"); + } + } + } catch (Exception exception) { + logger.error("向WCS发送拣选任务时发生异常:{}", convertJsonString(exception)); + throw new Exception("向WCS发送拣选任务时发生异常"); + } + } + + /** + * 处理重复入库的任务 + */ + public void solveDuplicateTask() throws Exception { + try { + // 检索任务表---重复入库的任务 + LambdaQueryWrapper duplicateTaskQueryWrapper = new LambdaQueryWrapper() + .eq(Task::getTaskType, TaskType.IN.getCode()) + .eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode()); + List duplicateTasks = taskService.list(duplicateTaskQueryWrapper); + // 需要发送给wcs的任务列表 + List request = new ArrayList<>(); + // 已经下发的任务组列表 + List taskGroupIds = new ArrayList<>(); + if (!duplicateTasks.isEmpty()) { + for (Task task : duplicateTasks) { + if (StringUtils.isNotEmpty(task.getPreTask())) {// 当前任务具有前置任务 + // 查询一下前置的任务有没有存在,存在则不下发 + if (taskService.exists(new LambdaQueryWrapper().eq(Task::getTaskId, task.getPreTask()))) { + continue; + } + } + if (taskGroupIds.contains(task.getTaskGroup())) { + // 已经发送过的任务组,跳过 + continue; + } + // 创建发送的任务 + WcsTaskRequest tempTask = new WcsTaskRequest(); + tempTask.setTaskId(task.getTaskGroup()); + tempTask.setDestination(task.getDestination()); + tempTask.setVehicleNo(task.getVehicleId()); + request.add(tempTask); + // 已经发送过的任务组 + taskGroupIds.add(task.getTaskGroup()); + } + if (request.isEmpty()) { + return; + } + // 发送任务 + String url = configMap.get(ConfigMapKeyEnum.URL_NEW_DESTINATION.getConfigKey()); + if (url != null) { + logger.info("向WCS发送新目的地,地址:{},请求详情:{}", url, convertJsonString(request)); + request.forEach(wcsTaskRequest -> { + ResponseEntity result = JSON.parseObject(HttpUtils.sendHttpPostWithoutToken(url, convertJsonString(wcsTaskRequest)), ResponseEntity.class); + try { + logService.save(new WmsLog(WmsUtils.generateId("LOG_"), "向WCS发送新目的地", "setStackerTaskNewDestination", convertJsonString(wcsTaskRequest), convertJsonString(result), url, LocalDateTime.now(), "WMS")); + } catch (Exception e) { + logger.error("插入日志错误"); + } + if (result != null && Objects.equals(ResponseCode.OK.getCode(), result.getCode())) { + taskService.update(new LambdaUpdateWrapper() + .set(Task::getTaskStatus, WmsTaskStatus.WAIT.getCode()) + .in(Task::getTaskGroup, taskGroupIds) + .eq(Task::getTaskStatus, WmsTaskStatus.DUPLICATE.getCode())); + } else { + 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/WmsTaskServiceImplements.java b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java new file mode 100644 index 0000000..c1cc4a6 --- /dev/null +++ b/src/main/java/com/wms/service/business/serviceImplements/WmsTaskServiceImplements.java @@ -0,0 +1,298 @@ +package com.wms.service.business.serviceImplements; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.wms.constants.enums.StockStatus; +import com.wms.constants.enums.TaskType; +import com.wms.constants.enums.VehicleStatus; +import com.wms.constants.enums.WmsTaskStatus; +import com.wms.entity.app.dto.extend.TaskDetailInfo; +import com.wms.entity.app.request.GoodsInRequest; +import com.wms.entity.app.request.TaskInRequest; +import com.wms.entity.app.request.TaskOutRequest; +import com.wms.entity.table.Location; +import com.wms.entity.table.Stock; +import com.wms.entity.table.Task; +import com.wms.entity.table.Vehicle; +import com.wms.service.*; +import com.wms.service.business.IWmsTaskService; +import com.wms.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import static com.wms.utils.StringUtils.convertJsonString; +import static com.wms.utils.WmsUtils.generateId; + +/** + * WMS任务服务实现 + */ +@Service +@RequiredArgsConstructor(onConstructor = @__(@Autowired)) +public class WmsTaskServiceImplements implements IWmsTaskService { + private final Logger logger = LoggerFactory.getLogger(this.getClass());// 日志 + private final VehicleService vehicleService;// 载具服务 + private final TaskService taskService;// 任务服务 + private final LocationService locationService;// 库位服务 + private final StockService stockService;// 库存服务 + + + /** + * 添加空入库任务 + * + * @param taskInRequest 入库请求 + * @return 添加结果 + */ + @Override + public String genEmptyInTask(TaskInRequest taskInRequest) { + String result = ""; + Task tempInTask = new Task(); + tempInTask.setTaskId(generateId("RK_")); + tempInTask.setTaskType(TaskType.IN.getCode()); + tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode()); + tempInTask.setTaskGroup(generateId("")); + tempInTask.setTaskPriority(1); + tempInTask.setVehicleId(taskInRequest.getVehicleId()); + tempInTask.setVehicleSize(1); + tempInTask.setWeight(taskInRequest.getTotalWeight()); + tempInTask.setCreateTime(LocalDateTime.now()); + tempInTask.setUserName(taskInRequest.getUserName()); + try { + if (!taskService.save(tempInTask)) { + return "添加空入库任务失败"; + } + } catch (Exception e) { + logger.error("添加空入库任务异常:{}", convertJsonString(e)); + return "添加空入库任务失败"; + } + return result; + } + + /** + * 添加入库任务 + * + * @param taskInRequest 入库请求 + * @return 添加结果 + */ + @Override + public String genGoodsInTask(TaskInRequest taskInRequest) { + String result = ""; + String taskGroupId = generateId(""); + List tempTasks = new ArrayList<>(); + for (GoodsInRequest goodsInRequest : taskInRequest.getGoodsList()) { + Task tempInTask = new Task(); + tempInTask.setTaskId(generateId("RK_")); + tempInTask.setTaskType(TaskType.IN.getCode()); + tempInTask.setTaskStatus(WmsTaskStatus.TEMP.getCode()); + tempInTask.setTaskGroup(taskGroupId); + tempInTask.setTaskPriority(1); + tempInTask.setVehicleId(taskInRequest.getVehicleId()); + tempInTask.setVehicleSize(1); + tempInTask.setWeight(taskInRequest.getTotalWeight()); + tempInTask.setCreateTime(LocalDateTime.now()); + tempInTask.setUserName(taskInRequest.getUserName()); + // 物料相关信息 + TaskDetailInfo goodsRelatedInfo = new TaskDetailInfo(); + // TODO 物料信息需要完善 + goodsRelatedInfo.setGoodsId(goodsInRequest.getGoodsId()); + goodsRelatedInfo.setGoodsName(""); + goodsRelatedInfo.setOpNum(goodsInRequest.getGoodsNum()); + goodsRelatedInfo.setOriginNum(BigDecimal.ZERO); + tempInTask.setGoodsRelated(goodsRelatedInfo); + + tempTasks.add(tempInTask); + } + + try { + if (!taskService.saveBatch(tempTasks)) { + return "添加入库任务失败"; + } + } catch (Exception e) { + logger.error("添加入库任务异常:{}", convertJsonString(e)); + return "添加入库任务失败"; + } + return result; + } + + /** + * 生成载具或库位出库任务 + * + * @param taskOutRequest 出库请求 + * @return 结果 + */ + @Override + public String genVehicleLocationOutTask(TaskOutRequest taskOutRequest) { + // 查询对应载具 + if (StringUtils.isNotEmpty(taskOutRequest.getVehicleId())) { + Vehicle currentVehicle = vehicleService.getOne(new LambdaQueryWrapper().eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); + // 创建空出库任务 + Task vehicleOutTask = new Task(); + vehicleOutTask.setTaskId(generateId("CK_")); + vehicleOutTask.setTaskType(TaskType.OUT.getCode()); + vehicleOutTask.setTaskGroup(generateId("")); + vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + vehicleOutTask.setTaskPriority(1); + vehicleOutTask.setVehicleId(taskOutRequest.getVehicleId()); + vehicleOutTask.setUserName(taskOutRequest.getUserName()); + vehicleOutTask.setOrigin(currentVehicle.getCurrentLocation()); + vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); + vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); + vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); + vehicleOutTask.setCreateTime(LocalDateTime.now()); + taskService.save(vehicleOutTask); + // 对应载具所有库存上锁 + stockService.update(new LambdaUpdateWrapper() + .set(Stock::getStockStatus, StockStatus.OUT.getCode()) + .eq(Stock::getVehicleId, taskOutRequest.getVehicleId())); + // 对应载具状态设置 + vehicleService.update(new LambdaUpdateWrapper() + .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) + .eq(Vehicle::getVehicleId, taskOutRequest.getVehicleId())); + } else { + // 查找对应库位 + Location currentLocation = locationService.getOne(new LambdaQueryWrapper().eq(Location::getLocationId, taskOutRequest.getOriginPoint())); + // 创建空出库任务 + Task vehicleOutTask = new Task(); + vehicleOutTask.setTaskId(generateId("CK_")); + vehicleOutTask.setTaskType(TaskType.OUT.getCode()); + vehicleOutTask.setTaskGroup(generateId("")); + vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + vehicleOutTask.setTaskPriority(1); + vehicleOutTask.setVehicleId(currentLocation.getVehicleId()); + vehicleOutTask.setUserName(taskOutRequest.getUserName()); + vehicleOutTask.setOrigin(currentLocation.getLocationId()); + vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); + vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); + vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); + vehicleOutTask.setCreateTime(LocalDateTime.now()); + taskService.save(vehicleOutTask); + // 对应库位所有库存上锁 + stockService.update(new LambdaUpdateWrapper() + .set(Stock::getStockStatus, StockStatus.OUT.getCode()) + .eq(Stock::getLocationId, taskOutRequest.getOriginPoint())); + // 对应库位状态设置 + vehicleService.update(new LambdaUpdateWrapper() + .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) + .eq(Vehicle::getCurrentLocation, taskOutRequest.getOriginPoint())); + } + return ""; + } + /** + * 生成物料出库任务 + * + * @param taskOutRequest 出库请求 + * @return 结果 + */ + @Override + public String genGoodsOutTask(TaskOutRequest taskOutRequest) { + // 查询库存 + LambdaQueryWrapper stockQueryWrapper = new LambdaQueryWrapper() + .apply("goods_related -> '$.goodsId' = {0}", taskOutRequest.getGoodsId()) + .apply("goods_related -> '$.remainNum' > 0") + .eq(StringUtils.isNotEmpty(taskOutRequest.getVehicleId()), Stock::getVehicleId, taskOutRequest.getVehicleId()) + .eq(StringUtils.isNotEmpty(taskOutRequest.getOriginPoint()), Stock::getLocationId, taskOutRequest.getOriginPoint()); + List stocks = stockService.list(stockQueryWrapper); + List goodsOutTasks = new ArrayList<>(); + BigDecimal needNum = taskOutRequest.getGoodsNum(); + for (Stock stock : stocks) { + if (Objects.equals(stock.getStockStatus(), StockStatus.OK.getCode())) {// 库存状态正常的情况 + // 悲观锁,锁定库存状态---同一载具下的库存 + boolean lockStocksFlag = stockService.update(new LambdaUpdateWrapper() + .set(Stock::getStockStatus, StockStatus.OUT.getCode()) + .eq(Stock::getVehicleId, stock.getVehicleId()) + .eq(Stock::getStockStatus, StockStatus.OK.getCode())); + + // 锁定载具状态 + boolean lockVehicleFlag = vehicleService.update(new LambdaUpdateWrapper() + .set(Vehicle::getVehicleStatus, VehicleStatus.OUT.getCode()) + .eq(Vehicle::getVehicleId, stock.getVehicleId()) + .eq(Vehicle::getVehicleStatus, VehicleStatus.ON)); + if (!lockStocksFlag || !lockVehicleFlag) { + // 释放锁 + stockService.update(new LambdaUpdateWrapper() + .set(Stock::getStockStatus, StockStatus.OK.getCode()) + .eq(Stock::getVehicleId, stock.getVehicleId()) + .eq(Stock::getStockStatus, StockStatus.OK.getCode())); + vehicleService.update(new LambdaUpdateWrapper() + .set(Vehicle::getVehicleStatus, VehicleStatus.ON.getCode()) + .eq(Vehicle::getVehicleId, stock.getVehicleId())); + continue; + } + // 创建出库任务 + Task vehicleOutTask = new Task(); + vehicleOutTask.setTaskId(generateId("CK_")); + vehicleOutTask.setTaskType(TaskType.OUT.getCode()); + vehicleOutTask.setTaskGroup(generateId("")); + vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + vehicleOutTask.setTaskPriority(1); + vehicleOutTask.setVehicleId(stock.getVehicleId()); + vehicleOutTask.setUserName(taskOutRequest.getUserName()); + vehicleOutTask.setOrigin(stock.getLocationId()); + vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); + vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); + vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); + vehicleOutTask.setCreateTime(LocalDateTime.now()); + // TODO 设定物料相关信息 需要完善 + TaskDetailInfo taskDetailInfo = new TaskDetailInfo(); + taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId()); + taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName()); + taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum); + taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum()); + vehicleOutTask.setGoodsRelated(taskDetailInfo); + goodsOutTasks.add(vehicleOutTask); + needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum()); + } else if (Objects.equals(stock.getStockStatus(), StockStatus.OUT.getCode())) { + // 查询到当前当前载具对应的任务,并同步 + Task sameVehicleTask = taskService.getOne(new LambdaQueryWrapper() + .eq(Task::getVehicleId, stock.getVehicleId())); + // 创建出库任务 + Task vehicleOutTask = new Task(); + vehicleOutTask.setTaskId(generateId("CK_")); + vehicleOutTask.setTaskType(TaskType.OUT.getCode()); + if (sameVehicleTask != null) { + vehicleOutTask.setTaskGroup(sameVehicleTask.getTaskGroup()); + vehicleOutTask.setTaskStatus(sameVehicleTask.getTaskStatus()); + vehicleOutTask.setTaskPriority(sameVehicleTask.getTaskPriority()); + vehicleOutTask.setPreTask(sameVehicleTask.getPreTask()); + } else { + vehicleOutTask.setTaskGroup(generateId("")); + vehicleOutTask.setTaskStatus(WmsTaskStatus.NEW.getCode()); + vehicleOutTask.setTaskPriority(1); + } + vehicleOutTask.setVehicleId(stock.getVehicleId()); + vehicleOutTask.setUserName(taskOutRequest.getUserName()); + vehicleOutTask.setOrigin(stock.getLocationId()); + vehicleOutTask.setDestination(taskOutRequest.getDestinationPoint()); + vehicleOutTask.setIsPicking(taskOutRequest.getIsPicking()); + vehicleOutTask.setPickStand(taskOutRequest.getPickStand()); + vehicleOutTask.setCreateTime(LocalDateTime.now()); + // TODO 设定物料相关信息 需要完善 + TaskDetailInfo taskDetailInfo = new TaskDetailInfo(); + taskDetailInfo.setGoodsId(stock.getGoodsRelated().getGoodsId()); + taskDetailInfo.setGoodsName(stock.getGoodsRelated().getGoodsName()); + taskDetailInfo.setOpNum(needNum.compareTo(stock.getGoodsRelated().getRemainNum()) > 0 ? stock.getGoodsRelated().getRemainNum() : needNum); + taskDetailInfo.setOriginNum(stock.getGoodsRelated().getRemainNum()); + vehicleOutTask.setGoodsRelated(taskDetailInfo); + goodsOutTasks.add(vehicleOutTask); + needNum = needNum.subtract(stock.getGoodsRelated().getRemainNum()); + } + // 盘点,移库,锁定状态不可使用 + if (needNum.compareTo(BigDecimal.ZERO) <= 0) { + // 库存足够,跳出循环 + break; + } + } + // 添加任务记录表 + taskService.saveBatch(goodsOutTasks); + return ""; + } + +} 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 b5bb0b4..63a5c9f 100644 --- a/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java +++ b/src/main/java/com/wms/service/business/serviceImplements/WorkServiceImplements.java @@ -2,10 +2,7 @@ package com.wms.service.business.serviceImplements; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.wms.constants.enums.StockStatus; -import com.wms.constants.enums.TaskType; -import com.wms.constants.enums.VehicleStatus; -import com.wms.constants.enums.WmsTaskStatus; +import com.wms.constants.enums.*; import com.wms.entity.app.dto.WorkCenterAndOrderDto; import com.wms.entity.app.dto.extend.StockDetailInfo; import com.wms.entity.table.*; @@ -215,7 +212,7 @@ public class WorkServiceImplements implements IWorkService { outsideVehiclesService.updateBatchById(usedOutsideVehiclesList); // 生成拣选任务 List vehicleIds = usedOutsideVehiclesList.stream().map(OutsideVehicles::getVehicleId).toList(); - createPickTasks(vehicleIds, workStation); + createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.NEW.getCode()); } // 判断此时需求数量是否为0 if (needNum.compareTo(BigDecimal.ZERO) <= 0) { @@ -408,6 +405,7 @@ public class WorkServiceImplements implements IWorkService { tempOutTask.setOrigin(tempStock.getLocationId()); tempOutTask.setDestination(""); tempOutTask.setCreateTime(LocalDateTime.now()); + tempOutTask.setIsPicking(1); outTasks.add(tempOutTask); // 添加载具列表 vehicleIds.add(tempStock.getVehicleId()); @@ -453,15 +451,19 @@ public class WorkServiceImplements implements IWorkService { // 保存流转箱信息 outsideVehiclesService.saveBatch(outsideVehicles); // 保存拣选任务至拣选任务表 - createPickTasks(vehicleIds, workStation); + createPickTasks(vehicleIds, workStation, PickTaskStatusEnum.TEMP.getCode()); } /** * 生成拣选任务 * @param vehicleIds 载具列表 * @param workStation 工作站台 + * @param pickStatus 任务状态:只接受-1、0。-1:暂存不发送,0:可发送 */ - private void createPickTasks(List vehicleIds, String workStation) { + private void createPickTasks(List vehicleIds, String workStation, Integer pickStatus) { + if (!Objects.equals(pickStatus, PickTaskStatusEnum.TEMP.getCode()) && !Objects.equals(pickStatus, PickTaskStatusEnum.NEW.getCode())) { + return; + } // 拣选任务暂存列表 List pickTasks = new ArrayList<>(); vehicleIds.forEach(vehicleId -> { @@ -470,7 +472,7 @@ public class WorkServiceImplements implements IWorkService { tempPickTask.setPickTaskId(generateId("PICK_")); tempPickTask.setVehicleId(vehicleId); tempPickTask.setStandId(workStation); - tempPickTask.setPickStatus(0); + tempPickTask.setPickStatus(pickStatus); tempPickTask.setLastUpdateTime(LocalDateTime.now()); pickTasks.add(tempPickTask); }); diff --git a/src/main/java/com/wms/webSocket/client/WebSocketClient.java b/src/main/java/com/wms/webSocket/client/WebSocketClient.java new file mode 100644 index 0000000..236b848 --- /dev/null +++ b/src/main/java/com/wms/webSocket/client/WebSocketClient.java @@ -0,0 +1,19 @@ +package com.wms.webSocket.client; + +import jakarta.websocket.Session; +import lombok.Data; + +/** + * + */ +@Data +public class WebSocketClient { + /** + * 连接会话 + */ + private Session session; + /** + * 连接uri + */ + private String uri; +} diff --git a/src/main/java/com/wms/webSocket/config/WebSocketConfig.java b/src/main/java/com/wms/webSocket/config/WebSocketConfig.java new file mode 100644 index 0000000..8766741 --- /dev/null +++ b/src/main/java/com/wms/webSocket/config/WebSocketConfig.java @@ -0,0 +1,16 @@ +package com.wms.webSocket.config; + +import org.springframework.boot.SpringBootConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.web.socket.server.standard.ServerEndpointExporter; + +/** + * ws配置类 + */ +@SpringBootConfiguration +public class WebSocketConfig { + @Bean + public ServerEndpointExporter serverEndpointExporter(){ + return new ServerEndpointExporter(); + } +} diff --git a/src/main/java/com/wms/webSocket/service/WebSocketService.java b/src/main/java/com/wms/webSocket/service/WebSocketService.java new file mode 100644 index 0000000..de18d9c --- /dev/null +++ b/src/main/java/com/wms/webSocket/service/WebSocketService.java @@ -0,0 +1,12 @@ +package com.wms.webSocket.service; + +import jakarta.websocket.server.ServerEndpoint; +import org.springframework.stereotype.Component; + +/** + * ws服务 + */ +@ServerEndpoint(value = "/websocket/{userName}") +@Component +public class WebSocketService { +}