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 59105299..0059646a 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 @@ -2,6 +2,8 @@ package com.gaotao.modules.autoWareHourceHaian.api.controller; import com.gaotao.common.utils.ResponseData; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnAgvCallbackRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyResult; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnPickingFeedbackRequest; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnRfidCountVerifyCallbackRequest; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnRfidLongMenCallbackRequest; @@ -32,6 +34,17 @@ public class HaiAnWmsMessageController extends AbstractController { @Autowired private HaiAnWmsMessageService haiAnWmsMessageService; + /** + * @Description 立库入库RFID同步复核入口;直接返回立库协议字段,入参校验与标签比对交由Service。- rqrq + * @param data 托盘号、扫描标签和可选栈板大site;gateCode/taskNo等字段忽略。- rqrq + * @return 复核通过或退出入库口指令及标签差异;查询失败由Service抛错。- rqrq + */ + @PostMapping("/inbound/verifyPalletRfid") + public HaiAnInboundRfidVerifyResult verifyInboundPalletRfid(@RequestBody HaiAnInboundRfidVerifyRequest data) { + // 同步调用复核服务;由Service按请求大site及托盘号查询明细,失败不得伪装成复核通过 - rqrq + return haiAnWmsMessageService.verifyInboundPalletRfid(data); + } + /** * @author rqrq * @Description 立库出入库状态回调入口,负责参数快验与异常兜底;仅认入货架(原入库)/出货架(原出库)/到达出库口(原取货通知)/离开入库口(原取走栈板)/到达异常位(原异常位处理)/到达手工分拣区 - rqrq diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyRequest.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyRequest.java new file mode 100644 index 00000000..b9be5530 --- /dev/null +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyRequest.java @@ -0,0 +1,23 @@ +package com.gaotao.modules.autoWareHourceHaian.api.entity; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +import java.util.List; + +/** + * @Description 海安入库 RFID 复核请求;只读取大site、托盘号和扫描标签,其余立库字段忽略。- rqrq + */ +@Data +@JsonIgnoreProperties(ignoreUnknown = true) +public class HaiAnInboundRfidVerifyRequest { + + /** 栈板大site,来自立库请求;可空,传入时用于限定 haian_pallet_detail.site,不是标签 sub_site。- rqrq */ + private String site; + + /** 托盘号,来自立库请求;必填,用于查询本盘明细并原样对应复核结果。- rqrq */ + private String palletId; + + /** RFID门扫描标签,来自立库请求;null或空数组视为空盘,去重后参与无序比对,不落库。- rqrq */ + private List rfidBarcodes; +} diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyResult.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyResult.java new file mode 100644 index 00000000..94c1b4f3 --- /dev/null +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyResult.java @@ -0,0 +1,39 @@ +package com.gaotao.modules.autoWareHourceHaian.api.entity; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +/** + * @Description 海安入库 RFID 复核直接响应立库的结果;差异仅给出退出指令,不创建搬运任务。- rqrq + */ +@Data +@JsonInclude(JsonInclude.Include.ALWAYS) +public class HaiAnInboundRfidVerifyResult { + + /** 协议结果码;复核完成时固定200,通过与否由verifyPassed判定,不落库。- rqrq */ + private Integer resCode; + + /** 立库展示文案;通过时提示继续入库,失败时包含扫描数及缺失、多余标签,不落库。- rqrq */ + private String resMsg; + + /** 本次实际托盘号,来自请求palletId,供立库关联复核结果,不落库。- rqrq */ + private String palletId; + + /** 标签集合是否完全一致,供立库决定继续或退出,不落库。- rqrq */ + private Boolean verifyPassed; + + /** 立库动作指令:通过为CONTINUE_INBOUND,失败为EXIT_TO_INBOUND_PORT,不落库。- rqrq */ + private String actionDirective; + + /** 预留返回端口;本接口固定null,由立库后续自行确定,不落库。- rqrq */ + private String returnPort; + + /** 预留异常位置;本接口固定null,不指派位置且不落库。- rqrq */ + private String exceptionLocation; + + /** 预留AGV任务号;本接口固定null,不创建AGV任务且不落库。- rqrq */ + private String agvTaskNo; + + /** 失败时的标签差异详情;通过时为null,供立库显示,不落库。- rqrq */ + private String remark; +} diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/HaiAnWmsMessageService.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/HaiAnWmsMessageService.java index 523a3cac..2c362c3b 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/HaiAnWmsMessageService.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/HaiAnWmsMessageService.java @@ -1,6 +1,8 @@ package com.gaotao.modules.autoWareHourceHaian.api.service; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnAgvCallbackRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyResult; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnPickingFeedbackRequest; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnRfidCountVerifyCallbackRequest; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnRfidLongMenCallbackRequest; @@ -13,6 +15,13 @@ import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnWcsInboundCallback */ public interface HaiAnWmsMessageService { + /** + * @Description 同步复核入库RFID标签;以库内标签为基准计算缺失和多余,空集合相等时通过,不写任务。- rqrq + * @param data 托盘号必填、扫描标签可空,site为可选栈板大site;其它立库参数忽略。- rqrq + * @return 立库要求的直接响应,包含复核结果、动作指令与差异文案。- rqrq + */ + HaiAnInboundRfidVerifyResult verifyInboundPalletRfid(HaiAnInboundRfidVerifyRequest data); + /** * @author rqrq * @Description 处理立库出入库状态回调并返回消息追踪ID;仅认入货架(原入库)/出货架(原出库)/到达出库口(原取货通知)/离开入库口(原取走栈板)/到达异常位(原异常位处理)/到达手工分拣区 - rqrq 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 9f823f0e..951d17d4 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 @@ -11,6 +11,8 @@ import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnStationStaticData; import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnStatusStaticData; import com.gaotao.modules.autoWareHourceHaian.staticData.HaiAnWcsTransTypeStaticData; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnAgvCallbackRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyRequest; +import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnInboundRfidVerifyResult; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnPickingFeedbackCargoInfo; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnPickingFeedbackProductInfo; import com.gaotao.modules.autoWareHourceHaian.api.entity.HaiAnPickingFeedbackRequest; @@ -54,6 +56,7 @@ import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; +import java.util.TreeSet; import java.util.UUID; /** @@ -178,6 +181,74 @@ public class HaiAnWmsMessageServiceImpl implements HaiAnWmsMessageService { return new RuntimeException(functionName + "处理失败: " + exception.getMessage(), exception); } + /** + * @Description 入库RFID同步复核:扫描侧先去重,再与托盘明细标签做无序集合比较;仅返回立库指令,不写任务或修改库存。- rqrq + * @param data palletId必填;rfidBarcodes空值为空盘,site若传入则作为栈板大site限定查询。- rqrq + * @return 集合相同继续入库;不同时给出库内缺失和扫码多余标签,查询失败直接抛错。- rqrq + */ + @Override + public HaiAnInboundRfidVerifyResult verifyInboundPalletRfid(HaiAnInboundRfidVerifyRequest data) { + if (data == null || !StringUtils.hasText(data.getPalletId())) { + throw new RuntimeException("入库RFID复核缺少palletId"); + } + String palletId = data.getPalletId().trim(); + String site = StringUtils.hasText(data.getSite()) ? data.getSite().trim() : null; + + // 扫描数组允许null或空;去重并忽略空白元素,数量按有效唯一标签计算,顺序不参与复核 - rqrq + Set scanned = new TreeSet(); + if (data.getRfidBarcodes() != null) { + for (String barcode : data.getRfidBarcodes()) { + if (StringUtils.hasText(barcode)) { + scanned.add(barcode.trim()); + } + } + } + + // 按托盘号和可选大site无锁查询本盘标签;mapper查询失败直接终止,不得把未知结果视作空盘放行 - rqrq + List detailSerialNos = haiAnPdaAutoWarehouseMapper.listInboundRfidVerifySerialNos(site, palletId); + if (detailSerialNos == null) { + throw new RuntimeException("入库RFID复核查询托盘明细失败:" + palletId); + } + Set expected = new TreeSet(); + for (String serialNo : detailSerialNos) { + if (StringUtils.hasText(serialNo)) { + expected.add(serialNo.trim()); + } + } + + // 缺失=库内有而门未扫到;多余=门扫到而库内没有。两边都空仍视为一致,不要求托盘主表存在 - rqrq + Set missing = new TreeSet(expected); + missing.removeAll(scanned); + Set extra = new TreeSet(scanned); + extra.removeAll(expected); + boolean passed = missing.isEmpty() && extra.isEmpty(); + + HaiAnInboundRfidVerifyResult result = new HaiAnInboundRfidVerifyResult(); + result.setResCode(200); + result.setPalletId(palletId); + result.setVerifyPassed(passed); + if (passed) { + result.setResMsg("入库 RFID 复核通过,继续入库上架"); + result.setActionDirective("CONTINUE_INBOUND"); + } else { + String differenceType = !missing.isEmpty() && !extra.isEmpty() + ? "扫描标签与组盘明细不一致" + : (!missing.isEmpty() ? "扫描缺少组盘标签" : "扫描到未知多余标签"); + // 差异集合按标签号排序后序列化,保证立库收到的缺失/多余清单稳定且为合法JSON数组 - rqrq + String differenceDetail = "实际扫描数: " + scanned.size() + + ", 组盘应有标签数: " + expected.size() + + "; 缺失标签=" + JSONObject.toJSONString(missing) + + "; 多余标签=" + JSONObject.toJSONString(extra); + result.setRemark("RFID门" + differenceType + "," + differenceDetail); + result.setResMsg("RFID门 复核失败,通知退出至入库口并调度 AGV 搬运至异常区: 入库" + + differenceType + "," + differenceDetail); + result.setActionDirective("EXIT_TO_INBOUND_PORT"); + } + log.info("海安入库RFID复核完成 - rqrq,site={},palletId={},扫描去重数={},库内标签数={},通过={}", + site, palletId, scanned.size(), expected.size(), passed); + return result; + } + /** * @author rqrq * @Description 处理海安立库出入库回调:按事务类型分流落库,到达出库口(原取货通知)执行幂等校验,目标区域固定A01并映射仓库/库位;仅认新中文 - rqrq diff --git a/src/main/java/com/gaotao/modules/autoWareHourceHaian/mapper/HaiAnPdaAutoWarehouseMapper.java b/src/main/java/com/gaotao/modules/autoWareHourceHaian/mapper/HaiAnPdaAutoWarehouseMapper.java index 4f12e3db..1cebcfe0 100644 --- a/src/main/java/com/gaotao/modules/autoWareHourceHaian/mapper/HaiAnPdaAutoWarehouseMapper.java +++ b/src/main/java/com/gaotao/modules/autoWareHourceHaian/mapper/HaiAnPdaAutoWarehouseMapper.java @@ -296,6 +296,11 @@ public interface HaiAnPdaAutoWarehouseMapper { */ Integer countPalletDetails(@Param("site") String site, @Param("palletId") String palletId); + /** + * 入库RFID复核只读标签号;palletId必填,site传入时限定栈板大site,空site按托盘号查询。NOLOCK可能读到短暂未提交明细并影响复核结果。- rqrq + */ + List listInboundRfidVerifySerialNos(@Param("site") String site, @Param("palletId") String palletId); + /** * @author rqrq * @Description 回写海安栈板empty_flag,保持空托盘状态可追踪 - rqrq diff --git a/src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml b/src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml index a9e75eca..ea0e24b4 100644 --- a/src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml +++ b/src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml @@ -505,6 +505,17 @@ AND pallet_id = #{palletId} + + + UPDATE haian_pallet