Browse Source

rfid校验

master
常熟吴彦祖 3 weeks ago
parent
commit
b7e1ee7a09
  1. 13
      src/main/java/com/gaotao/modules/autoWareHourceHaian/api/controller/HaiAnWmsMessageController.java
  2. 23
      src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyRequest.java
  3. 39
      src/main/java/com/gaotao/modules/autoWareHourceHaian/api/entity/HaiAnInboundRfidVerifyResult.java
  4. 9
      src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/HaiAnWmsMessageService.java
  5. 71
      src/main/java/com/gaotao/modules/autoWareHourceHaian/api/service/impl/HaiAnWmsMessageServiceImpl.java
  6. 5
      src/main/java/com/gaotao/modules/autoWareHourceHaian/mapper/HaiAnPdaAutoWarehouseMapper.java
  7. 11
      src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml

13
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

23
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<String> rfidBarcodes;
}

39
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;
}

9
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

71
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<String> scanned = new TreeSet<String>();
if (data.getRfidBarcodes() != null) {
for (String barcode : data.getRfidBarcodes()) {
if (StringUtils.hasText(barcode)) {
scanned.add(barcode.trim());
}
}
}
// 按托盘号和可选大site无锁查询本盘标签;mapper查询失败直接终止,不得把未知结果视作空盘放行 - rqrq
List<String> detailSerialNos = haiAnPdaAutoWarehouseMapper.listInboundRfidVerifySerialNos(site, palletId);
if (detailSerialNos == null) {
throw new RuntimeException("入库RFID复核查询托盘明细失败:" + palletId);
}
Set<String> expected = new TreeSet<String>();
for (String serialNo : detailSerialNos) {
if (StringUtils.hasText(serialNo)) {
expected.add(serialNo.trim());
}
}
// 缺失=库内有而门未扫到;多余=门扫到而库内没有。两边都空仍视为一致,不要求托盘主表存在 - rqrq
Set<String> missing = new TreeSet<String>(expected);
missing.removeAll(scanned);
Set<String> extra = new TreeSet<String>(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

5
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<String> listInboundRfidVerifySerialNos(@Param("site") String site, @Param("palletId") String palletId);
/**
* @author rqrq
* @Description 回写海安栈板empty_flag,保持空托盘状态可追踪 - rqrq

11
src/main/resources/mapper/autoWareHourceHaian/HaiAnPdaAutoWarehouseMapper.xml

@ -505,6 +505,17 @@
AND pallet_id = #{palletId}
</select>
<!-- 入库RFID复核按托盘号读取去重标签,site有值时限定栈板大site;按要求无锁,可能脏读或漏读并影响本次放行/退出判断 - rqrq -->
<select id="listInboundRfidVerifySerialNos" resultType="java.lang.String">
SELECT DISTINCT serial_no
FROM haian_pallet_detail WITH (NOLOCK)
WHERE pallet_id = #{palletId}
<if test="site != null and site != ''">
AND site = #{site}
</if>
ORDER BY serial_no
</select>
<!-- rqrq - 回写empty_flag -->
<update id="updatePalletEmptyFlag">
UPDATE haian_pallet

Loading…
Cancel
Save