Browse Source

自动分拣

master
常熟吴彦祖 4 months ago
parent
commit
e2d1c9d9a7
  1. 11
      src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsCallbackPalletScanMapper.java
  2. 2
      src/main/java/com/gaotao/modules/automatedWarehouse/service/AutoSortService.java
  3. 188
      src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java
  4. 10
      src/main/resources/mapper/automatedWarehouse/WcsCallbackPalletScanMapper.xml

11
src/main/java/com/gaotao/modules/automatedWarehouse/mapper/WcsCallbackPalletScanMapper.java

@ -35,6 +35,17 @@ public interface WcsCallbackPalletScanMapper extends BaseMapper<WcsCallbackPalle
*/
void updateProcessStatus(@Param("id") Long id, @Param("processStatus") String processStatus, @Param("errorMsg") String errorMsg);
/**
* @Description 使用乐观锁更新处理状态防止重复处理- rqrq
* @param id 记录ID
* @param oldStatus 原状态
* @param newStatus 新状态
* @return 更新的行数0表示更新失败
* @author rqrq
* @date 2025/10/30
*/
int updateProcessStatusWithLock(@Param("id") Long id, @Param("oldStatus") String oldStatus, @Param("newStatus") String newStatus);
/**
* @Description 增加重试次数 - rqrq
* @param id 记录ID

2
src/main/java/com/gaotao/modules/automatedWarehouse/service/AutoSortService.java

@ -16,6 +16,6 @@ public interface AutoSortService {
* @author rqrq
* @date 2025/10/09
*/
void processAutoSortCallback(WcsCallbackPalletScan callback) throws Exception;
void processAutoSortCallback(WcsCallbackPalletScan callback);
}

188
src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java

