From 7cad6afc6aafd2e50c297bb1a9ad60d506402fd1 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: Thu, 10 Sep 2026 12:43:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B7=A8site=E8=B0=83=E6=8B=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- .../autoWareHourceHaian/HAIAN_AI_CONTEXT.md | 2 +- .../controller/HaiAnWmsMessageController.java | 8 +++--- .../api/entity/HaiAnAgvCallbackRequest.java | 25 ++++++++++++++++++- .../impl/HaiAnWmsMessageServiceImpl.java | 9 ++++--- 5 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index b067ec8b..9a998ec7 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,5 @@ hs_err_pid* # 本地行尾与编辑器配置仅用于开发机,不参与版本提交 - rqrq .gitattributes .editorconfig -.vscode/ \ No newline at end of file +.vscode/ +.gitnexus diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md b/src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md index 4129ebc1..6416a173 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/HAIAN_AI_CONTEXT.md @@ -79,7 +79,7 @@ - 海安 `haian_ifs_pallet_move_queue.move_group_json.site` 存的是标签子site;自动任务执行时查询目标库位主数据必须先通过 `site_sub(subsiteid->siteid)` 反查大site,再按大site查询 `location`,禁止直接用子site查库位 - rqrq - 海安 `HaianAutoTaskScheduler` 处理队列时必须先将 `serial_no_str` 对应标签回写到目标仓库/库位,再调用老IFS `MoveInventoryPartV2`;IFS失败要回滚标签更新,确保WMS与IFS库位一致性 - rqrq - 海安自动任务开关使用 `scheduler.haianAutoTask.enabled`,P状态超时回收分钟数使用 `scheduler.haianAutoTask.ifsPalletMoveQueue.processing-timeout-minutes` - rqrq -- 海安 AGV 反馈接口 `POST /api/wms54/count/agvCallback` 新协议必填 `site/wmsId/taskId/palletId/targetPoint/targetArea/type`,`targetArea` 是下游 `wcs_area_code`,入库前必须按 `haian_area.wcs_area_code -> area_id` 转换后再写明细 `to_area`;`palletId` 在“下达任务”场景必须写入明细 `pallet_id`;`comment` 在“下达任务”场景写 `source_bill_no`、在 `RFID复核` 场景保存复核备注 - rqrq +- 海安 AGV 反馈接口 `POST /api/wms54/count/agvCallback` 新协议必填 `site/wmsId/taskId/托盘号/targetPoint/targetArea/type`;托盘号兼容 `palletId` 与对端协议字段 `pallet`,两者都有时优先 `palletId`,只传 `pallet` 也视为必填通过;`targetArea` 是下游 `wcs_area_code`,入库前必须按 `haian_area.wcs_area_code -> area_id` 转换后再写明细 `to_area`;解析后的托盘号在“下达任务”场景必须写入明细 `pallet_id`;`comment` 在“下达任务”场景写 `source_bill_no`、在 `RFID复核` 场景保存复核备注 - rqrq - 海安 AGV 回调采用“两段式”:第一段接口仅写 `haian_wms_transport_task_detail(status=已录入)`;第二段由 `HaianWcsSchedule.scheduleAgvFeedback(3.1秒)` 乐观锁消费明细并驱动主任务/托盘状态(下达=calling_flag:Y并创建主任务含from_area、取货=托运中、送货=完成+按需移库+回写area/location、取消=已取消且calling_flag:N) - rqrq - 海安 `wcsWareHouse` 回调同样采用“两段式”:第一段接口只写 `haian_wcs_callback_task(status=已录入)`;第二段由 `HaianWcsSchedule.scheduleHaianWcsTaskProcessing(2.6秒)` 乐观锁消费,并按 `入货架(原入库)/出货架(原出库)/离开入库口(原取走栈板)/到达异常位(原异常位处理)/到达出库口(原取货通知)/到达手工分拣区` 分流处理(到达出库口不再依赖transportTask分支,且不执行 `palletAutoGoToWCS.goToWCS` 回库逻辑;到达手工分拣区仅把 `haian_pallet.location_code` 改成回传点位,不改 calling_flag、不做移库) - rqrq - 海安被分拣站点写死为 `R1/R2/R3/R4`(`HaiAnStationStaticData.SORTED_SOURCE_STATIONS`,与自动分拣 `J1/J2/J3/J4` 不是同一组)。到达手工分拣区会把 `haian_pallet.location_code` 改成回传点位,分拣页“放回标签”必须按当前 `location_code` 是否命中该数组判断被分拣源盘,禁止用“不是 J1-J4 就算被分拣”(会误放行货架/输送线)。现场编码不同时只改 `HaiAnStationStaticData` - rqrq diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/controller/HaiAnWmsMessageController.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/controller/HaiAnWmsMessageController.java index 6eb5da2b..7039a7dc 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/controller/HaiAnWmsMessageController.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/controller/HaiAnWmsMessageController.java @@ -140,14 +140,14 @@ public class HaiAnWmsMessageController extends AbstractController { /** * @author rqrq * @Description AGV任务反馈入口,确保任务定位参数有效后交给Service编排处理 - rqrq - * @param data AGV回调实体(site/wmsId/taskId/palletId/targetPoint/targetArea(type为WCS区域编码)/type/comment) - rqrq + * @param data AGV回调实体(site/wmsId/taskId/palletId或pallet/targetPoint/targetArea(type为WCS区域编码)/type/comment) - rqrq * @return ResponseData 统一响应对象,成功返回messageId,失败返回错误原因 - rqrq */ @PostMapping("/count/agvCallback") public ResponseData agvCallback(@RequestBody HaiAnAgvCallbackRequest data) { try { if (!validateAgvCallbackData(data)) { - return errorResponse("参数验证失败:site/wmsId/taskId/palletId/targetPoint/targetArea/type为必填项,type需为约定动作类型"); + return errorResponse("参数验证失败:site/wmsId/taskId/托盘号(palletId或pallet)/targetPoint/targetArea/type为必填项,type需为约定动作类型"); } String messageId = haiAnWmsMessageService.handleAgvCallback(data); log.info("海安AGV任务反馈已接收 - rqrq,messageId={}, wmsId={}, taskId={}", @@ -232,14 +232,14 @@ public class HaiAnWmsMessageController extends AbstractController { /** * @author rqrq - * @Description 验证AGV任务反馈参数,确保主任务键与动作语义完整,避免状态串写 - rqrq + * @Description 验证AGV任务反馈参数,确保主任务键与动作语义完整,避免状态串写;托盘号走resolvePalletId兼容pallet/palletId - rqrq */ private boolean validateAgvCallbackData(HaiAnAgvCallbackRequest data) { if (data == null || !StringUtils.hasText(data.getSite()) || !StringUtils.hasText(data.getWmsId()) || !StringUtils.hasText(data.getTaskId()) - || !StringUtils.hasText(data.getPalletId()) + || !StringUtils.hasText(data.resolvePalletId()) || !StringUtils.hasText(data.getTargetPoint()) || !StringUtils.hasText(data.getTargetArea()) || !StringUtils.hasText(data.getType())) { diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnAgvCallbackRequest.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnAgvCallbackRequest.java index dea153a4..b7f58ed3 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnAgvCallbackRequest.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnAgvCallbackRequest.java @@ -1,6 +1,7 @@ package com.gaotao.modules.autoWareHourceHaian.api.entity; import lombok.Data; +import org.springframework.util.StringUtils; /** * @author rqrq @@ -25,10 +26,17 @@ public class HaiAnAgvCallbackRequest { private String taskId; /** - * 托盘编号(必填):用于标识本次AGV反馈作用托盘,下达任务场景需落库到任务明细 - rqrq + * 托盘编号(优先取值):海安内部字段名;用于标识本次AGV反馈作用托盘,下达任务场景需落库到任务明细。 + * 与 pallet 都有值时业务一律取本字段;不落请求表,仅回调入参。 - rqrq */ private String palletId; + /** + * 托盘编号兼容字段(对端协议名pallet):不落库、仅请求解析。 + * 对端文档传 pallet 而不是 palletId 时由此接收;palletId 为空才使用本字段,避免双字段同时到达时口径漂移。 - rqrq + */ + private String pallet; + /** * AGV设备号(可选) - rqrq */ @@ -53,5 +61,20 @@ public class HaiAnAgvCallbackRequest { * 回调备注(选填):RFID复核场景传复核结果文本,其它类型忽略 - rqrq */ private String comment; + + /** + * @author rqrq + * @Description 解析AGV回调托盘号:palletId优先,缺省回退pallet;都空返回null,避免对端两种字段名导致必填校验误杀 - rqrq + * @return 去空格后的托盘号,两者都空时为null - rqrq + */ + public String resolvePalletId() { + if (StringUtils.hasText(palletId)) { + return palletId.trim(); + } + if (StringUtils.hasText(pallet)) { + return pallet.trim(); + } + return null; + } } diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java index e305cadc..b905eac0 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java @@ -1338,7 +1338,8 @@ public class HaiAnWmsMessageServiceImpl implements HaiAnWmsMessageService { validateAgvCallbackRequest(data); String wmsId = data.getWmsId().trim(); String xjTaskId = data.getTaskId().trim(); - String palletId = data.getPalletId().trim(); + // 托盘号兼容对端pallet与内部palletId,两者都有时取palletId,避免协议字段名不一致导致下达任务落空托盘 - rqrq + String palletId = data.resolvePalletId(); String targetPoint = data.getTargetPoint().trim(); String targetArea = convertAgvTargetAreaToBusinessArea(site, data.getTargetArea()); String normalizedType = normalizeAgvCallbackType(data.getType()); @@ -1405,18 +1406,18 @@ public class HaiAnWmsMessageServiceImpl implements HaiAnWmsMessageService { /** * @author rqrq - * @Description 校验AGV回调核心字段:site/wmsId/taskId/palletId/targetPoint/targetArea/type均必填且type必须在白名单内 - rqrq + * @Description 校验AGV回调核心字段:site/wmsId/taskId/托盘号(palletId优先否则pallet)/targetPoint/targetArea/type均必填且type必须在白名单内 - rqrq */ private void validateAgvCallbackRequest(HaiAnAgvCallbackRequest data) { if (data == null || !StringUtils.hasText(data.getSite()) || !StringUtils.hasText(data.getWmsId()) || !StringUtils.hasText(data.getTaskId()) - || !StringUtils.hasText(data.getPalletId()) + || !StringUtils.hasText(data.resolvePalletId()) || !StringUtils.hasText(data.getTargetPoint()) || !StringUtils.hasText(data.getTargetArea()) || !StringUtils.hasText(data.getType())) { - throw new RuntimeException("AGV反馈参数缺失:site/wmsId/taskId/palletId/targetPoint/targetArea/type为必填项"); + throw new RuntimeException("AGV反馈参数缺失:site/wmsId/taskId/托盘号(palletId或pallet)/targetPoint/targetArea/type为必填项"); } String normalizedType = normalizeAgvCallbackType(data.getType()); if (!isSupportedAgvCallbackType(normalizedType)) {