diff --git a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java index e93c98b..b34696f 100644 --- a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java +++ b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/AutoSortServiceImpl.java @@ -259,10 +259,16 @@ public class AutoSortServiceImpl implements AutoSortService { wcsIntegrationMapper.batchDeletePalletDetailsBySerialNos(callback.getSite(), serialNosToDelete); log.info("批量删除{}条旧记录 - rqrq", serialNosToDelete.size()); + // 收集所有受影响的原栈板ID(用于后续更新empty_flag)- rqrq + Set affectedPalletIds = new HashSet<>(); + // 循环记录每个标签的扫出操作日志(从原栈板扫出)- rqrq for (String serialNo : serialNosToDelete) { try { String originalPalletId = serialToExistingPalletMap.get(serialNo); + if (originalPalletId != null) { + affectedPalletIds.add(originalPalletId); + } handlingUnitOperationLogService.logHandlingUnitOperation( callback.getSite(), // 站点 serialNo, // 条码号 @@ -280,6 +286,16 @@ public class AutoSortServiceImpl implements AutoSortService { } } log.info("扫出日志记录完成 - rqrq"); + + // 更新所有受影响的原栈板的empty_flag - rqrq + for (String affectedPalletId : affectedPalletIds) { + // 检查原栈板是否还有明细,根据结果更新empty_flag - rqrq + int remainingCount = wcsIntegrationMapper.countPalletDetails(callback.getSite(), affectedPalletId); + String emptyFlag = (remainingCount == 0) ? "Y" : "N"; + wcsIntegrationMapper.updatePalletEmptyFlag(callback.getSite(), affectedPalletId, emptyFlag, username); + log.info("更新原栈板empty_flag - rqrq,palletId={},remainingCount={},emptyFlag={}", + affectedPalletId, remainingCount, emptyFlag); + } } // 6.4 批量插入(排除已在目标托盘的记录)- rqrq diff --git a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/InventoryDiscrepancyServiceImpl.java b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/InventoryDiscrepancyServiceImpl.java index 2a4b1a6..3050a6d 100644 --- a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/InventoryDiscrepancyServiceImpl.java +++ b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/InventoryDiscrepancyServiceImpl.java @@ -294,6 +294,12 @@ public class InventoryDiscrepancyServiceImpl implements InventoryDiscrepancyServ System.out.println("原栈板非空,更新empty_flag='N' - rqrq"); } + // 7.1 更新虚拟栈板的empty_flag为N(已有物料转入)- rqrq + if (!removedSerialNos.isEmpty()) { + wcsIntegrationMapper.updatePalletEmptyFlag(callback.getSite(), virtualPalletId, "N", username); + System.out.println("虚拟栈板已有物料,更新empty_flag='N' - rqrq,虚拟栈板=" + virtualPalletId); + } + // 8. 更新回调记录状态为已完成 - rqrq wcsCallbackPalletScanMapper.updateProcessStatus( callback.getId(), diff --git a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/KitTransportProcessServiceImpl.java b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/KitTransportProcessServiceImpl.java index f9ee698..d1a9688 100644 --- a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/KitTransportProcessServiceImpl.java +++ b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/KitTransportProcessServiceImpl.java @@ -18,6 +18,125 @@ import java.util.stream.Collectors; * @Description 齐套运输处理服务实现类(专门处理单个订单的齐套运输,避免事务自调用失效)- rqrq * @Author rqrq * @Date 2025/10/21 + * + *

================== 齐套运输业务逻辑说明 ==================

+ * + *

一、什么是齐套?

+ *
+ * 齐套是指一个生产订单(由notifyNo+itemNo确定)所需的所有物料都已经从立库出库完成,
+ * 并且这些物料所在的栈板都已离开分拣位(D1/D2/R1-R4/J1-J4),进入缓存区(Z104)等待配送。
+ * 
+ * 齐套的目的是:当一个订单的所有物料都准备好后,统一发起运输任务,将栈板配送到生产区域。
+ * 
+ * + *

二、齐套判断条件(必须同时满足)

+ *
+ * 条件1:订单的所有物料明细(so_issue_notify_order_material_list_detail)的 out_wcs_flag='Y'
+ *        即:totalCount == outCount(总数量 = 已出库数量)
+ * 
+ * 条件2:订单所有物料关联的栈板都不在分拣位
+ *        分拣位列表:D1, D2, R1, R2, R3, R4, J1, J2, J3, J4
+ *        判断方式:遍历订单物料的serialNo → pallet_detail.pallet_id → pallet.location_code
+ *                 检查所有location_code是否都不在分拣位列表中
+ * 
+ * + *

三、齐套处理流程(5个步骤)

+ *
+ * 步骤1:检查物料出库情况
+ *        - 查询订单物料总数(totalCount)和已出库数(outCount,即out_wcs_flag='Y'的数量)
+ *        - 如果 totalCount != outCount,说明物料未全部出库,跳过此订单
+ *        - 如果 totalCount == 0,说明订单没有物料明细,跳过
+ * 
+ * 步骤2:检查栈板位置
+ *        - 查询订单所有物料关联的栈板位置(location_code)
+ *        - 如果位置列表为空,说明物料已被人工取走,直接标记订单完成
+ *        - 如果有任何栈板在分拣位,说明物料还在分拣中,跳过此订单
+ * 
+ * 步骤3:获取可用栈板
+ *        - 查询在缓存区(Z104)中,calling_flag='N'且站点status_db=1的栈板
+ *        - 这些是可以发起运输任务的栈板
+ *        - 如果没有可用栈板,说明已随之前任务运走,直接标记transport_flag='Y'
+ * 
+ * 步骤4:发起运输任务
+ *        - 逐个为可用栈板创建运输任务
+ *        - 特殊处理:如果订单有条码在分切区,第一个栈板目的地改为分切区(Z106)
+ *        - 每个运输任务独立事务,失败不影响其他栈板
+ * 
+ * 步骤5:更新状态
+ *        - 只有全部栈板都成功发起任务,才标记transport_flag='Y'
+ *        - 如果有失败的栈板,保持transport_flag='N',等待下次定时任务处理
+ *        - 当申请单下所有订单都transport_flag='Y'时,更新申请单push_wcs_flag='出库完成'
+ * 
+ * + *

四、相关数据表

+ *
+ * 1. so_issue_notify_order_list:领料申请单订单表
+ *    - notify_no + item_no 确定一个订单
+ *    - production_area:生产区域(运输目的地)
+ *    - transport_flag:运输标记(N=未运输,Y=已运输)
+ *    - status:订单状态(ISSUE=待领料)
+ *    - push_wms_flag:推送WMS标记(Y=已推送)
+ * 
+ * 2. so_issue_notify_order_material_list_detail:订单物料明细表
+ *    - notify_no + item_no 关联订单
+ *    - serial_no:物料序列号(条码)
+ *    - out_wcs_flag:出库标记(N=未出库,Y=已出库)
+ * 
+ * 3. pallet_detail:栈板明细表
+ *    - serial_no 关联物料条码
+ *    - pallet_id:所在栈板
+ * 
+ * 4. pallet:栈板表
+ *    - pallet_id:栈板编码
+ *    - location_code:所在站点(关联agv_station)
+ *    - calling_flag:是否正在被调用(Y/N)
+ * 
+ * 5. agv_station:AGV站点表
+ *    - station_code:站点编码
+ *    - status_db:站点状态(0=空闲,1=有货,2=待放货,3=待取货)
+ *    - area_type:区域类型(如Z104=缓存区)
+ * 
+ * 6. so_issue_notify_header:领料申请单表头
+ *    - notify_no:申请单号
+ *    - push_wcs_flag:推送WCS状态(Y=已推送,出库完成=全部订单运输完成)
+ * 
+ * + *

五、定时任务调度

+ *
+ * 1. 定时任务类:WcsTaskScheduler.scheduleKitTransportCheck()
+ *    - 每100秒执行一次
+ *    - 调用 KitTransportService.processKitTransport()
+ * 
+ * 2. 处理逻辑:KitTransportServiceImpl.processKitTransport()
+ *    - 查询待处理订单(status='ISSUE', push_wms_flag='Y', transport_flag='N')
+ *    - 每次最多处理100个订单
+ *    - 逐个调用 processOrderKitTransport() 处理
+ *    - 每个订单处理后休息1秒,避免死锁
+ * 
+ * 3. 单订单处理:本类.processOrderKitTransport()
+ *    - 处理单个订单的齐套判断和运输任务创建
+ *    - 返回true表示已齐套并处理,返回false表示未齐套或处理失败
+ * 
+ * + *

六、特殊场景处理

+ *
+ * 场景1:物料被人工取走
+ *        - 表现:订单物料全部out_wcs_flag='Y',但栈板位置列表为空
+ *        - 处理:直接标记transport_flag='Y',认为已完成
+ * 
+ * 场景2:齐套但无可用栈板
+ *        - 表现:订单齐套了,但缓存区没有可用栈板
+ *        - 原因:可能已随之前的订单运走(多个订单共用栈板)
+ *        - 处理:直接标记transport_flag='Y'
+ * 
+ * 场景3:分切区物料
+ *        - 表现:订单有物料的仓库是分切区(Z999)
+ *        - 处理:第一个栈板目的地改为分切区(Z106),其他栈板照常去生产区域
+ * 
+ * 场景4:部分栈板运输失败
+ *        - 表现:部分栈板发起运输任务失败
+ *        - 处理:保持transport_flag='N',等待下次定时任务重试
+ * 
*/ @Slf4j @Service diff --git a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java index d691c09..f0c7f1e 100644 --- a/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java +++ b/src/main/java/com/gaotao/modules/automatedWarehouse/service/impl/WcsIntegrationServiceImpl.java @@ -3020,6 +3020,14 @@ public class WcsIntegrationServiceImpl implements WcsIntegrationService { } } log.info("条码转移日志记录完成 - rqrq"); + + // 更新来源栈板的empty_flag为Y(合托后来源栈板变空)- rqrq + wcsIntegrationMapper.updatePalletEmptyFlag(site, sourcePalletId, "Y", username); + log.info("更新来源栈板empty_flag='Y' - rqrq,palletId={}", sourcePalletId); + + // 更新目标栈板的empty_flag为N(合托后目标栈板有货)- rqrq + wcsIntegrationMapper.updatePalletEmptyFlag(site, targetPalletId, "N", username); + log.info("更新目标栈板empty_flag='N' - rqrq,palletId={}", targetPalletId); log.info("合托操作完成 - rqrq,已将{}条明细从{}转移到{}", sourceDetailList.size(), sourcePalletId, targetPalletId); }