@ -61,28 +61,35 @@ public class AutoSortServiceImpl implements AutoSortService {
* @date 2025/10/09
*/
@Override
@Transactional
public void processAutoSortCallback(WcsCallbackPalletScan callback) throws Exception {
@Transactional(rollbackFor = Exception.class)
public void processAutoSortCallback(WcsCallbackPalletScan callback) {
System.out.println("开始处理WCS自动拣选回调记录 - rqrq,palletId=" + callback.getPalletId()
+ ",分拣方式=" + callback.getSoreType() + "(1=气胀轴, 2=抱箱)");
try {
// 1. 更新回调记录状态为处理中乐观锁- rqrq
wcsCallbackPalletScanMapper.updateProcessStatus(callback.getId(), "PROCESSING", null);
// 1. 使用乐观锁更新回调记录状态为处理中防止重复处理- rqrq
int lockResult = wcsCallbackPalletScanMapper.updateProcessStatusWithLock(
callback.getId(), callback.getProcessStatus(), "PROCESSING");
if (lockResult == 0) {
System.out.println("乐观锁更新失败 - rqrq:记录可能已被其他线程处理,跳过");
return; // 获取锁失败直接返回 - rqrq
}
System.out.println("乐观锁更新成功 - rqrq:状态已更新为处理中");
// 2. 解析jsonStr为PushPalletDetailDto对象 - rqrq
if (!StringUtils.hasText(callback.getJsonStr())) {
throw new Exception("jsonStr为空,无法解析栈板和明细信息");
throw new RuntimeException("jsonStr为空,无法解析栈板和明细信息");
}
PushPalletDetailDto pushData = JSONObject.parseObject(callback.getJsonStr(), PushPalletDetailDto.class);
if (pushData == null) {
throw new Exception("jsonStr解析为PushPalletDetailDto失败");
throw new RuntimeException("jsonStr解析为PushPalletDetailDto失败");
}
String targetPalletId = pushData.getPalletBarcode();
if (!StringUtils.hasText(targetPalletId)) {
throw new Exception("PushPalletDetailDto中未找到目标栈板编码(palletBarcode)");
throw new RuntimeException("PushPalletDetailDto中未找到目标栈板编码(palletBarcode)");
}
// 解析明细列表 - rqrq
@ -151,12 +158,22 @@ public class AutoSortServiceImpl implements AutoSortService {
List<String> processedSerialNos = new ArrayList<>();
for (IncrementalDetail detail : incrementalDetails) {
// 先检查是否在其他栈板如果是则删除 - rqrq
// 先检查是否在其他栈板 - rqrq
Map<String, Object> existingPalletInfo = wcsIntegrationMapper.findPalletByLabel(
callback.getSite(), detail.serialNo);
if (existingPalletInfo != null) {
String existingPalletId = (String) existingPalletInfo.get("palletId");
System.out.println("条码" + detail.serialNo + "在栈板" + existingPalletId + "中,先删除旧记录 - rqrq");
// 如果已经在目标栈板上跳过避免删除重建导致数据丢失- rqrq
if (targetPalletId.equals(existingPalletId)) {
System.out.println("条码" + detail.serialNo + "已在目标栈板上,跳过 - rqrq");
processedSerialNos.add(detail.serialNo);
continue;
}
// 在其他栈板先删除 - rqrq
System.out.println("条码" + detail.serialNo + "在其他栈板" + existingPalletId + "中,先删除旧记录 - rqrq");
wcsIntegrationMapper.deletePalletDetailBySerialNo(callback.getSite(), detail.serialNo);
}
@ -168,123 +185,116 @@ public class AutoSortServiceImpl implements AutoSortService {
System.out.println("扫进成功 - rqrq:serialNo=" + detail.serialNo +
", position=" + detail.position + ", layer=" + detail.layer);
// 更新SOIssueNotifyOrderMaterialList_detail的out_wcs_flag为Y - rqrq
try {
// wcsIntegrationMapper.updateSOIssueNotifyDetailOutWcsFlagByTask(
// callback.getSite(), callback.getTaskNo(), callback.getItemNo(), detail.serialNo);
// System.out.println("更新out_wcs_flag成功 - rqrq:taskNo=" + callback.getTaskNo() +
// ", itemNo=" + callback.getItemNo() + ", serialNo=" + detail.serialNo);
//这边不应该处理out_wcs_flag 会影响下面数据
// 记录处理成功的序列号 - rqrq
processedSerialNos.add(detail.serialNo);
} catch (Exception ex) {
// 更新失败不影响主流程只打印日志 - rqrq
// System.err.println("更新out_wcs_flag失败 - rqrq:" + ex.getMessage());
}
// 记录处理成功的序列号 - rqrq
processedSerialNos.add(detail.serialNo);
}
// 7. 根据序列号查询SOIssueNotifyOrderMaterialList_detail明细获取task_seq等信息 - rqrq
if (!processedSerialNos.isEmpty()) {
System.out.println("开始更新wms_order_task_detail状态 - rqrq,序列号数量=" + processedSerialNos.size());
try {
// 查询申请单明细 - rqrq
List<com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> notifyDetails =
wcsIntegrationMapper.getSOIssueNotifyDetailsBySerialNos(callback.getSite(), processedSerialNos);
System.out.println("查询到申请单明细数量:" + notifyDetails.size() + " - rqrq");
// 按task_ref+task_item+task_seq分组去重 - rqrq
Map<String, com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> taskKeyMap = new HashMap<>();
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : notifyDetails) {
// 跳过task_seq为0或null的记录 - rqrq
if (notifyDetail.getTaskSeq() == null || notifyDetail.getTaskSeq() == 0) {
System.out.println("跳过task_seq为0或null的记录,序列号=" + notifyDetail.getSerialNo() + " - rqrq");
continue;
}
String taskKey = notifyDetail.getTaskRef() + "_" + notifyDetail.getTaskItem() + "_" + notifyDetail.getTaskSeq();
taskKeyMap.put(taskKey, notifyDetail);
}
System.out.println("去重后的任务明细数量:" + taskKeyMap.size() + " - rqrq");
// 遍历更新wms_order_task_detail状态 - rqrq
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskKeyMap.values()) {
String taskNo = notifyDetail.getTaskRef();
Integer itemNo = notifyDetail.getTaskItem();
Integer seqNo = notifyDetail.getTaskSeq();
wcsIntegrationMapper.updateWmsOrderTaskDetailStatusForSorting(callback.getSite(), taskNo, itemNo, seqNo);
System.out.println("更新wms_order_task_detail状态为已完成已分拣,taskNo=" + taskNo +
", itemNo=" + itemNo + ", seqNo=" + seqNo + " - rqrq");
// 查询申请单明细 - rqrq
List<com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> notifyDetails =
wcsIntegrationMapper.getSOIssueNotifyDetailsBySerialNos(callback.getSite(), processedSerialNos);
System.out.println("查询到申请单明细数量:" + notifyDetails.size() + " - rqrq");
// 按task_ref+task_item+task_seq分组去重 - rqrq
Map<String, com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> taskKeyMap = new HashMap<>();
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : notifyDetails) {
// 跳过task_seq为0或null的记录 - rqrq
if (notifyDetail.getTaskSeq() == null || notifyDetail.getTaskSeq() == 0) {
System.out.println("跳过task_seq为0或null的记录,序列号=" + notifyDetail.getSerialNo() + " - rqrq");
continue;
}
// 8. 检查每个任务的所有明细是否都已完成如果是则更新主表状态为已完成 - rqrq
// 收集所有涉及的taskNo+itemNo组合去重- rqrq
Map<String, com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> taskMainKeyMap = new HashMap<>();
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskKeyMap.values()) {
String taskMainKey = notifyDetail.getTaskRef() + "_" + notifyDetail.getTaskItem();
taskMainKeyMap.put(taskMainKey, notifyDetail);
}
System.out.println("去重后的任务主表数量:" + taskMainKeyMap.size() + " - rqrq");
String taskKey = notifyDetail.getTaskRef() + "_" + notifyDetail.getTaskItem() + "_" + notifyDetail.getTaskSeq();
taskKeyMap.put(taskKey, notifyDetail);
}
System.out.println("去重后的任务明细数量:" + taskKeyMap.size() + " - rqrq");
// 遍历更新wms_order_task_detail状态 - rqrq
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskKeyMap.values()) {
String taskNo = notifyDetail.getTaskRef();
Integer itemNo = notifyDetail.getTaskItem();
Integer seqNo = notifyDetail.getTaskSeq();
// 遍历检查并更新主表状态 - rqrq
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskMainKeyMap.values()) {
String taskNo = notifyDetail.getTaskRef();
Integer itemNo = notifyDetail.getTaskItem();
// 检查该任务的所有明细是否都已完成 - rqrq
int unfinishedCount = wcsIntegrationMapper.checkAllTaskDetailCompleted(callback.getSite(), taskNo, itemNo);
if (unfinishedCount == 0) {
// 所有明细都已完成更新主表状态为已完成 - rqrq
wcsIntegrationMapper.updateWmsOrderTaskStatusCompleted(callback.getSite(), taskNo, itemNo);
System.out.println("任务所有明细都已完成,更新wms_order_task主表状态为已完成,taskNo=" + taskNo +
", itemNo=" + itemNo + " - rqrq");
} else {
System.out.println("任务还有" + unfinishedCount + "个明细未完成,暂不更新主表状态,taskNo=" + taskNo +
", itemNo=" + itemNo + " - rqrq");
}
}
wcsIntegrationMapper.updateWmsOrderTaskDetailStatusForSorting(callback.getSite(), taskNo, itemNo, seqNo);
System.out.println("更新wms_order_task_detail状态为已完成已分拣,taskNo=" + taskNo +
", itemNo=" + itemNo + ", seqNo=" + seqNo + " - rqrq");
}
// 8. 检查每个任务的所有明细是否都已完成如果是则更新主表状态为已完成 - rqrq
// 收集所有涉及的taskNo+itemNo组合去重- rqrq
Map<String, com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail> taskMainKeyMap = new HashMap<>();
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskKeyMap.values()) {
String taskMainKey = notifyDetail.getTaskRef() + "_" + notifyDetail.getTaskItem();
taskMainKeyMap.put(taskMainKey, notifyDetail);
}
System.out.println("去重后的任务主表数量:" + taskMainKeyMap.size() + " - rqrq");
// 遍历检查并更新主表状态 - rqrq
for (com.gaotao.modules.notify.entity.SOIssueNotifyOrderMaterialListDetail notifyDetail : taskMainKeyMap.values()) {
String taskNo = notifyDetail.getTaskRef();
Integer itemNo = notifyDetail.getTaskItem();
System.out.println("更新wms_order_task_detail和wms_order_task状态完成 - rqrq");
// 检查该任务的所有明细是否都已完成 - rqrq
int unfinishedCount = wcsIntegrationMapper.checkAllTaskDetailCompleted(callback.getSite(), taskNo, itemNo);
} catch (Exception ex) {
// 更新任务状态失败不影响主流程只打印日志 - rqrq
System.err.println("更新任务状态失败 - rqrq:" + ex.getMessage());
ex.printStackTrace();
if (unfinishedCount == 0) {
// 所有明细都已完成更新主表状态为已完成 - rqrq
wcsIntegrationMapper.updateWmsOrderTaskStatusCompleted(callback.getSite(), taskNo, itemNo);
System.out.println("任务所有明细都已完成,更新wms_order_task主表状态为已完成,taskNo=" + taskNo +
", itemNo=" + itemNo + " - rqrq");
} else {
System.out.println("任务还有" + unfinishedCount + "个明细未完成,暂不更新主表状态,taskNo=" + taskNo +
", itemNo=" + itemNo + " - rqrq");
}
}
System.out.println("更新wms_order_task_detail和wms_order_task状态完成 - rqrq");
}
// 9. 更新out_wcs_flag标识 - rqrq
for (IncrementalDetail detail : incrementalDetails) {
wcsIntegrationMapper.updateSOIssueNotifyDetailOutWcsFlagByTask(
callback.getSite(), callback.getTaskNo(), callback.getItemNo(), detail.serialNo);
System.out.println("更新out_wcs_flag成功 - rqrq:taskNo=" + callback.getTaskNo() +
", itemNo=" + callback.getItemNo() + ", serialNo=" + detail.serialNo);
}
// 9. 更新空栈板标记 - rqrq
// 10. 查询栈板信息并创建配送任务 - rqrq
Pallet pallet = wcsIntegrationMapper.getPalletByCode(callback.getSite(), callback.getPalletId());
if (pallet == null) {
throw new RuntimeException("栈板不存在:" + callback.getPalletId());
}
// 11. 更新空栈板标记 - rqrq
wcsIntegrationMapper.updatePalletEmptyFlag(callback.getSite(), targetPalletId, "N", username);
// 12. 创建配送任务 - rqrq
ScheduleDeliveryTask scheduleDeliveryTask = new ScheduleDeliveryTask();
scheduleDeliveryTask.setSite(callback.getSite());
scheduleDeliveryTask.setSourceBillNo(callback.getTaskNo());
try {
scheduleDeliveryTask.setSourceLineId(Long.valueOf(callback.getItemNo()));
} catch (NumberFormatException e) {
// 解析失败返回默认值 0
// 解析失败返回默认值 0 - rqrq
scheduleDeliveryTask.setSourceLineId(0L);
}
scheduleDeliveryTask.setPalletId(callback.getPalletId());
Pallet pallet = wcsIntegrationMapper.getPalletByCode(callback.getSite(), callback.getPalletId());
scheduleDeliveryTask.setFromLocation(pallet.getLocationCode());
scheduleDeliveryTask.setToArea("Z104");
scheduleDeliveryTask.setUsername( "SYS_WMS");
scheduleDeliveryTask.setUsername("SYS_WMS");
autoTaskService.scheduleDeliveryTask(scheduleDeliveryTask);
// 10. 更新回调记录状态为已完成 - rqrq
// 13. 更新回调记录状态为已完成 - rqrq
wcsCallbackPalletScanMapper.updateProcessStatus(callback.getId(), "COMPLETED",
"成功处理" + incrementalDetails.size() + "条增量数据");
System.out.println("WCS自动拣选回调处理完成 - rqrq,palletId=" + targetPalletId
+ ",增量数据=" + incrementalDetails.size() + "条");
} catch (RuntimeException e) {
} catch (Exception e) {
System.err.println("处理WCS自动拣选回调失败 - rqrq,palletId=" + callback.getPalletId()
+ ",错误:" + e.getMessage());
e.printStackTrace();
@ -295,7 +305,7 @@ public class AutoSortServiceImpl implements AutoSortService {
// 增加重试次数 - rqrq
wcsCallbackPalletScanMapper.incrementRetryCount(callback.getId());
throw e;
throw new RuntimeException("处理WCS自动拣选回调失败:" + e.getMessage(), e);
}
}
}

10
src/main/resources/mapper/automatedWarehouse/WcsCallbackPalletScanMapper.xml

@ -40,6 +40,16 @@
WHERE id = #{id}
</update>
<!-- rqrq - 使用乐观锁更新处理状态(防止重复处理)-->
<update id="updateProcessStatusWithLock">
UPDATE wcs_callback_pallet_scan
SET process_status = #{newStatus},
process_time = GETDATE(),
updated_at = GETDATE()
WHERE id = #{id}
AND process_status = #{oldStatus}
</update>
<!-- rqrq - 增加重试次数 -->
<update id="incrementRetryCount">
UPDATE wcs_callback_pallet_scan

Loading…
Cancel
Save