常熟吴彦祖 3 months ago
parent
commit
7d66f8a1d7
  1. 57
      src/main/java/com/gaotao/modules/api/service/impl/WmsMessageServiceImpl.java
  2. 148
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsTaskServiceImpl.java
  3. 22
      src/main/resources/mapper/automatedWarehouse/WcsIntegrationMapper.xml

57
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. 更新成功日志

148
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<WmsOrderTask> 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);
}
}
}

22
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
<where>
AND c.is_deleted = '0'
AND (c.calling_flag IS NULL OR c.calling_flag != 'Y')
@ -128,10 +128,10 @@
<!-- ==================== 打托相关SQL - AI制作 ==================== -->
<!-- 检查栈板是否存在并获取栈板信息 - AI制作 -->
<!-- 检查栈板是否存在并获取栈板信息 - AI制作/rqrq -->
<select id="getPalletInfo" resultType="java.util.Map">
SELECT pallet_id, pallet_type, status, location_code, site, calling_flag
FROM pallet
FROM pallet WITH (NOLOCK)
WHERE site = #{site} AND pallet_id = #{palletId} AND is_deleted = '0'
</select>
@ -886,7 +886,7 @@
WHERE station_code = #{stationCode}
</select>
<!-- 获取栈板详细信息(包含palletType和autoSort以及托盘类型详情) - AI制作 -->
<!-- 获取栈板详细信息(包含palletType和autoSort以及托盘类型详情) - AI制作/rqrq -->
<select id="getPalletInfoWithTypeDetails" resultType="PalletData">
SELECT
p.site,
@ -904,9 +904,9 @@
pt.wcs_sore_type AS wcsSoreType,
pt.max_layer AS maxLayer,
pf.pallet_family_desc AS palletFamilyDesc
FROM pallet p
LEFT JOIN pallet_type pt ON p.site = pt.site AND p.pallet_type = pt.pallet_type
LEFT JOIN pallet_family pf ON p.site = pf.site AND p.pallet_family = pf.pallet_family
FROM pallet p WITH (NOLOCK)
LEFT JOIN pallet_type pt WITH (NOLOCK) ON p.site = pt.site AND p.pallet_type = pt.pallet_type
LEFT JOIN pallet_family pf WITH (NOLOCK) ON p.site = pf.site AND p.pallet_family = pf.pallet_family
WHERE p.site = #{site}
AND p.pallet_id = #{palletId}
AND p.is_deleted = '0'
@ -1372,7 +1372,7 @@
sore_type AS soreType,
auto_sort AS autoSort,
empty_flag AS emptyFlag
FROM pallet
FROM pallet WITH (NOLOCK)
WHERE site = #{site}
AND pallet_id = #{palletId}
AND is_deleted = '0'

Loading…
Cancel
Save