From 0e5b01739c74338322ad57ebdc6ee75b60e3e84f Mon Sep 17 00:00:00 2001 From: btobab Date: Tue, 23 Sep 2025 21:59:47 +0800 Subject: [PATCH] =?UTF-8?q?1.=20=E5=B0=8F=E5=B9=85=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=89=98=E7=9B=98=E5=BA=93=E7=9A=84=E5=85=A5=E5=BA=93=E6=B5=81?= =?UTF-8?q?=E7=A8=8B=EF=BC=8C=E4=B8=8E=E4=B8=8A=E5=B1=82=E5=95=86=E9=87=8F?= =?UTF-8?q?=E5=90=8E=E6=94=B9=E4=B8=BA=E5=85=88=E8=B0=83=E7=94=A8query?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3=E6=9F=A5=E8=AF=A2=E6=98=AF=E5=90=A6=E5=8F=AF?= =?UTF-8?q?=E4=B8=8A=E6=96=99=EF=BC=8C=E5=8F=AF=E4=B8=8A=E6=96=99=E6=89=8D?= =?UTF-8?q?=E8=83=BD=E8=B0=83=E7=94=A8orderIn=E6=8E=A5=E5=8F=A3=EF=BC=8C?= =?UTF-8?q?=E4=B9=8B=E5=90=8E=E8=BD=AE=E8=AF=A2agvDone=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=EF=BC=8C=E7=9B=B4=E5=88=B0=E8=BF=94=E5=9B=9E0=EF=BC=8C?= =?UTF-8?q?=E5=8D=B3=E5=85=A5=E5=BA=93=E8=AE=A2=E5=8D=95=E7=8A=B6=E6=80=81?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AE=8C=E6=88=90=EF=BC=8C=E5=B0=86=E5=85=A5?= =?UTF-8?q?=E5=BA=93=E4=BB=BB=E5=8A=A1=E6=8E=A8=E9=80=81wcs=E5=85=A5?= =?UTF-8?q?=E5=BA=93=202.=20=E5=88=A0=E9=99=A4=E6=89=98=E7=9B=98=E5=BA=93?= =?UTF-8?q?=E5=92=8C=E6=96=99=E7=AE=B1=E5=BA=93=E7=9A=84=E8=B5=84=E6=BA=90?= =?UTF-8?q?=E9=94=81=E6=8F=92=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api-tests/MyWmsController.http | 60 +-- .../api-tests/TaskController.http | 60 --- .../wms_main/repository/http/HttpClient.java | 14 +- .../api/serviceImpl/WcsApiServiceImpl.java | 2 - .../service/business/IAgvLockService.java | 52 --- .../serviceImpl/AgvLockServiceImpl.java | 232 --------- .../serviceImpl/StackerTaskServiceImpl.java | 157 ++++--- .../MyWmsControllerServiceImpl.java | 24 - .../quartz_job/job_executor/MyInExecutor.java | 97 ++++ .../job_executor/WcsStackerTaskSender.java | 34 +- .../src/main/resources/application.yml | 2 +- .../api-tests/MyWmsController.http | 18 +- .../constant/enums/wms/OrderStatusEnum.java | 1 + .../controller/mywms/MyWmsController.java | 5 +- .../model/dto/request/mywms/AGVDoneReq.java | 11 + .../service/business/IAgvLockService.java | 109 ----- .../serviceImpl/AgvLockServiceImpl.java | 442 ------------------ .../serviceImpl/StackerTaskServiceImpl.java | 5 - .../controller/IMyWmsControllerService.java | 3 +- .../MyWmsControllerServiceImpl.java | 54 +-- .../job_executor/WcsStackerTaskSender.java | 33 -- .../src/main/resources/application.yml | 12 +- 22 files changed, 266 insertions(+), 1161 deletions(-) delete mode 100644 202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/TaskController.http delete mode 100644 202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java delete mode 100644 202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java create mode 100644 202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/MyInExecutor.java create mode 100644 202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/model/dto/request/mywms/AGVDoneReq.java delete mode 100644 202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java delete mode 100644 202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/MyWmsController.http b/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/MyWmsController.http index 6538bc2..22013a9 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/MyWmsController.http +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/MyWmsController.http @@ -1,14 +1,14 @@ ### MyWMS接口测试 ### 基础配置 -@baseUrl = http://localhost:12315 +@baseUrl = http://localhost:12325 ### 1. 入库订单接口 POST {{baseUrl}}/mywms/orderIn Content-Type: application/json { - "taskId": "testOrderId9", - "vehicleNo": "1002" + "taskId": "testId1", + "vehicleNo": "1001" } ### 2. 出库订单接口 @@ -16,54 +16,18 @@ POST {{baseUrl}}/mywms/orderOut Content-Type: application/json { - "taskId": "testOrderId1", + "taskId": "testId1", "vehicleNo": "1002" } -### 3. 库存查询接口 - 仅按载具查询 -POST {{baseUrl}}/mywms/stock +### 3. 发送任务结果 - 任务完成 +POST {{baseUrl}}/wms/task/sendTaskResult Content-Type: application/json { - "requestId": "testOrderId1", - "details": [ - { - "vehicleNo": "1002" - } - ] -} - -### 4. 库存查询接口 - 仅按库位查询 -POST {{baseUrl}}/mywms/stock -Content-Type: application/json - -{ - "requestId": "testOrderId2", - "details": [ - { - "locationId": "A02-01-02-02" - } - ] -} - -### 5. 检查是否允许投料 -GET {{baseUrl}}/mywms/allowFeed - -### 6. 允许出库 -GET {{baseUrl}}/mywms/allowOut - -### 测试数据说明 -# 1. orderIn: 入库订单接口,需要taskId和vehicleNo -# 2. orderOut: 出库订单接口,需要taskId和vehicleNo -# 3. stock: 库存查询接口,需要requestId和details数组 -# - details中可以包含vehicleNo和/或locationId -# 4. allowFeed: 查询当前系统是否允许投料操作(GET请求) - -### 响应格式说明 -# 所有接口都返回MyWmsResponse格式: -# { -# "code": 200, // 响应码 -# "message": "操作成功", // 响应消息 -# "data": {}, // 具体数据 -# "success": true // 是否成功 -# } \ No newline at end of file + "taskId": "1758635063394010001", + "taskStatus": 100, + "vehicleNo": "1009", + "destination": "CR", + "message": "任务执行成功" +} \ No newline at end of file diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/TaskController.http b/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/TaskController.http deleted file mode 100644 index d0d0e46..0000000 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/api-tests/TaskController.http +++ /dev/null @@ -1,60 +0,0 @@ -### TaskController接口测试 - WMS任务控制接口 -### 基础配置 -@baseUrl = http://localhost:12315 - -### 1. WCS请求载具入库 -POST {{baseUrl}}/wms/task/wcsRequestVehicleIn -Content-Type: application/json - -{ - "origin": "CR", - "vehicleNo": "1002", - "codeMessage": "test", - "remark": "载具入库测试" -} - -### 2. 发送任务结果 - 任务完成 -POST {{baseUrl}}/wms/task/sendTaskResult -Content-Type: application/json - -{ - "taskId": "1756881794848010000", - "taskStatus": 100, - "vehicleNo": "1009", - "destination": "CR", - "message": "任务执行成功" -} - -### 测试数据说明 -# 1. wcsRequestVehicleIn: WCS请求载具入库 -# - origin: 点位(必填) -# - vehicleNo: 载具信息(必填) -# - codeMessage: 条码信息(可选) -# - remark: 备注(可选) - -# 2. sendTaskResult: WCS反馈任务执行结果 -# - taskId: 任务ID(必填) -# - taskStatus: 任务状态(必填) -# * 0: 等待执行 -# * 1: 执行中 -# * 2: 执行完成 -# * 3: 执行失败 -# - vehicleNo: 载具号(必填) -# - destination: 终点(可选) -# - message: 信息(可选) - -### 响应格式说明 -# wcsRequestVehicleIn返回WcsVehicleInResponse: -# { -# "success": true, -# "code": "SUCCESS", -# "message": "请求成功", -# "data": {} -# } - -# sendTaskResult返回BaseWcsApiResponse: -# { -# "success": true, -# "code": "SUCCESS", -# "message": "任务结果接收成功" -# } \ No newline at end of file diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/repository/http/HttpClient.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/repository/http/HttpClient.java index ca9d25e..2f9b646 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/repository/http/HttpClient.java +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/repository/http/HttpClient.java @@ -90,6 +90,7 @@ public class HttpClient { /** * 发送一个 Post 请求 + * * @param request 请求数据 * @return 响应数据 */ @@ -97,14 +98,14 @@ public class HttpClient { log.info("请求信息{}", StringUtils.objectToString(request)); HttpResponse response = new HttpResponse(); String url = request.getUrl(); - if(StringUtils.isEmpty(url)) { + if (StringUtils.isEmpty(url)) { // 请求地址没传 response.setSuccess(false); response.setResponseCode(999); response.setException(new Exception("请求地址为空")); return response; } - if(StringUtils.isEmpty(request.getData())) { + if (StringUtils.isEmpty(request.getData())) { request.setData("{}"); } response.setRequestUrl(url); @@ -113,11 +114,12 @@ public class HttpClient { CloseableHttpClient httpClient = HttpClientBuilder.create().build(); HttpPost postRequest = new HttpPost(url); postRequest.setHeader("Content-Type", request.getContentType()); - postRequest.setHeader("Authorization", request.getToken()); + postRequest.setHeader("Expect", "100-continue"); + // postRequest.setHeader("Authorization", request.getToken()); // 设置请求头 - for(Map.Entry entry : request.getHeader().entrySet()){ - postRequest.setHeader(entry.getKey(), entry.getValue()); - } + // for(Map.Entry entry : request.getHeader().entrySet()){ + // postRequest.setHeader(entry.getKey(), entry.getValue()); + // } postRequest.setEntity(new StringEntity(request.getData())); RequestConfig requestConfig = RequestConfig.custom() .setConnectTimeout(request.getTimeout()) diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/api/serviceImpl/WcsApiServiceImpl.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/api/serviceImpl/WcsApiServiceImpl.java index ecd186d..bd3dd8e 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/api/serviceImpl/WcsApiServiceImpl.java +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/api/serviceImpl/WcsApiServiceImpl.java @@ -46,7 +46,6 @@ public class WcsApiServiceImpl implements IWcsApiService { // response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class)); // return response; // } - // TODO success -> error return WcsApiResponse.success("请求未获得响应信息。", null); } @@ -116,7 +115,6 @@ public class WcsApiServiceImpl implements IWcsApiService { // response = httpResponse.getData(response.getClass().asSubclass(WcsApiResponse.class)); // return response; // } - // TODO error -> success // return WcsApiResponse.error("请求未获得响应信息。", null); WcsCanFeedResponse wcsCanFeedResponse = new WcsCanFeedResponse(); wcsCanFeedResponse.setResponseTime(LocalDateTime.now()); diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java deleted file mode 100644 index d45dba5..0000000 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.wms_main.service.business; - -import com.wms_main.model.po.TAppAgvLock; - -/** - * 入库口互锁服务接口 - * 管理单一入库口的AGV上料互锁机制 - */ -public interface IAgvLockService { - - /** - * AGV就位并放货后,锁定入库口 - * @param agvId AGV设备ID - * @param inboundPort 入库口编号 - * @return 锁定结果:成功返回锁定记录,失败返回null - */ - TAppAgvLock lockInboundPort(String agvId, String inboundPort); - - /** - * 检查入库口是否可以上料(MES系统调用) - * @param inboundPort 入库口编号 - * @return 是否可以上料 - */ - boolean canFeedToInboundPort(String inboundPort); - - /** - * 获取当前入库口处理中的任务数量 - * @param inboundPort 入库口编号 - * @return 处理中的任务数量 - */ - int getProcessingTaskCount(String inboundPort); - - /** - * 获取入库口状态描述 - * @param inboundPort 入库口编号 - * @return 状态描述(空闲/占用) - */ - String getInboundPortStatus(String inboundPort); - - /** - * 清理超时锁定 - * @return 清理的记录数 - */ - int cleanTimeoutLocks(); - - /** - * 释放指定入库口的所有活动锁定 - * @param inboundPort 入库口编号 - * @return 释放的锁定数量 - */ - int releaseAllInboundPortLocks(String inboundPort); -} \ No newline at end of file diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java deleted file mode 100644 index 51187c5..0000000 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java +++ /dev/null @@ -1,232 +0,0 @@ -package com.wms_main.service.business.serviceImpl; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.wms_main.constant.enums.wms.WmsAgvLockEnums; -import com.wms_main.dao.ITAppAgvLockService; -import com.wms_main.dao.ITAppTaskService; -import com.wms_main.model.po.TAppAgvLock; -import com.wms_main.model.po.TAppTask; -import com.wms_main.constant.enums.wms.WmsTaskTypeEnums; -import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums; -import com.wms_main.repository.utils.StringUtils; -import com.wms_main.repository.utils.UUIDUtils; -import com.wms_main.service.business.IAgvLockService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.List; - -/** - * 入库口互锁服务实现 - * 管理单一入库口的AGV上料互锁机制 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class AgvLockServiceImpl implements IAgvLockService { - - private final ITAppAgvLockService agvLockService; - private final ITAppTaskService appTaskService; - - private static final String DEFAULT_INBOUND_PORT = "R1"; // 默认入库口 - private static final int DEFAULT_TIMEOUT_SECONDS = 600; // 默认超时时间10分钟 - - @Override - @Transactional - public TAppAgvLock lockInboundPort(String agvId, String inboundPort) { - if (StringUtils.isEmpty(agvId)) { - log.warn("AGV ID为空"); - return null; - } - - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查入库口是否已被占用 - List existingLocks = agvLockService.list(new LambdaQueryWrapper().eq(TAppAgvLock::getFeedStation, inboundPort)); - if (existingLocks == null || existingLocks.isEmpty()) { - return createInboundPortLock(agvId, inboundPort); - } else { - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, inboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "AGV就位并放货,锁定入库口") - ); - return null; - } - } - - @Override - public boolean canFeedToInboundPort(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查入库口是否有活动的锁定 - List activeLocks = agvLockService.getByStation(inboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - log.debug("入库口 {} 当前被占用,无法上料", inboundPort); - return false; - } - - // 检查是否有正在处理的入库任务 - int processingTasks = getProcessingTaskCount(inboundPort); - boolean canFeed = processingTasks == 0; - - log.debug("入库口 {} 可上料状态: {}, 处理中任务数: {}", inboundPort, canFeed, processingTasks); - return canFeed; - } - - @Override - public int getProcessingTaskCount(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 统计正在处理的入库任务数量(包括等待、运行状态的任务) - List processingTasks = appTaskService.list( - new LambdaQueryWrapper() - .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()) - .in(TAppTask::getTaskStatus, - WmsStackerTaskStatusEnums.WAIT.getCode(), - WmsStackerTaskStatusEnums.RUN.getCode()) - .like(TAppTask::getOrigin, inboundPort) // 假设任务来源包含入库口信息 - ); - - return processingTasks.size(); - } - - @Override - public String getInboundPortStatus(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 检查是否有活动锁定 - List activeLocks = agvLockService.getByStation(inboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - return "占用"; - } - - // 检查是否有处理中的任务 - int processingTasks = getProcessingTaskCount(inboundPort); - if (processingTasks > 0) { - return "占用"; - } - - return "空闲"; - } - - @Override - @Transactional - public int cleanTimeoutLocks() { - List timeoutLocks = agvLockService.getTimeoutLocks(); - if (timeoutLocks.isEmpty()) { - return 0; - } - - try { - for (TAppAgvLock lock : timeoutLocks) { - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getLockId, lock.getLockId()) - .set(TAppAgvLock::getLockStatus, 0) - .set(TAppAgvLock::getUnlockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "超时自动释放") - ); - - log.info("释放超时锁定: AGV {} 在入库口 {}", lock.getAgvId(), lock.getFeedStation()); - } - - log.info("清理了 {} 个超时锁定", timeoutLocks.size()); - return timeoutLocks.size(); - } catch (Exception e) { - log.error("清理超时锁定失败", e); - return 0; - } - } - - @Override - @Transactional - public int releaseAllInboundPortLocks(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - try { - // 释放指定入库口的所有活动锁定 - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, inboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getUnlockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "入库任务完成,批量释放锁定") - ); - - // 查询实际释放的锁定数量 - List activeLocks = agvLockService.getByStation(inboundPort); - int releasedCount = (int) activeLocks.stream() - .filter(lock -> lock.getLockStatus() == 0) - .count(); - - log.info("释放入库口 {} 的所有锁定,共释放 {} 个锁定", inboundPort, releasedCount); - return releasedCount; - } catch (Exception e) { - log.error("释放入库口 {} 的所有锁定失败", inboundPort, e); - return 0; - } - } - - /** - * 创建入库口锁定记录 - */ - private TAppAgvLock createInboundPortLock(String agvId, String inboundPort) { - TAppAgvLock lock = new TAppAgvLock(); - lock.setLockId(UUIDUtils.getNewUUID()); - lock.setAgvId(agvId); - lock.setFeedStation(inboundPort); - lock.setLockStatus(1); - lock.setLockType("INBOUND_PORT_LOCK"); - lock.setPriority(1); - lock.setQueuePosition(1); - lock.setLockTime(LocalDateTime.now()); - lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS); - lock.setCreateTime(LocalDateTime.now()); - lock.setUpdateTime(LocalDateTime.now()); - lock.setRemark("AGV就位并放货,锁定入库口"); - - if (agvLockService.save(lock)) { - log.info("AGV {} 成功锁定入库口 {}", agvId, inboundPort); - return lock; - } - - log.error("AGV {} 锁定入库口 {} 失败", agvId, inboundPort); - return null; - } -} \ No newline at end of file diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java index 999952e..c161e7b 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java @@ -9,12 +9,12 @@ import com.wms_main.constant.enums.wms.*; import com.wms_main.dao.*; import com.wms_main.model.dto.request.mywms.OrderInCBReq; import com.wms_main.model.dto.request.mywms.OrderOutCBReq; +import com.wms_main.model.dto.response.mes.MesApiResponse; import com.wms_main.model.po.*; import com.wms_main.repository.utils.ConvertUtils; import com.wms_main.repository.utils.StringUtils; import com.wms_main.repository.utils.UUIDUtils; import com.wms_main.service.api.IExternalApiService; -import com.wms_main.service.business.IAgvLockService; import com.wms_main.service.business.IStackerTaskService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -25,7 +25,6 @@ import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; - /** * 服务实现 */ @@ -73,8 +72,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { */ private final AppCommon appCommon; - private final IAgvLockService agvLockService; - /** * 存WcsTask表 * 更新WmsTask表 @@ -92,9 +89,9 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .set(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId()) .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.EXECUTED.getCode()) .eq(TAppTask::getVehicleId, wcsTask.getVehicleId()) - .eq(TAppTask::getTaskType, ConvertUtils.convertStackerTaskTypeFromWcsToWms(wcsTask.getWcsTaskType())) - .eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.WAIT.getCode()) - ); + .eq(TAppTask::getTaskType, + ConvertUtils.convertStackerTaskTypeFromWcsToWms(wcsTask.getWcsTaskType())) + .eq(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.WAIT.getCode())); } /** @@ -131,33 +128,36 @@ public class StackerTaskServiceImpl implements IStackerTaskService { // 查询库位 List locationList = appLocationService.list(queryWrapper); List candidateLocationList = locationList.stream().filter(item -> { - boolean filterResult = item.getIsWorking() == 0 && item.getIsLock() == 0 && item.getIsOccupy() == 0; - if (locationFilter != null) { - if (locationFilter.getLRow() != null) { - filterResult = filterResult && Objects.equals(item.getLRow(), locationFilter.getLRow()); - } - if (locationFilter.getLCol() != null) { - filterResult = filterResult && Objects.equals(item.getLCol(), locationFilter.getLCol()); - } - if (locationFilter.getLLayer() != null) { - filterResult = filterResult && Objects.equals(item.getLLayer(), locationFilter.getLLayer()); - } - } - return filterResult; - }).sorted(Comparator.comparingInt(TAppLocation::getLDepth).reversed()) + boolean filterResult = item.getIsWorking() == 0 && item.getIsLock() == 0 && item.getIsOccupy() == 0; + if (locationFilter != null) { + if (locationFilter.getLRow() != null) { + filterResult = filterResult && Objects.equals(item.getLRow(), locationFilter.getLRow()); + } + if (locationFilter.getLCol() != null) { + filterResult = filterResult && Objects.equals(item.getLCol(), locationFilter.getLCol()); + } + if (locationFilter.getLLayer() != null) { + filterResult = filterResult && Objects.equals(item.getLLayer(), locationFilter.getLLayer()); + } + } + return filterResult; + }).sorted(Comparator.comparingInt(TAppLocation::getLDepth).reversed()) .sorted(Comparator.comparingInt(location -> location.getLCol() + location.getLLayer())) .toList(); // 判断是否输入了subArea if (locationFilter != null && StringUtils.isNotEmpty(locationFilter.getSubArea())) { // 对candidateLocationList进行排序 - List firstList = candidateLocationList.stream().filter(item -> item.getSubArea().equals(locationFilter.getSubArea())).toList(); - List lastList = candidateLocationList.stream().filter(item -> !item.getSubArea().equals(locationFilter.getSubArea())).toList(); + List firstList = candidateLocationList.stream() + .filter(item -> item.getSubArea().equals(locationFilter.getSubArea())).toList(); + List lastList = candidateLocationList.stream() + .filter(item -> !item.getSubArea().equals(locationFilter.getSubArea())).toList(); candidateLocationList = new ArrayList<>(firstList);// 先添加符合subArea的库位 candidateLocationList.addAll(lastList);// 再添加不符合subArea的库位 } // 找一个空闲的库位 for (TAppLocation candidateLocation : candidateLocationList) { - if (candidateLocation.getIsWorking() == 1 || candidateLocation.getIsLock() == 1 || candidateLocation.getIsOccupy() == 1) { + if (candidateLocation.getIsWorking() == 1 || candidateLocation.getIsLock() == 1 + || candidateLocation.getIsOccupy() == 1) { continue; } if (isMaxDepthAvailable(locationList, candidateLocation)) { @@ -167,8 +167,7 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .set(TAppLocation::getIsOccupy, 1) .set(TAppLocation::getVehicleId, requestVehicleId) .eq(TAppLocation::getLocationId, candidateLocation.getLocationId()) - .eq(TAppLocation::getIsOccupy, 0) - )) { + .eq(TAppLocation::getIsOccupy, 0))) { // 当前库位可用 targetLocation = candidateLocation; break; @@ -193,31 +192,37 @@ public class StackerTaskServiceImpl implements IStackerTaskService { /** * 获取一个堆垛机库的空库位 + * * @param equipmentId 设备号 * @return 返回的库位信息 */ @Override public TAppLocation getEmptyLocation(Integer equipmentId, WmsLocationTypeEnums type) { - if(equipmentId == null) return null; + if (equipmentId == null) + return null; List allLocations = appLocationService.getAllLocation(equipmentId); - if(allLocations == null || allLocations.isEmpty()) return null; + if (allLocations == null || allLocations.isEmpty()) + return null; for (TAppLocation location : allLocations) { - if(location.getIsOccupy() != 0 || location.getIsLock() != 0 || location.getIsWorking() != 0){ + if (location.getIsOccupy() != 0 || location.getIsLock() != 0 || location.getIsWorking() != 0) { continue; // 不可用货位 } - if(type != null && !type.getCode().equals(location.getLocationType())) { + if (type != null && !type.getCode().equals(location.getLocationType())) { continue; } - // 检查内侧深度是否可用 + // 检查内侧深度是否可用 Integer lDepth = location.getLDepth(); - if(lDepth != null && lDepth.compareTo(1) > 0) { + if (lDepth != null && lDepth.compareTo(1) > 0) { boolean canUse = true; - for(int i = lDepth - 1; i > 0; i--) { + for (int i = lDepth - 1; i > 0; i--) { int checkDepth = i; - List sameColLocations = allLocations.stream().filter(item -> - item.getLRow().equals(location.getLRow()) && item.getLCol().equals(location.getLCol()) - && item.getLLayer().equals(location.getLLayer()) && item.getLDepth().equals(checkDepth)).toList(); - if(sameColLocations.isEmpty()) { + List sameColLocations = allLocations.stream() + .filter(item -> item.getLRow().equals(location.getLRow()) + && item.getLCol().equals(location.getLCol()) + && item.getLLayer().equals(location.getLLayer()) + && item.getLDepth().equals(checkDepth)) + .toList(); + if (sameColLocations.isEmpty()) { continue; // 库位不存在可能 } TAppLocation sameColLocationsFirst = sameColLocations.getFirst(); @@ -225,26 +230,26 @@ public class StackerTaskServiceImpl implements IStackerTaskService { TAppStock checkIsHaveStock = new TAppStock(); checkIsHaveStock.setLocationId(sameColLocationsFirst.getLocationId()); List checkStockIsHaveStockResult = appStockService.getWithEntity(checkIsHaveStock); - if(checkStockIsHaveStockResult == null) { + if (checkStockIsHaveStockResult == null) { canUse = false; // 数据库查询失败,库位直接不可用 break; } - if(!checkStockIsHaveStockResult.isEmpty()) { + if (!checkStockIsHaveStockResult.isEmpty()) { canUse = false; // 库位有库存,不可用 break; } // 校验是否存在出入库任务 Boolean existsTaskWithLocation = appWcsTaskService.existsTaskWithLocation(location.getLocationId()); - if(existsTaskWithLocation == null) { + if (existsTaskWithLocation == null) { canUse = false; break; } - if(existsTaskWithLocation) { + if (existsTaskWithLocation) { canUse = false; // 库位有任务,不可用 break; } } - if(!canUse) { + if (!canUse) { continue; // 不可用 } return location; @@ -273,11 +278,12 @@ public class StackerTaskServiceImpl implements IStackerTaskService { return false; } // 查询到排列层对应的库位列表 - List diffDepthLocationList = appLocationList.stream().filter(item -> - Objects.equals(item.getLRow(), appLocation.getLRow()) && + List diffDepthLocationList = appLocationList.stream() + .filter(item -> Objects.equals(item.getLRow(), appLocation.getLRow()) && Objects.equals(item.getLCol(), appLocation.getLCol()) && Objects.equals(item.getLLayer(), appLocation.getLLayer()) && - !Objects.equals(item.getLDepth(), appLocation.getLDepth())).toList(); + !Objects.equals(item.getLDepth(), appLocation.getLDepth())) + .toList(); // 结果 boolean result = true; for (TAppLocation diffDepthLocation : diffDepthLocationList) { @@ -324,20 +330,24 @@ public class StackerTaskServiceImpl implements IStackerTaskService { // 查找到所有的入库任务列表---非暂存和完成状态。 List inTasks = appTaskService.list(new LambdaQueryWrapper() .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()) - .notIn(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode(), WmsStackerTaskStatusEnums.TEMP.getCode())); + .notIn(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.FINISH.getCode(), + WmsStackerTaskStatusEnums.TEMP.getCode())); if (inTasks == null || inTasks.isEmpty()) { for (TAppLocation appLocation : emptyLocationList) { if (equipCountMap.containsKey(appLocation.getEquipmentId())) { - equipCountMap.replace(appLocation.getEquipmentId(), equipCountMap.get(appLocation.getEquipmentId()) + 1); + equipCountMap.replace(appLocation.getEquipmentId(), + equipCountMap.get(appLocation.getEquipmentId()) + 1); } } } else { for (TAppTask inTask : inTasks) { if (StringUtils.isNotEmpty(inTask.getDestination())) { // 当前目标库位的设备号 - TAppLocation destinationEquipmentId = appCommon.getInstantLocationByLocationId(inTask.getDestination()); + TAppLocation destinationEquipmentId = appCommon + .getInstantLocationByLocationId(inTask.getDestination()); if (equipCountMap.containsKey(destinationEquipmentId.getEquipmentId())) { - equipCountMap.replace(destinationEquipmentId.getEquipmentId(), equipCountMap.get(destinationEquipmentId.getEquipmentId()) + 1); + equipCountMap.replace(destinationEquipmentId.getEquipmentId(), + equipCountMap.get(destinationEquipmentId.getEquipmentId()) + 1); } } } @@ -352,7 +362,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .toList(); } - /** * 实现 * @@ -393,25 +402,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .eq(TAppStock::getVehicleId, orderIn.getVehicleNo())); } - OrderInCBReq orderInCBReq = new OrderInCBReq(); - orderInCBReq.setTaskId(orderIn.getOrderId()); - orderInCBReq.setVehicleNo(wmsTask.getVehicleId()); - orderInCBReq.setLocationId(wmsTask.getDestination()); - orderInCBReq.setResult(OrderInCBEnums.COMPLETE.getCode()); - orderInCBReq.setResultMessage("入库完成"); - - // int times = 0; - // MesApiResponse response = null; - // do { - // Thread.sleep(15000L * times); - // response = externalApiService.invokeOrderInCB(orderInCBReq); - // times++; - // } while (response.getCode() != 0 && times <= 10); - // if (response.getCode() != 0) { - // log.error("[wms]上报失败"); - // } else { - // log.info("[wms]上报成功"); - // } if (!appOrderInService.removeById(orderIn.getRecordId())) { log.info("整箱入库完成删除入库单失败,任务:{},原因:删除入库单失败", wmsTask.getTaskId()); } @@ -424,7 +414,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { appVehicleService.saveOrUpdate(vehicle); appCommon.updateWorkingLocations(wmsTask.getDestination(), 0); - agvLockService.releaseAllInboundPortLocks("CR"); // 备份并删除任务 if (!appTaskService.removeById(wmsTask.getTaskId())) { log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId()); @@ -432,6 +421,24 @@ public class StackerTaskServiceImpl implements IStackerTaskService { if (!appTaskBakService.save(wmsTask.of())) { log.info("备份入库任务失败,任务:{}", wmsTask.getTaskId()); } + // OrderInCBReq orderInCBReq = new OrderInCBReq(); + // orderInCBReq.setTaskId(orderIn.getOrderId()); + // orderInCBReq.setVehicleNo(wmsTask.getVehicleId()); + // orderInCBReq.setLocationId(wmsTask.getDestination()); + // orderInCBReq.setResult(OrderInCBEnums.COMPLETE.getCode()); + // orderInCBReq.setResultMessage("入库完成"); + // int times = 0; + // MesApiResponse response = null; + // do { + // Thread.sleep(15000L * times); + // response = externalApiService.invokeOrderInCB(orderInCBReq); + // times++; + // } while (response.getCode() != 0 && times <= 10); + // if (response.getCode() != 0) { + // log.error("[wms]上报失败"); + // } else { + // log.info("[wms]上报成功"); + // } } } @@ -449,16 +456,14 @@ public class StackerTaskServiceImpl implements IStackerTaskService { appStockService.update(new LambdaUpdateWrapper() .in(TAppStock::getStockId, thisVehicleStocks.stream().map(TAppStock::getStockId).toList()) .set(TAppStock::getLocationId, wmsTask.getDestination()) - .set(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()) - ); + .set(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode())); appLocationService.update(new LambdaUpdateWrapper() .eq(TAppLocation::getLocationId, wmsTask.getOrigin()) .set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode()) .set(TAppLocation::getVehicleId, "")); appVehicleService.update(new LambdaUpdateWrapper() .eq(TAppVehicle::getVehicleId, wmsTask.getVehicleId()) - .set(TAppVehicle::getLocationId, wmsTask.getDestination()) - ); + .set(TAppVehicle::getLocationId, wmsTask.getDestination())); appCommon.updateWorkingLocations(wmsTask.getDestination(), 0); appCommon.updateWorkingLocations(wmsTask.getOrigin(), 0); appTaskService.removeById(wmsTask.getTaskId()); @@ -482,7 +487,8 @@ public class StackerTaskServiceImpl implements IStackerTaskService { // 5. 添加出库记录 // 根据载具号map一下 Map> vehicleIdToTaskMap = stackerOutTasks.stream() - .filter(outTask -> Objects.equals(outTask.getTaskType(), WmsTaskTypeEnums.OUT.getCode()) && Objects.equals(outTask.getTaskStatus(), WmsStackerTaskStatusEnums.FINISH.getCode())) + .filter(outTask -> Objects.equals(outTask.getTaskType(), WmsTaskTypeEnums.OUT.getCode()) + && Objects.equals(outTask.getTaskStatus(), WmsStackerTaskStatusEnums.FINISH.getCode())) .collect(Collectors.groupingBy(TAppTask::getVehicleId)); for (String vehicleId : vehicleIdToTaskMap.keySet()) { // 查询当前载具的数据 @@ -515,7 +521,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode()) .set(TAppStock::getLocationId, "") .eq(TAppStock::getVehicleId, vehicleId)); - agvLockService.releaseAllInboundPortLocks("CR"); // 当前载具的任务列表 List thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId); if (thisVehicleOutTasks.isEmpty()) { diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java index e9e1242..79e5735 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java @@ -21,7 +21,6 @@ import com.wms_main.model.po.TAppStock; import com.wms_main.repository.utils.StringUtils; import com.wms_main.repository.utils.UUIDUtils; import com.wms_main.service.api.IWcsApiService; -import com.wms_main.service.business.IAgvLockService; import com.wms_main.service.controller.IMyWmsControllerService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -39,7 +38,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { private final ITAppOrderOutService appOrderOutService; private final ITAppStockService appStockService; private final ITAppLocationService appLocationService; - private final IAgvLockService agvLockService; private final IWcsApiService wcsApiService; @Override @@ -181,17 +179,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { return MyWmsResponse.error("WCS系统查询失败", false); } - Boolean wcsAllow = wcsResponse.getData().isAllowAction(); - if (!wcsAllow) { - return MyWmsResponse.error("WCS系统不允许入库", false); - } - - // 3. 检查agvLock服务获取wms状态 - Boolean wmsAllow = agvLockService.canFeedToInboundPort("CR"); - if (!wmsAllow) { - return MyWmsResponse.error("入库口锁定中", false); - } - return MyWmsResponse.success(true); } catch (Exception e) { return MyWmsResponse.error("系统异常,请稍后重试", false); @@ -207,17 +194,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { return MyWmsResponse.error("WCS系统查询失败", false); } - Boolean wcsAllow = wcsResponse.getData().isAllowAction(); - if (!wcsAllow) { - return MyWmsResponse.error("WCS系统不允许出库", false); - } - - // 2. 检查agvLock服务获取wms状态 (使用CR口) - Boolean wmsAllow = agvLockService.canFeedToInboundPort("CR"); - if (!wmsAllow) { - return MyWmsResponse.error("出库口锁定中", false); - } - return MyWmsResponse.success(true); } catch (Exception e) { return MyWmsResponse.error("系统异常,请稍后重试", false); diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/MyInExecutor.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/MyInExecutor.java new file mode 100644 index 0000000..1e77dec --- /dev/null +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/MyInExecutor.java @@ -0,0 +1,97 @@ +package com.wms_main.service.quartz_job.job_executor; + +import java.time.LocalDateTime; +import java.util.List; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.wms_main.constant.enums.wms.OrderStatusEnum; +import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums; +import com.wms_main.constant.enums.wms.WmsTaskTypeEnums; +import com.wms_main.dao.ITAppOrderInService; +import com.wms_main.dao.ITAppTaskService; +import com.wms_main.model.po.TAppLocation; +import com.wms_main.model.po.TAppOrderIn; +import com.wms_main.model.po.TAppTask; +import com.wms_main.repository.utils.UUIDUtils; +import com.wms_main.service.business.IStackerTaskService; + +import org.quartz.DisallowConcurrentExecution; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.PersistJobDataAfterExecution; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@PersistJobDataAfterExecution +// 以下注解用于实现fixed_delay +@DisallowConcurrentExecution +@RequiredArgsConstructor +public class MyInExecutor implements Job { + private final ITAppOrderInService appOrderInService; + private final IStackerTaskService stackerTaskService; + private final ITAppTaskService appWmsTaskService; + + private static String ORIGIN = "CR"; + + @Override + public void execute(JobExecutionContext context) { + processInOrders(); + } + + private void processInOrders() { + List orders = appOrderInService.list( + new LambdaQueryWrapper() + .eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode())); + orders.forEach(this::processSingleOrder); + } + + private void processSingleOrder(TAppOrderIn orderIn) { + if (orderIn == null) { + return; + } + /* 查找可用库位 */ + TAppLocation useLocation = stackerTaskService.requestOneLocation(null, orderIn.getVehicleNo()); + if (useLocation == null) { + log.error("暂没有可以直接使用的库位,因为存在互锁的库位,请等待当前任务都执行完成后再试"); + return; + } + TAppTask newInTask = appWmsTaskService.getOne(new LambdaQueryWrapper() + .eq(TAppTask::getVehicleId, orderIn.getVehicleNo()) + .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode())); + if (newInTask != null) { + newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode()); + newInTask.setDestination(useLocation.getLocationId()); + newInTask.setTaskGroup(orderIn.getOrderId()); + if (!appWmsTaskService.updateById(newInTask)) { + log.error("生成任务失败,无法插入新的入库任务"); + return; + } + } else { + newInTask = new TAppTask(); + newInTask.setTaskId(UUIDUtils.getNewUUID()); + newInTask.setTaskGroup(orderIn.getOrderId()); + newInTask.setTaskType(WmsTaskTypeEnums.IN.getCode()); + newInTask.setTaskStatus(WmsStackerTaskStatusEnums.WAIT.getCode()); + newInTask.setOrigin(ORIGIN); + newInTask.setDestination(useLocation.getLocationId()); + newInTask.setCreateTime(LocalDateTime.now()); + newInTask.setOpUser("wcs"); + newInTask.setVehicleId(orderIn.getVehicleNo()); + newInTask.setTaskPriority(1); + + if (!appWmsTaskService.save(newInTask)) { + log.error("生成任务失败,无法插入新的入库任务"); + return; + } + } + appOrderInService.update( + new LambdaUpdateWrapper() + .eq(TAppOrderIn::getRecordId, orderIn.getRecordId()) + .set(TAppOrderIn::getOrderStatus, OrderStatusEnum.RUNNING.getCode()) + .set(TAppOrderIn::getUpdateTime, LocalDateTime.now())); + return; + } +} diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java index 1b30e02..1749d94 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java @@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums; import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums; -import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums; import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums; import com.wms_main.dao.ITAppTaskService; import com.wms_main.dao.ITAppWcsTaskService; @@ -15,7 +14,6 @@ import com.wms_main.model.po.TAppTask; import com.wms_main.model.po.TAppWcsTask; import com.wms_main.repository.utils.StringUtils; import com.wms_main.service.api.IWcsApiService; -import com.wms_main.service.business.IAgvLockService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.quartz.*; @@ -43,11 +41,6 @@ public class WcsStackerTaskSender implements Job { * Wcs接口服务 */ private final IWcsApiService wcsApiService; - /** - * AGV锁定服务 - */ - private final IAgvLockService agvLockService; - /** * 运行定时任务 * 向Wcs发送堆垛机任务 @@ -56,10 +49,10 @@ public class WcsStackerTaskSender implements Job { */ @Override public void execute(JobExecutionContext jobExecutionContext) { - if (appWcsTaskService.exists(new LambdaQueryWrapper().eq(TAppWcsTask::getWcsTaskStatus, - WcsStackerTaskStatusEnums.WAIT.getCode()))) { - return; - } + // if (appWcsTaskService.exists(new LambdaQueryWrapper().eq(TAppWcsTask::getWcsTaskStatus, + // WcsStackerTaskStatusEnums.WAIT.getCode()))) { + // return; + // } // 查询到所有的待下发的wcsTask并按优先级排序 List waitSendWcsTaskList = appWcsTaskService.list( new LambdaQueryWrapper() @@ -72,12 +65,6 @@ public class WcsStackerTaskSender implements Job { waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority())); // 发送任务 TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst(); - if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) { - Boolean wmsAllow = agvLockService.canFeedToInboundPort(wcsTask.getDestination()); - if (!wmsAllow) { - return; - } - } // 生成请求 WcsStackerTaskRequest request = new WcsStackerTaskRequest( wcsTask.getWcsTaskId(), @@ -101,19 +88,6 @@ public class WcsStackerTaskSender implements Job { .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode()) .eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId())); - if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) { - try { - agvLockService.lockInboundPort("AGV", wcsTask.getDestination()); - } catch (Exception e) { - log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getDestination(), wcsTask.getWcsTaskId()); - } - } else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) { - try { - agvLockService.lockInboundPort("AGV", wcsTask.getOrigin()); - } catch (Exception e) { - log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getOrigin(), wcsTask.getWcsTaskId()); - } - } } else { log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request), StringUtils.objectToString(wcsResponse)); diff --git a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/resources/application.yml b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/resources/application.yml index c124c2d..3c280d0 100644 --- a/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/resources/application.yml +++ b/202504-Wms-MengYang-box/wms_serve_mengyang/src/main/resources/application.yml @@ -23,7 +23,7 @@ spring: # 服务配置 server: - port: 12315 + port: 12325 servlet: context-path: / diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/api-tests/MyWmsController.http b/202504-Wms-MengYang-tp/wms_serve_mengyang/api-tests/MyWmsController.http index f219dc8..058b5b3 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/api-tests/MyWmsController.http +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/api-tests/MyWmsController.http @@ -8,7 +8,7 @@ Content-Type: application/json { "taskId": "testOrderId1", - "vehicleNo": "1003" + "vehicleNo": "1001" } ### 2. 出库订单接口 @@ -16,8 +16,8 @@ POST {{baseUrl}}/mywms/orderOut Content-Type: application/json { - "taskId": "testOrderId3", - "vehicleNo": "1001" + "taskId": "testOrderId2", + "vehicleNo": "1002" } ### 3. 发送任务结果 - 任务完成 @@ -25,7 +25,7 @@ POST {{baseUrl}}/wms/task/sendTaskResult Content-Type: application/json { - "taskId": "1757666162511010000", + "taskId": "1758595357068010000", "taskStatus": 100, "vehicleNo": "1007", "destination": "C1", @@ -51,7 +51,15 @@ POST {{baseUrl}}/mywms/cancelOrderIn Content-Type: application/json { - "vehicleNo": "1003" + "vehicleNo": "1005" +} + +### 8. AGVDone +POST {{baseUrl}}/mywms/agvDone +Content-Type: application/json + +{ + "taskId": "testOrderId1" } ### 测试数据说明 diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/constant/enums/wms/OrderStatusEnum.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/constant/enums/wms/OrderStatusEnum.java index 0fdb28f..8e9ea90 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/constant/enums/wms/OrderStatusEnum.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/constant/enums/wms/OrderStatusEnum.java @@ -5,6 +5,7 @@ import lombok.Getter; @Getter public enum OrderStatusEnum { + TEMP(-1, "暂存"), CREATE(0, "创建"), RUNNING(1, "运行中"), COMPLETE(2, "完成"), diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/controller/mywms/MyWmsController.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/controller/mywms/MyWmsController.java index 28916fc..c8c81af 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/controller/mywms/MyWmsController.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/controller/mywms/MyWmsController.java @@ -1,5 +1,6 @@ package com.wms_main.controller.mywms; +import com.wms_main.model.dto.request.mywms.AGVDoneReq; import com.wms_main.model.dto.request.mywms.OrderInCancel; import com.wms_main.model.dto.request.mywms.OrderInReq; import com.wms_main.model.dto.request.mywms.OrderOutReq; @@ -49,8 +50,8 @@ public class MyWmsController { } @PostMapping("/agvDone") - public MyWmsResponse agvDone() { - return myWmsControllerService.agvDone(); + public MyWmsResponse agvDone(@RequestBody AGVDoneReq request) { + return myWmsControllerService.agvDone(request); } @PostMapping("/cancelOrderIn") diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/model/dto/request/mywms/AGVDoneReq.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/model/dto/request/mywms/AGVDoneReq.java new file mode 100644 index 0000000..81f3b86 --- /dev/null +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/model/dto/request/mywms/AGVDoneReq.java @@ -0,0 +1,11 @@ +package com.wms_main.model.dto.request.mywms; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Getter; +import lombok.Setter; +@Getter +@Setter +public class AGVDoneReq { + @JsonProperty("taskId") + private String taskId; +} diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java deleted file mode 100644 index 44726c0..0000000 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/IAgvLockService.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.wms_main.service.business; - -import com.wms_main.model.po.TAppAgvLock; - -/** - * AGV资源锁定服务接口 - * 管理入库口和出库口的AGV设备互锁机制 - */ -public interface IAgvLockService { - - /** - * AGV就位并放货后,锁定入库口 - * @param agvId AGV设备ID - * @param inboundPort 入库口编号 - * @return 锁定结果:成功返回锁定记录,失败返回null - */ - TAppAgvLock lockInboundPort(String agvId, String inboundPort); - - /** - * 检查入库口是否可以上料(MES系统调用) - * @param inboundPort 入库口编号 - * @return 是否可以上料 - */ - boolean canFeedToInboundPort(String inboundPort); - - /** - * 获取当前入库口处理中的任务数量 - * @param inboundPort 入库口编号 - * @return 处理中的任务数量 - */ - int getProcessingTaskCount(String inboundPort); - - /** - * 获取入库口状态描述 - * @param inboundPort 入库口编号 - * @return 状态描述(空闲/占用) - */ - String getInboundPortStatus(String inboundPort); - - /** - * 清理超时锁定 - * @return 清理的记录数 - */ - int cleanTimeoutLocks(); - - /** - * 释放指定入库口的所有活动锁定 - * @param inboundPort 入库口编号 - * @return 释放的锁定数量 - */ - int releaseAllInboundPortLocks(String inboundPort); - - // ========== 出库口锁定相关方法 ========== - - /** - * AGV到达出库口后,锁定出库口 - * @param agvId AGV设备ID - * @param outboundPort 出库口编号 - * @return 锁定结果:成功返回锁定记录,失败返回null - */ - TAppAgvLock lockOutboundPort(String agvId, String outboundPort); - - /** - * 检查出库口是否可以出料(MES系统调用) - * @param outboundPort 出库口编号 - * @return 是否可以出料 - */ - boolean canFeedToOutboundPort(String outboundPort); - - /** - * 获取当前出库口处理中的任务数量 - * @param outboundPort 出库口编号 - * @return 处理中的任务数量 - */ - int getProcessingOutTaskCount(String outboundPort); - - /** - * 获取出库口状态描述 - * @param outboundPort 出库口编号 - * @return 状态描述(空闲/占用) - */ - String getOutboundPortStatus(String outboundPort); - - /** - * 释放指定出库口的所有活动锁定 - * @param outboundPort 出库口编号 - * @return 释放的锁定数量 - */ - int releaseAllOutboundPortLocks(String outboundPort); - - // ========== 通用锁定方法 ========== - - /** - * 通用资源锁定方法 - * @param agvId AGV设备ID - * @param stationCode 站台编号(R1=入库口,C1=出库口) - * @param taskType 任务类型(1=入库,2=出库) - * @return 锁定结果:成功返回锁定记录,失败返回null - */ - TAppAgvLock lockStation(String agvId, String stationCode, Integer taskType); - - /** - * 通用资源解锁方法 - * @param stationCode 站台编号(R1=入库口,C1=出库口) - * @param taskType 任务类型(1=入库,2=出库) - * @return 释放的锁定数量 - */ - int releaseStationLocks(String stationCode, Integer taskType); -} \ No newline at end of file diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java deleted file mode 100644 index 6d4af5e..0000000 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/AgvLockServiceImpl.java +++ /dev/null @@ -1,442 +0,0 @@ -package com.wms_main.service.business.serviceImpl; - -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; -import com.wms_main.constant.enums.wms.WmsAgvLockEnums; -import com.wms_main.dao.ITAppAgvLockService; -import com.wms_main.dao.ITAppTaskService; -import com.wms_main.model.po.TAppAgvLock; -import com.wms_main.model.po.TAppTask; -import com.wms_main.constant.enums.wms.WmsTaskTypeEnums; -import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums; -import com.wms_main.repository.utils.StringUtils; -import com.wms_main.repository.utils.UUIDUtils; -import com.wms_main.service.business.IAgvLockService; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.util.List; -import java.util.Objects; - -/** - * AGV资源锁定服务实现 - * 管理入库口和出库口的AGV设备互锁机制 - */ -@Service -@RequiredArgsConstructor -@Slf4j -public class AgvLockServiceImpl implements IAgvLockService { - - private final ITAppAgvLockService agvLockService; - private final ITAppTaskService appTaskService; - - private static final String DEFAULT_INBOUND_PORT = "R1"; // 默认入库口 - private static final String DEFAULT_OUTBOUND_PORT = "C1"; // 默认出库口 - private static final int DEFAULT_TIMEOUT_SECONDS = 600; // 默认超时时间10分钟 - - @Override - @Transactional - public TAppAgvLock lockInboundPort(String agvId, String inboundPort) { - if (StringUtils.isEmpty(agvId)) { - log.warn("AGV ID为空"); - return null; - } - - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查入库口是否已被占用 - List existingLocks = agvLockService.list(new LambdaQueryWrapper().eq(TAppAgvLock::getFeedStation, inboundPort)); - if (existingLocks == null || existingLocks.isEmpty()) { - return createInboundPortLock(agvId, inboundPort); - } else { - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, inboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "AGV就位并放货,锁定入库口") - ); - return null; - } - } - - @Override - public boolean canFeedToInboundPort(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查入库口是否有活动的锁定 - List activeLocks = agvLockService.getByStation(inboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - log.debug("入库口 {} 当前被占用,无法上料", inboundPort); - return false; - } - - // 检查是否有正在处理的入库任务 - int processingTasks = getProcessingTaskCount(inboundPort); - boolean canFeed = processingTasks == 0; - - log.debug("入库口 {} 可上料状态: {}, 处理中任务数: {}", inboundPort, canFeed, processingTasks); - return canFeed; - } - - @Override - public int getProcessingTaskCount(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 统计正在处理的入库任务数量(包括等待、运行状态的任务) - List processingTasks = appTaskService.list( - new LambdaQueryWrapper() - .eq(TAppTask::getTaskType, WmsTaskTypeEnums.IN.getCode()) - .in(TAppTask::getTaskStatus, - WmsStackerTaskStatusEnums.WAIT.getCode(), - WmsStackerTaskStatusEnums.RUN.getCode()) - .like(TAppTask::getOrigin, inboundPort) // 假设任务来源包含入库口信息 - ); - - return processingTasks.size(); - } - - @Override - public String getInboundPortStatus(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - // 检查是否有活动锁定 - List activeLocks = agvLockService.getByStation(inboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - return "占用"; - } - - // 检查是否有处理中的任务 - int processingTasks = getProcessingTaskCount(inboundPort); - if (processingTasks > 0) { - return "占用"; - } - - return "空闲"; - } - - @Override - @Transactional - public int cleanTimeoutLocks() { - List timeoutLocks = agvLockService.getTimeoutLocks(); - if (timeoutLocks.isEmpty()) { - return 0; - } - - try { - for (TAppAgvLock lock : timeoutLocks) { - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getLockId, lock.getLockId()) - .set(TAppAgvLock::getLockStatus, 0) - .set(TAppAgvLock::getUnlockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "超时自动释放") - ); - - log.info("释放超时锁定: AGV {} 在入库口 {}", lock.getAgvId(), lock.getFeedStation()); - } - - log.info("清理了 {} 个超时锁定", timeoutLocks.size()); - return timeoutLocks.size(); - } catch (Exception e) { - log.error("清理超时锁定失败", e); - return 0; - } - } - - @Override - @Transactional - public int releaseAllInboundPortLocks(String inboundPort) { - // 使用默认入库口如果未指定 - if (StringUtils.isEmpty(inboundPort)) { - inboundPort = DEFAULT_INBOUND_PORT; - } - - try { - // 释放指定入库口的所有活动锁定 - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, inboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getUnlockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "入库任务完成,批量释放锁定") - ); - - // 查询实际释放的锁定数量 - List activeLocks = agvLockService.getByStation(inboundPort); - int releasedCount = (int) activeLocks.stream() - .filter(lock -> lock.getLockStatus() == 0) - .count(); - - log.info("释放入库口 {} 的所有锁定,共释放 {} 个锁定", inboundPort, releasedCount); - return releasedCount; - } catch (Exception e) { - log.error("释放入库口 {} 的所有锁定失败", inboundPort, e); - return 0; - } - } - - // ========== 出库口锁定相关方法实现 ========== - - @Override - @Transactional - public TAppAgvLock lockOutboundPort(String agvId, String outboundPort) { - if (StringUtils.isEmpty(agvId)) { - log.warn("AGV ID为空"); - return null; - } - - // 使用默认出库口如果未指定 - if (StringUtils.isEmpty(outboundPort)) { - outboundPort = DEFAULT_OUTBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查出库口是否已被占用 - List existingLocks = agvLockService.list(new LambdaQueryWrapper().eq(TAppAgvLock::getFeedStation, outboundPort)); - if (existingLocks == null || existingLocks.isEmpty()) { - return createOutboundPortLock(agvId, outboundPort); - } else { - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, outboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "AGV就位并取货,锁定出库口") - ); - return null; - } - } - - @Override - public boolean canFeedToOutboundPort(String outboundPort) { - // 使用默认出库口如果未指定 - if (StringUtils.isEmpty(outboundPort)) { - outboundPort = DEFAULT_OUTBOUND_PORT; - } - - // 清理超时锁定 - cleanTimeoutLocks(); - - // 检查出库口是否有活动的锁定 - List activeLocks = agvLockService.getByStation(outboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - log.debug("出库口 {} 当前被占用,无法出料", outboundPort); - return false; - } - - // 检查是否有正在处理的出库任务 - int processingTasks = getProcessingOutTaskCount(outboundPort); - boolean canFeed = processingTasks == 0; - - log.debug("出库口 {} 可出料状态: {}, 处理中任务数: {}", outboundPort, canFeed, processingTasks); - return canFeed; - } - - @Override - public int getProcessingOutTaskCount(String outboundPort) { - // 使用默认出库口如果未指定 - if (StringUtils.isEmpty(outboundPort)) { - outboundPort = DEFAULT_OUTBOUND_PORT; - } - - // 统计正在处理的出库任务数量(包括等待、运行状态的任务) - List processingTasks = appTaskService.list( - new LambdaQueryWrapper() - .eq(TAppTask::getTaskType, WmsTaskTypeEnums.OUT.getCode()) - .in(TAppTask::getTaskStatus, - WmsStackerTaskStatusEnums.WAIT.getCode(), - WmsStackerTaskStatusEnums.RUN.getCode()) - .like(TAppTask::getDestination, outboundPort) // 假设任务目标包含出库口信息 - ); - - return processingTasks.size(); - } - - @Override - public String getOutboundPortStatus(String outboundPort) { - // 使用默认出库口如果未指定 - if (StringUtils.isEmpty(outboundPort)) { - outboundPort = DEFAULT_OUTBOUND_PORT; - } - - // 检查是否有活动锁定 - List activeLocks = agvLockService.getByStation(outboundPort); - boolean hasActiveLock = activeLocks.stream() - .anyMatch(lock -> lock.getLockStatus() == 1); - - if (hasActiveLock) { - return "占用"; - } - - // 检查是否有处理中的任务 - int processingTasks = getProcessingOutTaskCount(outboundPort); - if (processingTasks > 0) { - return "占用"; - } - - return "空闲"; - } - - @Override - @Transactional - public int releaseAllOutboundPortLocks(String outboundPort) { - // 使用默认出库口如果未指定 - if (StringUtils.isEmpty(outboundPort)) { - outboundPort = DEFAULT_OUTBOUND_PORT; - } - - try { - // 释放指定出库口的所有活动锁定 - agvLockService.update( - new LambdaUpdateWrapper() - .eq(TAppAgvLock::getFeedStation, outboundPort) - .eq(TAppAgvLock::getLockStatus, WmsAgvLockEnums.LOCK.getCode()) - .set(TAppAgvLock::getLockStatus, WmsAgvLockEnums.AVAILABLE.getCode()) - .set(TAppAgvLock::getUnlockTime, LocalDateTime.now()) - .set(TAppAgvLock::getRemark, "出库任务完成,批量释放锁定") - ); - - // 查询实际释放的锁定数量 - List activeLocks = agvLockService.getByStation(outboundPort); - int releasedCount = (int) activeLocks.stream() - .filter(lock -> lock.getLockStatus() == 0) - .count(); - - log.info("释放出库口 {} 的所有锁定,共释放 {} 个锁定", outboundPort, releasedCount); - return releasedCount; - } catch (Exception e) { - log.error("释放出库口 {} 的所有锁定失败", outboundPort, e); - return 0; - } - } - - // ========== 通用锁定方法实现 ========== - - @Override - @Transactional - public TAppAgvLock lockStation(String agvId, String stationCode, Integer taskType) { - if (StringUtils.isEmpty(agvId) || StringUtils.isEmpty(stationCode) || Objects.isNull(taskType)) { - log.warn("锁定参数不完整: agvId={}, stationCode={}, taskType={}", agvId, stationCode, taskType); - return null; - } - - if (WmsTaskTypeEnums.IN.getCode().equals(taskType)) { - return lockInboundPort(agvId, stationCode); - } else if (WmsTaskTypeEnums.OUT.getCode().equals(taskType)) { - return lockOutboundPort(agvId, stationCode); - } else { - log.warn("不支持的任务类型: {}", taskType); - return null; - } - } - - @Override - @Transactional - public int releaseStationLocks(String stationCode, Integer taskType) { - if (StringUtils.isEmpty(stationCode) || Objects.isNull(taskType)) { - log.warn("解锁参数不完整: stationCode={}, taskType={}", stationCode, taskType); - return 0; - } - - if (WmsTaskTypeEnums.IN.getCode().equals(taskType)) { - return releaseAllInboundPortLocks(stationCode); - } else if (WmsTaskTypeEnums.OUT.getCode().equals(taskType)) { - return releaseAllOutboundPortLocks(stationCode); - } else { - log.warn("不支持的任务类型: {}", taskType); - return 0; - } - } - - // ========== 私有方法 ========== - - /** - * 创建入库口锁定记录 - */ - private TAppAgvLock createInboundPortLock(String agvId, String inboundPort) { - TAppAgvLock lock = new TAppAgvLock(); - lock.setLockId(UUIDUtils.getNewUUID()); - lock.setAgvId(agvId); - lock.setFeedStation(inboundPort); - lock.setLockStatus(1); - lock.setLockType("INBOUND_PORT_LOCK"); - lock.setPriority(1); - lock.setQueuePosition(1); - lock.setLockTime(LocalDateTime.now()); - lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS); - lock.setCreateTime(LocalDateTime.now()); - lock.setUpdateTime(LocalDateTime.now()); - lock.setRemark("AGV就位并放货,锁定入库口"); - - if (agvLockService.save(lock)) { - log.info("AGV {} 成功锁定入库口 {}", agvId, inboundPort); - return lock; - } - - log.error("AGV {} 锁定入库口 {} 失败", agvId, inboundPort); - return null; - } - - /** - * 创建出库口锁定记录 - */ - private TAppAgvLock createOutboundPortLock(String agvId, String outboundPort) { - TAppAgvLock lock = new TAppAgvLock(); - lock.setLockId(UUIDUtils.getNewUUID()); - lock.setAgvId(agvId); - lock.setFeedStation(outboundPort); - lock.setLockStatus(1); - lock.setLockType("OUTBOUND_PORT_LOCK"); - lock.setPriority(1); - lock.setQueuePosition(1); - lock.setLockTime(LocalDateTime.now()); - lock.setTimeoutSeconds(DEFAULT_TIMEOUT_SECONDS); - lock.setCreateTime(LocalDateTime.now()); - lock.setUpdateTime(LocalDateTime.now()); - lock.setRemark("AGV就位并取货,锁定出库口"); - - if (agvLockService.save(lock)) { - log.info("AGV {} 成功锁定出库口 {}", agvId, outboundPort); - return lock; - } - - log.error("AGV {} 锁定出库口 {} 失败", agvId, outboundPort); - return null; - } -} \ No newline at end of file diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java index a4300e3..0e2b74a 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/business/serviceImpl/StackerTaskServiceImpl.java @@ -15,7 +15,6 @@ import com.wms_main.repository.utils.ConvertUtils; import com.wms_main.repository.utils.StringUtils; import com.wms_main.repository.utils.UUIDUtils; import com.wms_main.service.api.IExternalApiService; -import com.wms_main.service.business.IAgvLockService; import com.wms_main.service.business.IStackerTaskService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -68,8 +67,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { private final ITAppOrderOutService appOrderOutService; private final IExternalApiService externalApiService; - - private final IAgvLockService agvLockService; /** * 业务通用 */ @@ -455,7 +452,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { appVehicleService.saveOrUpdate(vehicle); appCommon.updateWorkingLocations(wmsTask.getDestination(), 0); - agvLockService.releaseStationLocks("R1", WmsTaskTypeEnums.IN.getCode()); // 备份并删除任务 if (!appTaskService.removeById(wmsTask.getTaskId())) { log.info("删除入库任务失败,任务:{}", wmsTask.getTaskId()); @@ -571,7 +567,6 @@ public class StackerTaskServiceImpl implements IStackerTaskService { .set(TAppStock::getStockStatus, WmsStockStatusEnums.OUTED.getCode()) .set(TAppStock::getLocationId, "") .eq(TAppStock::getVehicleId, vehicleId)); - agvLockService.releaseStationLocks("C1", WmsTaskTypeEnums.OUT.getCode()); // 当前载具的任务列表 List thisVehicleOutTasks = vehicleIdToTaskMap.get(vehicleId); if (thisVehicleOutTasks.isEmpty()) { diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/IMyWmsControllerService.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/IMyWmsControllerService.java index e16e48e..04b8ee4 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/IMyWmsControllerService.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/IMyWmsControllerService.java @@ -1,5 +1,6 @@ package com.wms_main.service.controller; +import com.wms_main.model.dto.request.mywms.AGVDoneReq; import com.wms_main.model.dto.request.mywms.OrderInCancel; import com.wms_main.model.dto.request.mywms.OrderInReq; import com.wms_main.model.dto.request.mywms.OrderOutReq; @@ -22,5 +23,5 @@ public interface IMyWmsControllerService { String cancelOrderIn(OrderInCancel request); - MyWmsResponse agvDone(); + MyWmsResponse agvDone(AGVDoneReq request); } diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java index 169e757..18f19f2 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/controller/serviceImpl/MyWmsControllerServiceImpl.java @@ -30,7 +30,6 @@ import com.wms_main.model.po.TAppWcsTask; import com.wms_main.repository.utils.StringUtils; import com.wms_main.repository.utils.UUIDUtils; import com.wms_main.service.api.IWcsApiService; -import com.wms_main.service.business.IAgvLockService; import com.wms_main.service.controller.IMyWmsControllerService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -47,7 +46,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { private final ITAppOrderInService appOrderInService; private final ITAppOrderOutService appOrderOutService; private final ITAppStockService appStockService; - private final IAgvLockService agvLockService; private final IWcsApiService wcsApiService; private final ITAppTaskService appTaskService; private final ITAppWcsTaskService appWcsTaskService; @@ -63,14 +61,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { return OrderResponse.error("参数错误"); } - // 检查入库口是否可用 - String inboundPort = "R1"; // 默认入库口 - boolean canFeed = agvLockService.canFeedToInboundPort(inboundPort); - if (!canFeed) { - String portStatus = agvLockService.getInboundPortStatus(inboundPort); - return OrderResponse.error("入库口当前" + portStatus + ",无法生成入库订单,请稍后重试"); - } - // 校验是否存在相同的入库单 List withTaskId = appOrderInService.getWithTaskId(request.getTaskId()); if (withTaskId == null) { @@ -91,7 +81,7 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { orderIn.setVehicleNo(request.getVehicleNo()); orderIn.setInStand("R1"); orderIn.setRequestUser("wms"); - orderIn.setOrderStatus(OrderStatusEnum.CREATE.getCode()); + orderIn.setOrderStatus(OrderStatusEnum.TEMP.getCode()); orderIn.setCreateTime(LocalDateTime.now()); orderIn.setUpdateTime(LocalDateTime.now()); if (!appOrderInService.save(orderIn)) { @@ -209,11 +199,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { if (!wcsAllow) { return MyWmsResponse.error("WCS系统不允许AGV上料", false); } - - Boolean wmsAllow = agvLockService.canFeedToInboundPort("R1"); - if (!wmsAllow) { - return MyWmsResponse.error("入库口锁定中", false); - } return MyWmsResponse.success(true); } catch (Exception e) { return MyWmsResponse.error("系统异常,请稍后重试", null); @@ -222,7 +207,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { private MyWmsResponse queryStandStatusOut(QueryStandStatusReq request) { try { - // 1. 调用wcs.canFeed检查wcs状态 (使用R1口) WcsApiResponse wcsResponse = wcsApiService .queryStandStatus(new WcsQueryStandStatusRequest(request.getStandType())); if (wcsResponse == null || wcsResponse.getData() == null) { @@ -234,12 +218,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { return MyWmsResponse.error("WCS系统不允许AGV取货", false); } - // 2. 检查agvLock服务获取wms状态 (使用R1口) - Boolean wmsAllow = agvLockService.canFeedToInboundPort("C1"); - if (!wmsAllow) { - return MyWmsResponse.error("出库口锁定中", false); - } - return MyWmsResponse.success(true); } catch (Exception e) { return MyWmsResponse.error("系统异常,请稍后重试", false); @@ -247,7 +225,27 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { } @Override - public MyWmsResponse agvDone() { + public MyWmsResponse agvDone(AGVDoneReq request) { + if (StringUtils.isEmpty(request.getTaskId())) { + return agvDoneOut(); + } else { + return agvDoneIn(request); + } + } + + private MyWmsResponse agvDoneIn(AGVDoneReq request) { + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() + .eq(TAppOrderIn::getOrderId, request.getTaskId()) + .eq(TAppOrderIn::getOrderStatus, OrderStatusEnum.TEMP.getCode()) + .set(TAppOrderIn::getOrderStatus, OrderStatusEnum.CREATE.getCode()); + if (appOrderInService.update(updateWrapper)) { + return MyWmsResponse.success(); + } else { + return MyWmsResponse.error("更新订单状态失败", null); + } + } + + private MyWmsResponse agvDoneOut() { try { BaseWcsApiResponse wcsResponse = wcsApiService.agvDone(); if (wcsResponse == null) { @@ -284,8 +282,10 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { if (locationList != null && locationList.size() > 0) { location = locationList.getFirst(); } - if (location != null && !appStockService.exists(new LambdaQueryWrapper().eq(StringUtils.isNotEmpty(vehicleNo), - TAppStock::getVehicleId, vehicleNo).eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()))) { + if (location != null && !appStockService.exists(new LambdaQueryWrapper() + .eq(StringUtils.isNotEmpty(vehicleNo), + TAppStock::getVehicleId, vehicleNo) + .eq(TAppStock::getStockStatus, WmsStockStatusEnums.OK.getCode()))) { if (!appLocationService.update( new LambdaUpdateWrapper().eq(TAppLocation::getLocationId, location.getLocationId()) .set(TAppLocation::getIsOccupy, WmsLocationOccupyStatusEnums.EMPTY.getCode()) @@ -297,6 +297,6 @@ public class MyWmsControllerServiceImpl implements IMyWmsControllerService { } else { return "该载具已在库中,无法清除库位信息 / 库位表中无数据"; } - + } } diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java index ac46969..21c14d0 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/java/com/wms_main/service/quartz_job/job_executor/WcsStackerTaskSender.java @@ -4,7 +4,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.wms_main.constant.enums.wcs.WcsApiResponseCodeEnums; import com.wms_main.constant.enums.wcs.WcsStackerTaskStatusEnums; -import com.wms_main.constant.enums.wcs.WcsStackerTaskTypeEnums; import com.wms_main.constant.enums.wms.WmsStackerTaskStatusEnums; import com.wms_main.dao.ITAppTaskService; import com.wms_main.dao.ITAppWcsTaskService; @@ -15,7 +14,6 @@ import com.wms_main.model.po.TAppTask; import com.wms_main.model.po.TAppWcsTask; import com.wms_main.repository.utils.StringUtils; import com.wms_main.service.api.IWcsApiService; -import com.wms_main.service.business.IAgvLockService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.quartz.*; @@ -44,11 +42,6 @@ public class WcsStackerTaskSender implements Job { * Wcs接口服务 */ private final IWcsApiService wcsApiService; - /** - * AGV锁定服务 - */ - private final IAgvLockService agvLockService; - /** * 运行定时任务 * 向Wcs发送堆垛机任务 @@ -73,18 +66,6 @@ public class WcsStackerTaskSender implements Job { waitSendWcsTaskList.sort((task1, task2) -> Integer.compare(task2.getTaskPriority(), task1.getTaskPriority())); // 发送任务 TAppWcsTask wcsTask = waitSendWcsTaskList.getFirst(); - Boolean wmsAllow = false; - if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) { - wmsAllow = agvLockService.canFeedToOutboundPort(wcsTask.getDestination()); - } else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) { - wmsAllow = agvLockService.canFeedToInboundPort(wcsTask.getOrigin()); - } - if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode()) - || wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) { - if (!wmsAllow) { - return; - } - } // 生成请求 WcsStackerTaskRequest request = new WcsStackerTaskRequest( wcsTask.getWcsTaskId(), @@ -107,20 +88,6 @@ public class WcsStackerTaskSender implements Job { new LambdaUpdateWrapper() .set(TAppTask::getTaskStatus, WmsStackerTaskStatusEnums.SEND.getCode()) .eq(TAppTask::getWcsTaskId, wcsTask.getWcsTaskId())); - - if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.OUT.getCode())) { - try { - agvLockService.lockOutboundPort("AGV", wcsTask.getDestination()); - } catch (Exception e) { - log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getDestination(), wcsTask.getWcsTaskId()); - } - } else if (wcsTask.getWcsTaskType().equals(WcsStackerTaskTypeEnums.IN.getCode())) { - try { - agvLockService.lockInboundPort("AGV", wcsTask.getOrigin()); - } catch (Exception e) { - log.error("任务发送成功后锁定{}口失败,任务ID: {}", wcsTask.getOrigin(), wcsTask.getWcsTaskId()); - } - } } else { log.error("堆垛机任务发送失败,请求{},响应信息{}。", StringUtils.objectToString(request), StringUtils.objectToString(wcsResponse)); diff --git a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/resources/application.yml b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/resources/application.yml index b2a9989..c46612f 100644 --- a/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/resources/application.yml +++ b/202504-Wms-MengYang-tp/wms_serve_mengyang/src/main/resources/application.yml @@ -5,13 +5,13 @@ spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver # 本地 - # url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true - # username: root - # password: root - # 服务器 url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true - username: user - password: user + username: root + password: root + # 服务器 + # url: jdbc:mysql://localhost:3306/wms_mengyang_tp?characterEncoding=utf8&serverTimezone=Asia/Shanghai&allowMultiQueries=true&rewriteBatchedStatements=true + # username: user + # password: user profiles: active: online