From 7d66f8a1d75fd2c638b341b24bbf161588651d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=B8=B8=E7=86=9F=E5=90=B4=E5=BD=A6=E7=A5=96?= Date: Fri, 24 Oct 2025 22:59:33 +0800 Subject: [PATCH] gx --- .../service/impl/WmsMessageServiceImpl.java | 57 +++++-- .../service/impl/WcsTaskServiceImpl.java | 148 ++++++++++++++---- .../WcsIntegrationMapper.xml | 22 +-- 3 files changed, 176 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java b/src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java index 78be2f2..65388d0 100644 --- a/src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java +++ b/src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java @@ -367,6 +367,33 @@ public class WmsMessageServiceImpl implements WmsMessageService { } else { throw new RuntimeException("不支持的事务类型:" + inData.getTransTypeDesc()); } + // 所有类型都保存到日志表,由定时任务统一处理 - rqrq + if ("取货通知".equals(inData.getTransTypeDesc()) || "取走栈板".equals(inData.getTransTypeDesc()) || + "入库".equals(inData.getTransTypeDesc()) || "出库".equals(inData.getTransTypeDesc())) { + // 4. 保存WCS回调数据到新表,等待定时任务处理 - rqrq + WcsCallbackTask callbackTask = new WcsCallbackTask(); + callbackTask.setSite(inData.getSite()); + callbackTask.setPalletId(inData.getPalletId()); + callbackTask.setTransTypeDesc(inData.getTransTypeDesc()); + callbackTask.setToWarehouseId(toWarehouseId); + callbackTask.setToLocationId(toLocationId); + callbackTask.setStatus("已录入"); // 等待定时任务处理 + callbackTask.setCreatedTime(new Date()); + callbackTask.setRetryCount(0); + callbackTask.setRemark("WCS立库" + inData.getTransTypeDesc() + "回调"); + callbackTask.setTaskNo(inData.getTaskNo()); + callbackTask.setItemNo(inData.getItemNo()); + callbackTask.setToStation(inData.getToBarcode()); + + // 保存到WCS回调任务表 - rqrq + wcsIntegrationMapper.insertWcsCallbackTask(callbackTask); + + log.info("WCS回调数据已保存:栈板={}, 任务类型={}, 目标位置={}-{}", + inData.getPalletId(), inData.getTransTypeDesc(), toWarehouseId, toLocationId); + } + + // 以下是旧的同步处理逻辑,已移至定时任务处理,保留作为备份参考 - rqrq + /* //单独call料栈板到达出库口 直接转移站点然后更新任务就行 if ("取货通知".equals(inData.getTransTypeDesc())) { updateOrderTaskStatusForQuHuo(inData); @@ -526,6 +553,8 @@ public class WmsMessageServiceImpl implements WmsMessageService { } + // 旧的入库出库同步处理逻辑,已移至定时任务统一处理 - rqrq + /* }else if ("入库".equals(inData.getTransTypeDesc())||"出库".equals(inData.getTransTypeDesc())) { // 4. 保存WCS回调数据到新表,等待定时任务处理 WcsCallbackTask callbackTask = new WcsCallbackTask(); @@ -559,23 +588,27 @@ public class WmsMessageServiceImpl implements WmsMessageService { wcsIntegrationMapper.reUpdatePalletDetailWcsFlag(inData.getSite(),inData.getPalletId()); wcsIntegrationMapper.updatePalletCallingFlag(inData.getSite(), inData.getPalletId(), "Y", "SYS_WMS"); } + */ + // 如果是入库,需要立即更新一些状态(防止没有组盘入库的情况)- rqrq + if ("入库".equals(inData.getTransTypeDesc())) { + updateOrderTaskStatusForInboundCallback(inData); + //防止没有组盘入库 - rqrq + wcsIntegrationMapper.updatePalletDetailWcsFlag(inData.getSite(), inData.getPalletId()); + log.info("入库回调:已更新pallet_detail的wcs_flag - rqrq,palletId={}", inData.getPalletId()); + } + + // 如果是出库,需要立即更新一些状态 - rqrq + if ("出库".equals(inData.getTransTypeDesc())) { + updateOrderTaskStatusForOutCallback(inData); + //可能是移库出库 - rqrq + wcsIntegrationMapper.reUpdatePalletDetailWcsFlag(inData.getSite(), inData.getPalletId()); + log.info("出库回调:已更新pallet_detail的wcs_flag - rqrq,palletId={}", inData.getPalletId()); + } log.info("WCS回调数据已保存:栈板={}, 任务类型={}, 目标位置={}-{}", inData.getPalletId(), inData.getTransTypeDesc(), toWarehouseId, toLocationId); - // 业务逻辑已转移到定时任务WcsTaskScheduler中处理 - // WareHouseTransferRequest request = new WareHouseTransferRequest(); - // request.setSite(inData.getSite()); - // request.setPalletId(inData.getPalletId()); - // request.setToWarehouseId(toWarehouseId); - // request.setToLocationId(toLocationId); - // request.setBusinessType("立库" + inData.getTransTypeDesc()); - // request.setRemark("WCS立库" + inData.getTransTypeDesc() + "操作"); - // request.setToStation("*");//立库内的站点都为* - // // 5. 调用通用移库方法 - // String result = doWareHouseForPallet(request); - String result = "WCS回调数据已保存,等待定时任务处理"; // 6. 更新成功日志 diff --git a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsTaskServiceImpl.java b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsTaskServiceImpl.java index 79492cf..00d0c5b 100644 --- a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsTaskServiceImpl.java +++ b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsTaskServiceImpl.java @@ -52,7 +52,7 @@ public class WcsTaskServiceImpl implements WcsTaskService { @Override @Transactional public void processWcsCallbackTask(WcsCallbackTask callbackTask) { - // 判断是否为超时恢复的任务 + // 判断是否为超时恢复的任务 - rqrq boolean isTimeoutRecovery = "处理中".equals(callbackTask.getStatus()); try { @@ -64,16 +64,18 @@ public class WcsTaskServiceImpl implements WcsTaskService { log.info("处理WCS回调任务:palletId={}, transType={}, currentStatus={}", callbackTask.getPalletId(), callbackTask.getTransTypeDesc(), callbackTask.getStatus()); } + + // 获取用户名 - rqrq List orderTasks = wcsIntegrationMapper.findOrderTasksByTaskNo( callbackTask.getSite(), callbackTask.getTaskNo() ); - String userName="sys_wms"; + String userName = "sys_wms"; if (orderTasks != null && !orderTasks.isEmpty()) { userName = orderTasks.get(0).getCreatedBy(); } - // 1. 使用乐观锁更新状态为处理中(防止重复处理) + // 1. 使用乐观锁更新状态为处理中(防止重复处理)- rqrq int updateCount = wcsIntegrationMapper.updateWcsCallbackTaskStatusWithLock( callbackTask.getId(), callbackTask.getStatus(), // 原状态(已录入 or 处理失败 or 处理中) @@ -81,42 +83,53 @@ public class WcsTaskServiceImpl implements WcsTaskService { new Date() ); - // 2. 如果更新失败,说明已被其他线程处理,直接返回 + // 2. 如果更新失败,说明已被其他线程处理,直接返回 - rqrq if (updateCount == 0) { log.warn("任务已被其他线程处理,跳过:id={}, palletId={}, status={}", callbackTask.getId(), callbackTask.getPalletId(), callbackTask.getStatus()); return; // 跳过,不抛异常 } - log.info("成功锁定任务,开始处理:palletId={}, isTimeoutRecovery={}", - callbackTask.getPalletId(), isTimeoutRecovery); - - // 3. 构建移库请求参数 - WareHouseTransferRequest request = buildWareHouseTransferRequest(callbackTask); - request.setUsername(userName); - // 4. 调用通用移库方法(原样调用,不修改) - String result = wmsMessageService.doWareHouseForPallet(request); - - log.info("WCS回调任务处理成功:palletId={}, result={}", callbackTask.getPalletId(), result); + log.info("成功锁定任务,开始处理:palletId={}, transType={}, isTimeoutRecovery={}", + callbackTask.getPalletId(), callbackTask.getTransTypeDesc(), isTimeoutRecovery); - // 5. 如果是入库,更新对应的wms_order_task状态 - if ("入库".equals(callbackTask.getTransTypeDesc())) { - updateOrderTaskStatusForInbound(callbackTask); - wcsIntegrationMapper.updatePalletCallingFlag(callbackTask.getSite(), callbackTask.getPalletId(), "N", "SYS_WMS"); - } - if ("出库".equals(callbackTask.getTransTypeDesc())) { - wcsIntegrationMapper.updatePalletWcsLocation(callbackTask.getSite(), callbackTask.getPalletId(), null); - wcsIntegrationMapper.updatePalletCallingFlag(callbackTask.getSite(), callbackTask.getPalletId(), "Y", "SYS_WMS"); + // 3. 根据不同的TransTypeDesc执行不同的处理逻辑 - rqrq + String result = ""; + if ("入库".equals(callbackTask.getTransTypeDesc()) || "出库".equals(callbackTask.getTransTypeDesc())) { + // 入库和出库需要执行移库操作 - rqrq + WareHouseTransferRequest request = buildWareHouseTransferRequest(callbackTask); + request.setUsername(userName); + result = wmsMessageService.doWareHouseForPallet(request); + + // 更新托盘状态 - rqrq + if ("入库".equals(callbackTask.getTransTypeDesc())) { + updateOrderTaskStatusForInbound(callbackTask); + wcsIntegrationMapper.updatePalletCallingFlag(callbackTask.getSite(), callbackTask.getPalletId(), "N", "SYS_WMS"); + } else { + wcsIntegrationMapper.updatePalletWcsLocation(callbackTask.getSite(), callbackTask.getPalletId(), null); + wcsIntegrationMapper.updatePalletCallingFlag(callbackTask.getSite(), callbackTask.getPalletId(), "Y", "SYS_WMS"); + } + } else if ("取货通知".equals(callbackTask.getTransTypeDesc())) { + // 取货通知:更新托盘位置和订单任务状态 - rqrq + result = processPickupNotification(callbackTask); + } else if ("取走栈板".equals(callbackTask.getTransTypeDesc())) { + // 取走栈板:更新站点状态 - rqrq + result = processPalletRemoval(callbackTask); + } else { + throw new RuntimeException("不支持的事务类型:" + callbackTask.getTransTypeDesc()); } - // 6. 更新任务状态为已完成 + log.info("WCS回调任务处理成功:palletId={}, transType={}, result={}", + callbackTask.getPalletId(), callbackTask.getTransTypeDesc(), result); + + // 6. 更新任务状态为已完成 - rqrq wcsIntegrationMapper.updateWcsCallbackTaskStatus(callbackTask.getId(), "已完成", null, new Date(), null); } catch (Exception e) { - log.error("处理WCS回调任务失败:palletId={}, isTimeoutRecovery={}", - callbackTask.getPalletId(), isTimeoutRecovery, e); // 记录完整堆栈 + log.error("处理WCS回调任务失败:palletId={}, transType={}, isTimeoutRecovery={}", + callbackTask.getPalletId(), callbackTask.getTransTypeDesc(), isTimeoutRecovery, e); - // 更新重试次数(超时恢复的任务也算作一次重试) + // 更新重试次数(超时恢复的任务也算作一次重试)- rqrq int currentRetryCount = (callbackTask.getRetryCount() == null ? 0 : callbackTask.getRetryCount()); int newRetryCount = isTimeoutRecovery ? currentRetryCount + 1 : currentRetryCount + 1; String status = newRetryCount >= 3 ? "处理失败" : "已录入"; // 重试3次后标记为失败 @@ -126,6 +139,7 @@ public class WcsTaskServiceImpl implements WcsTaskService { log.warn("任务处理失败,更新状态:id={}, retryCount={}->{}, status={}", callbackTask.getId(), currentRetryCount, newRetryCount, status); + // 更新失败状态到日志表 - rqrq wcsIntegrationMapper.updateWcsCallbackTaskStatus(callbackTask.getId(), status, null, null, errorMsg); wcsIntegrationMapper.updateWcsCallbackTaskRetryCount(callbackTask.getId(), newRetryCount); @@ -182,7 +196,7 @@ public class WcsTaskServiceImpl implements WcsTaskService { public WareHouseTransferRequest buildWareHouseTransferRequest(WcsCallbackTask callbackTask) { WareHouseTransferRequest request = new WareHouseTransferRequest(); - // 从回调任务中获取基本信息 + // 从回调任务中获取基本信息 - rqrq request.setSite(callbackTask.getSite()); request.setPalletId(callbackTask.getPalletId()); request.setToWarehouseId(callbackTask.getToWarehouseId()); @@ -190,13 +204,21 @@ public class WcsTaskServiceImpl implements WcsTaskService { request.setTransType("移库"); request.setToStation(callbackTask.getToStation()); // 立库内的站点都为* - // 根据transTypeDesc判断业务类型 + // 根据transTypeDesc判断业务类型 - rqrq if ("入库".equals(callbackTask.getTransTypeDesc())) { request.setBusinessType("立库入库"); request.setRemark("WCS立库入库操作"); } else if ("出库".equals(callbackTask.getTransTypeDesc())) { request.setBusinessType("立库出库"); request.setRemark("WCS立库出库操作"); + } else if ("取货通知".equals(callbackTask.getTransTypeDesc())) { + // 取货通知不需要移库操作,只需要更新托盘位置 - rqrq + request.setBusinessType("取货通知"); + request.setRemark("WCS取货通知操作"); + } else if ("取走栈板".equals(callbackTask.getTransTypeDesc())) { + // 取走栈板不需要移库操作,只需要更新站点状态 - rqrq + request.setBusinessType("取走栈板"); + request.setRemark("WCS取走栈板操作"); } else { throw new RuntimeException("不支持的事务类型:" + callbackTask.getTransTypeDesc()); } @@ -282,4 +304,74 @@ public class WcsTaskServiceImpl implements WcsTaskService { } } + /** + * @Description 处理取货通知 - rqrq + * @param callbackTask WCS回调任务 + * @return 处理结果 + * @author rqrq + * @date 2025/10/24 + */ + private String processPickupNotification(WcsCallbackTask callbackTask) { + System.out.println("开始处理取货通知 - rqrq,palletId=" + callbackTask.getPalletId() + ", toStation=" + callbackTask.getToStation()); + + try { + // 1. 更新订单任务状态 - rqrq + if (callbackTask.getTaskNo() != null && callbackTask.getItemNo() != null) { + WmsOrderTask orderTask = wcsIntegrationMapper.findOrderTasksByTaskNoItem( + callbackTask.getSite(), callbackTask.getTaskNo(), callbackTask.getItemNo()); + if (orderTask != null) { + wcsIntegrationMapper.updateOrderTaskStatusAndWmsStatus( + orderTask.getId(), "待取货", "待取货"); + wcsIntegrationMapper.updateOrderTaskDetailStatusByTaskNoPalletId( + callbackTask.getSite(), callbackTask.getTaskNo(), "待取货", "待取货", callbackTask.getPalletId()); + System.out.println("更新订单任务状态为待取货 - rqrq,taskNo=" + callbackTask.getTaskNo()); + } + } + + // 2. 更新托盘calling_flag为N - rqrq + wcsIntegrationMapper.updatePalletCallingFlag(callbackTask.getSite(), callbackTask.getPalletId(), "N", "SYS_WMS"); + + // 3. 更新站点状态为有货 - rqrq + wcsIntegrationMapper.updateAgvStationStatus(callbackTask.getToStation(), 1, "有货"); + + // 4. 更新托盘位置 - rqrq + wcsIntegrationMapper.updatePalletLocationCode(callbackTask.getSite(), callbackTask.getPalletId(), callbackTask.getToStation()); + + System.out.println("处理取货通知完成 - rqrq,palletId=" + callbackTask.getPalletId()); + return "取货通知处理成功"; + + } catch (Exception e) { + System.err.println("处理取货通知失败 - rqrq:" + e.getMessage()); + throw new RuntimeException("处理取货通知失败: " + e.getMessage(), e); + } + } + + /** + * @Description 处理取走栈板 - rqrq + * @param callbackTask WCS回调任务 + * @return 处理结果 + * @author rqrq + * @date 2025/10/24 + */ + private String processPalletRemoval(WcsCallbackTask callbackTask) { + System.out.println("开始处理取走栈板 - rqrq,palletId=" + callbackTask.getPalletId() + ", toStation=" + callbackTask.getToStation()); + + try { + // 1. 检查toStation是否以D开头(滚筒对接区)- rqrq + if (callbackTask.getToStation() == null || !callbackTask.getToStation().startsWith("D")) { + throw new RuntimeException("目前只有滚筒对接区(D1/D2)可以执行取走栈板操作,当前站点:" + callbackTask.getToStation()); + } + + // 2. 更新站点状态为空闲 - rqrq + wcsIntegrationMapper.updateAgvStationStatus(callbackTask.getToStation(), 0, "空闲"); + + System.out.println("处理取走栈板完成 - rqrq,palletId=" + callbackTask.getPalletId() + ", 站点" + callbackTask.getToStation() + "已更新为空闲"); + return "取走栈板处理成功,站点已更新为空闲"; + + } catch (Exception e) { + System.err.println("处理取走栈板失败 - rqrq:" + e.getMessage()); + throw new RuntimeException("处理取走栈板失败: " + e.getMessage(), e); + } + } + } \ No newline at end of file diff --git a/src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml b/src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml index 3389454..df4b83e 100644 --- a/src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml +++ b/src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml @@ -16,7 +16,7 @@ NULL AS batchNo, NULL AS wdr, NULL AS expiredDate - FROM pallet c + FROM pallet c WITH (NOLOCK) WHERE c.site = #{site} AND c.pallet_id = #{palletId} AND c.is_deleted = '0' @@ -33,9 +33,9 @@ b.batch_no AS batchNo, b.wdr, CONVERT(VARCHAR(10), b.expired_date, 120) AS expiredDate - FROM pallet_detail a - INNER JOIN handling_unit b ON a.site = b.site AND a.serial_no = b.unit_id - INNER JOIN pallet c ON a.site = c.site AND a.pallet_id = c.pallet_id + FROM pallet_detail a WITH (NOLOCK) + INNER JOIN handling_unit b WITH (NOLOCK) ON a.site = b.site AND a.serial_no = b.unit_id + INNER JOIN pallet c WITH (NOLOCK) ON a.site = c.site AND a.pallet_id = c.pallet_id AND c.is_deleted = '0' AND (c.calling_flag IS NULL OR c.calling_flag != 'Y') @@ -128,10 +128,10 @@ - + @@ -886,7 +886,7 @@ WHERE station_code = #{stationCode} - +