Browse Source

接口幂等性校验

master
常熟吴彦祖 8 months ago
parent
commit
8aaa246c97
  1. 37
      src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java
  2. 29
      src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsIntegrationMapper.java
  3. 33
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/PalletCancelServiceImpl.java
  4. 11
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java
  5. 50
      src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml

37
src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java

@ -316,8 +316,41 @@ public class WmsMessageServiceImpl implements WmsMessageService {
// 2. 参数验证 - rqrq
validateWcsWareHouseParams(inData);
if("取货通知".equals(inData.getTransTypeDesc())) {
// 3. 幂等性验证检查是否已处理过该消息 - rqrq
WcsCallbackTask existTask = wcsIntegrationMapper.getWcsCallbackTaskByBusinessKey(
inData.getSite(),
inData.getPalletId(),
inData.getTransTypeDesc(),
inData.getTaskNo(),
inData.getItemNo(),
inData.getToBarcode()
);
if (existTask != null) {
// 已存在相同的回调任务直接返回成功不执行任何业务逻辑 - rqrq
String idempotentMsg = String.format("消息已处理(幂等性验证),跳过重复操作 - taskId=%d, 栈板=%s, 类型=%s, taskNo=%s, itemNo=%d, toStation=%s, 原记录创建时间=%s",
existTask.getId(),
inData.getPalletId(),
inData.getTransTypeDesc(),
inData.getTaskNo(),
inData.getItemNo(),
inData.getToBarcode(),
existTask.getCreatedTime());
log.info(idempotentMsg + " - rqrq");
// 更新成功日志 - rqrq
long executionTime = System.currentTimeMillis() - startTime;
interfaceCallLogService.updateCallResult(logId, idempotentMsg, "SUCCESS", null, executionTime);
return idempotentMsg;
}
}
log.info("幂等性验证通过,开始处理新消息 - rqrq:栈板={}, 类型={}, taskNo={}, itemNo={}, toStation={}",
inData.getPalletId(), inData.getTransTypeDesc(), inData.getTaskNo(), inData.getItemNo(), inData.getToBarcode());
// 3. 根据业务类型分别处理 - rqrq
// 4. 根据业务类型分别处理 - rqrq
String result;
switch (inData.getTransTypeDesc()) {
case "入库":
@ -339,7 +372,7 @@ public class WmsMessageServiceImpl implements WmsMessageService {
throw new RuntimeException("不支持的事务类型:" + inData.getTransTypeDesc());
}
// 4. 更新成功日志 - rqrq
// 5. 更新成功日志 - rqrq
long executionTime = System.currentTimeMillis() - startTime;
interfaceCallLogService.updateCallResult(logId, result, "SUCCESS", null, executionTime);

29
src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsIntegrationMapper.java

@ -174,6 +174,16 @@ public interface WcsIntegrationMapper {
*/
WmsTransportTask getActivePalletTransportTask(@Param("site") String site, @Param("palletId") String palletId);
/**
* @Description 查询栈板在wms_transport_task表中是否有未完成的任务 - rqrq
* @param site 站点
* @param palletId 栈板编码
* @return 未完成的运输任务列表状态不是"已完成""已取消"
* @author rqrq
* @date 2025/11/26
*/
WmsTransportTask getUnfinishedTransportTaskByPallet(@Param("site") String site, @Param("palletId") String palletId);
/**
* 统计栈板明细数量 - AI制作
*/
@ -485,6 +495,25 @@ public interface WcsIntegrationMapper {
*/
void insertWcsCallbackTask(WcsCallbackTask callbackTask);
/**
* @Description 根据业务唯一键查询WCS回调任务是否已存在幂等性验证- rqrq
* @param site 站点
* @param palletId 栈板ID
* @param transTypeDesc 操作类型
* @param taskNo 任务号
* @param itemNo 明细号
* @param toStation 目标站点
* @return WCS回调任务如果已存在
* @author rqrq
* @date 2025/11/26
*/
WcsCallbackTask getWcsCallbackTaskByBusinessKey(@Param("site") String site,
@Param("palletId") String palletId,
@Param("transTypeDesc") String transTypeDesc,
@Param("taskNo") String taskNo,
@Param("itemNo") Integer itemNo,
@Param("toStation") String toStation);
/**
* 查询指定状态的WCS回调任务列表 - AI制作
*/

33
src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/PalletCancelServiceImpl.java

@ -44,32 +44,43 @@ public class PalletCancelServiceImpl implements PalletCancelService {
String site = data.getSite();
String palletId = data.getPalletId();
System.out.println("开始取消WCS组盘 - rqrq,palletId=" + palletId);
log.info("开始取消WCS组盘 - rqrq,palletId={}", palletId);
// 检查栈板是否有AGV调度任务 - rqrq
// 前置校验检查栈板是否已呼叫AGV送入立库wms_transport_task表- rqrq
WmsTransportTask unfinishedTask = wcsIntegrationMapper.getUnfinishedTransportTaskByPallet(site, palletId);
if (unfinishedTask != null) {
String taskNo = unfinishedTask.getTaskNo();
String status = unfinishedTask.getStatus();
log.warn("托盘已呼叫AGV送入立库,无法取消 - rqrq:palletId={}, taskNo={}, status={}", palletId, taskNo, status);
throw new RuntimeException("该托盘已经呼叫AGV送入立库,无法取消托盘,请先取消AGV任务(任务号:" + taskNo + ",状态:" + status + ")");
}
log.info("wms_transport_task表检查通过,无未完成任务 - rqrq");
// 检查栈板是否有AGV调度任务这个是旧逻辑保留兼容性- rqrq
WmsTransportTask transportTask = wcsIntegrationMapper.getActivePalletTransportTask(site, palletId);
if (transportTask != null) {
String taskStatus = transportTask.getStatus();
String taskNo = transportTask.getTaskNo();
System.out.println("栈板存在运输任务 - rqrq,taskNo=" + taskNo + ",status=" + taskStatus);
log.info("栈板存在运输任务 - rqrq,taskNo={}, status={}", taskNo, taskStatus);
if ("已下达".equals(taskStatus)) {
// 任务已下达到AGV不允许取消组盘 - rqrq
System.out.println("任务已下达到AGV,无法取消组盘 - rqrq");
log.warn("任务已下达到AGV,无法取消组盘 - rqrq,taskNo={}", taskNo);
throw new RuntimeException("已有AGV来提取,无法取消组盘");
} else if ("已预约".equals(taskStatus) || "已创建".equals(taskStatus)) {
// 任务未下达到AGV先取消AGV任务 - rqrq
System.out.println("任务状态为" + taskStatus + ",先取消AGV任务 - rqrq");
log.info("任务状态为{},先取消AGV任务 - rqrq,taskNo={}", taskStatus, taskNo);
try {
agvTaskService.cancelAgvTask(site, taskNo);
System.out.println("AGV任务取消成功 - rqrq");
log.info("AGV任务取消成功 - rqrq,taskNo={}", taskNo);
} catch (Exception e) {
System.out.println("AGV任务取消失败 - rqrq:" + e.getMessage());
log.error("AGV任务取消失败 - rqrq,taskNo={},error={}", taskNo, e.getMessage());
throw new RuntimeException("取消AGV任务失败:" + e.getMessage());
}
}
} else {
System.out.println("栈板不存在运输任务,继续取消组盘 - rqrq");
log.info("栈板不存在运输任务,继续取消组盘 - rqrq");
}
// 获取当前用户 - rqrq
@ -77,11 +88,11 @@ public class PalletCancelServiceImpl implements PalletCancelService {
// 1. 更新pallet_detail的wcs_flag=1 - rqrq
wcsIntegrationMapper.updateAllPalletDetailWcsFlagToOne(site, palletId);
System.out.println("已更新栈板明细wcs_flag为1 - rqrq");
log.info("已更新栈板明细wcs_flag为1 - rqrq,palletId={}", palletId);
// 2. 更新pallet的calling_flag=N - rqrq
wcsIntegrationMapper.updatePalletCallingFlag(site, palletId, "N", username);
System.out.println("已更新栈板calling_flag为N - rqrq");
log.info("已更新栈板calling_flag为N - rqrq,palletId={}", palletId);
// 3. 调用WCS API通知取消组盘 - rqrq
SpecialPalletTask pushData = new SpecialPalletTask();
@ -90,7 +101,7 @@ public class PalletCancelServiceImpl implements PalletCancelService {
pushData.setOperationType(1);
wcsApiService.SpecialPalletTask(pushData);
System.out.println("取消WCS组盘完成 - rqrq");
log.info("取消WCS组盘完成 - rqrq,palletId={}", palletId);
}
}

11
src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java

@ -2246,6 +2246,17 @@ public class WcsIntegrationServiceImpl implements WcsIntegrationService {
System.out.println("开始取消WCS组盘 - rqrq,palletId=" + palletId);
// 前置校验检查栈板是否已呼叫AGV送入立库wms_transport_task表- rqrq
WmsTransportTask unfinishedTask = wcsIntegrationMapper.getUnfinishedTransportTaskByPallet(site, palletId);
if (unfinishedTask != null) {
String taskNo = unfinishedTask.getTaskNo();
String status = unfinishedTask.getStatus();
System.err.println("托盘已呼叫AGV送入立库,无法取消 - rqrq:palletId=" + palletId + ", taskNo=" + taskNo + ", status=" + status);
throw new RuntimeException("该托盘已经呼叫AGV送入立库,无法取消托盘,请先取消AGV任务(任务号:" + taskNo + ",状态:" + status + ")");
}
System.out.println("wms_transport_task表检查通过,无未完成任务 - rqrq");
// 获取当前用户 - rqrq
String username = ((SysUserEntity) SecurityUtils.getSubject().getPrincipal()).getUsername();

50
src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml

@ -383,6 +383,27 @@
ORDER BY created_time DESC
</select>
<!-- rqrq - 查询栈板在wms_transport_task表中是否有未完成的任务 -->
<select id="getUnfinishedTransportTaskByPallet" resultType="WmsTransportTask">
SELECT TOP 1
id, site, task_no as taskNo, item_no as itemNo, source_type as sourceType,
source_bill_no as sourceBillNo, source_line_id as sourceLineId,
part_no as partNo, qty, batch_no as batchNo, serial_no as serialNo,
from_location as fromLocation, to_location as toLocation,
pallet_id as palletId, agv_code as agvCode, priority, status,
wms_send_time as wmsSendTime, wcs_receive_time as wcsReceiveTime,
start_time as startTime, complete_time as completeTime,
error_code as errorCode, error_msg as errorMsg,
created_by as createdBy, created_time as createdTime, updated_time as updatedTime,
wcs_task_id as wcsTaskId, finish_qty as finishQty, wms_status as wmsStatus,
pallet_type as palletType, to_area as toArea
FROM wms_transport_task WITH (NOLOCK)
WHERE site = #{site}
AND pallet_id = #{palletId}
AND status NOT IN ('已完成', '已取消')
ORDER BY created_time DESC
</select>
<!-- 统计栈板明细数量 - AI制作 -->
<select id="countPalletDetails" resultType="java.lang.Integer">
SELECT COUNT(1)
@ -905,6 +926,35 @@
where task_no=#{taskNo} and site=#{site}
</select>
<!-- rqrq - 根据业务唯一键查询WCS回调任务是否已存在(幂等性验证)-->
<select id="getWcsCallbackTaskByBusinessKey" resultType="WcsCallbackTask">
SELECT TOP 1
id,
site,
pallet_id AS palletId,
trans_type_desc AS transTypeDesc,
to_warehouse_id AS toWarehouseId,
to_location_id AS toLocationId,
status,
created_time AS createdTime,
process_start_time AS processStartTime,
process_end_time AS processEndTime,
error_msg AS errorMsg,
retry_count AS retryCount,
remark,
task_no AS taskNo,
item_no AS itemNo,
to_station AS toStation
FROM wcs_callback_task
WHERE site = #{site}
AND pallet_id = #{palletId}
AND trans_type_desc = #{transTypeDesc}
AND task_no = #{taskNo}
AND item_no = #{itemNo}
AND to_station = #{toStation}
ORDER BY created_time DESC
</select>
<!-- 插入WCS回调任务 - AI制作 -->
<insert id="insertWcsCallbackTask" useGeneratedKeys="true" keyProperty="id">
INSERT INTO wcs_callback_task (

Loading…
Cancel
Save