10 KiB
WaveRuleMatchService 当前流程文档
对应代码:
wms-wave/src/main/groovy/com/ittx/wms/wave/service/shopee/WaveRuleMatchService.groovy本文只描述当前代码已经存在的流程,不保留已删除方法或历史占位方案。
1. 服务职责
WaveRuleMatchService 负责 Shopee 自动集波的工作站调度、规则匹配、Shopee 波次号准备、格口占用、picking task 同步、内部 wave 创建与运行,以及失败回滚和处理日志。
当前 ticketType 分流:
| ticketType | 类型 | 分流方法 |
|---|---|---|
1 |
SALES_TASK | assignTaskTicket |
2 |
SALES_ORDER | assignOrder |
3 |
RTS | assignOrder |
4 |
MTO_ORDER | assignOrder |
5 |
MTO_TASK | assignTaskTicket |
6 |
RT | assignRt |
MTO_TASK 保持任务单流程;SALES_ORDER、MTO_ORDER、RTS 共用订单流程。
2. 调度入口
2.1 assignShopeeWaveToAcceptedWorkStations
计划任务入口:
assignShopeeWaveToAcceptedWorkStations(session, warehouseCode, workStationCode)
├─ 查询当前仓库可接单且启用的拣选工作站
├─ 指定 workStationCode 时只处理该工作站
├─ 按可用空格口数量降序、工作站 ID 升序排序
├─ 逐个调用 matchByStation(session, workstation)
└─ 单个工作站失败不阻断后续工作站
只要方法已经接收 WcsWorkStation,shipmentType 都直接读取 workstation.shipmentType,不再单独传参。
2.2 matchByStation
matchByStation(session, workstation)
├─ 校验 workstation.status=ENABLE
├─ 校验 warehouseCode
├─ 校验 acceptStatus=OPEN
├─ 获取 warehouseCode 维度 Redis 锁
├─ ORDER_PICK
│ └─ assignSingles
└─ BATCH_PICK
├─ 查询操作员技能与工作站 waveRule 交集
├─ findEnabledRules
├─ fillShortage,优先补当前工作站已占用格口
└─ 无补单结果时按规则 ticketType 分流
├─ 1/5 → assignTaskTicket
├─ 2/3/4 → assignOrder
└─ 6 → assignRt
仓库级锁覆盖同一工作站匹配轮次,最终在 finally 中解锁并记录结束日志。
3. 快速拣选
assignSingles 处理 pickType=1 候选,每单独占一个格口和一个内部 wave。
assignSingles(warehouseCode, workstation)
├─ findSingleEmptyCells(workstation.id)
├─ findSingleShipments(warehouseCode, emptyCellCount, workstation)
└─ 逐单处理
├─ findShipmentExt
├─ 确定 Shopee 波次号
│ ├─ shopeeWaveCode 已有值 → 直接使用
│ ├─ RT → 使用 shipmentCode
│ └─ 其他 → acquireWave
├─ RT → backfillRtShopeeWaveCode
├─ 非 RT 且使用已有波次号 → createInternalShopeeWave
├─ occupySingleCell
├─ createWave
├─ syncShopeePickingTaskAndFilterAcceptedShipments(..., ticketType)
│ └─ 仅 RT 跳过外部接口
├─ updateLocalShopeeWaveBinding
└─ addToWave
快速拣选不写 waveRule,调用 updateLocalShopeeWaveBinding 时传空规则编码。
4. 任务单分流
SALES_TASK 与 MTO_TASK 共用 assignTaskTicket。
assignTaskTicket(warehouseCode, workstation, rule, ticketType)
├─ findSingleEmptyCells(workstation.id, rule)
├─ findTaskTicketShipments(..., ticketType, rule)
└─ 逐单处理
├─ 从 shipment_header_ext1 读取 shopeeWaveCode
├─ createInternalShopeeWave
│ └─ code + ticketType 不存在时创建 shopee_wave
├─ occupySingleCell
├─ createWave
├─ syncShopeePickingTaskAndFilterAcceptedShipments(..., ticketType)
├─ updateLocalShopeeWaveBinding
└─ addToWave
任务单同步完成后直接执行本地绑定,不再经过独立绑定转发方法,也不重复执行 Shopee 波次锁和可用性检查。
5. 订单分流
SALES_ORDER、MTO_ORDER、RTS 共用 assignOrder。
assignOrder(warehouseCode, workstation, rule, ticketType)
├─ findUnusedCells(workstation.id, rule)
└─ 对首个可用格口
├─ findAvailableShipments(..., ticketType)
├─ hasEmptyCellMinShipments
├─ acquireWave(warehouseCode, ticketType)
└─ assignAcquiredWaveToCell
└─ assignToCell
首次分配每轮只启动一个新格口;后续容量缺口由 fillShortage 优先处理。
6. RT 分流
assignRt 是 RT 专用的一单一格口流程:
assignRt(warehouseCode, workstation, rule)
├─ findSingleEmptyCells(workstation.id, rule)
├─ findRtTicketShipments
└─ 逐单处理
├─ 使用 shipmentCode 作为本地 Shopee 波次号
├─ backfillRtShopeeWaveCode
├─ occupySingleCell
├─ createWave
├─ updateLocalShopeeWaveBinding
└─ addToWave
RT 不申请接口号段,也不调用 Shopee picking task 外部接口。
7. 缺口补单
fillShortage 只按关联 shopee_wave.status=200(USING) 判断格口是否需要进入补单检查。
fillShortage(warehouseCode, workstation)
├─ findShortage(workstation.id)
├─ 逐格口读取 currentWaveRule 与 ticketType
├─ calcNeedQty
├─ 记录需要补单的格口处理日志
├─ resolveBoundShipmentGroup
├─ findAvailableShipmentBatch(..., shopeeWaveCode, groupKey)
└─ assignToCell
补单不重新申请 Shopee 波次号,并保持同一 Shopee 波次的 groupKey 一致。
8. 单格口完整分配
assignToCell 在格口锁内完成普通订单首次分配或补单:
assignToCell(...)
├─ 校验 ticketType、shipmentIds、shopeeWaveCode
├─ 获取 cellLockKey(cell.id)
├─ pickCellShipments,按剩余容量截断候选
├─ occupyCell
├─ createWave
├─ Shopee 同步
│ ├─ 新格口 → syncShopeePickingTaskAndFilterAcceptedShipments
│ └─ 已有同波次格口 → syncShopeeAppendOrderAndFilterAcceptedShipments
├─ bindBatchShipmentWave
│ ├─ waveBindLockKey
│ ├─ isWaveAvailable
│ └─ updateLocalShopeeWaveBinding
├─ addToWave
├─ 非 Flow Pick 达到 maxShipments → shopee_wave.status=400(FULL)
└─ finally 释放格口锁
assignAcquiredWaveToCell 只承接已经取得的 Shopee 波次号,并调用 assignToCell。
9. Shopee picking task 同步
9.1 首次同步
syncShopeePickingTaskAndFilterAcceptedShipments 显式接收 ticketType:
RT:不调用外部接口,直接返回当前单据。- 其他类型:始终调用
sendShopeePickingTaskRequest。 - 同步成功后写
pickingTaskSyncWaveCode,并更新shopee_wave.startPickUploadSts。 - 根据 Shopee 返回失败列表解析踢单,失败单写入
kickOutWave。
接口映射:
| ticketType | 接口 |
|---|---|
| SALES_TASK | Sales start picking task |
| SALES_ORDER | Sales create picking task |
| RTS / MTO_ORDER | RTS/MTO create picking task |
| MTO_TASK | MTO start picking task |
9.2 补单同步
已有同波次格口通过 syncShopeeAppendOrderAndFilterAcceptedShipments 调用 append order:
- SALES_ORDER → Sales append order
- RTS / MTO_ORDER → RTS/MTO append order
10. Shopee 波次记录
10.1 acquireWave
acquireWave(warehouseCode, ticketType) 在 waveAcquireLockKey(ticketType) 锁内查询:
where ticketType = :ticketType
and sourceType = INTERFACE
and waveDate >= 当前时间减 10 小时
and status = UNUSED
order by rand()
limit 1
该方法只返回候选号段,不在此处更新状态。
10.2 createInternalShopeeWave
对单据已有的 shopeeWaveCode,先按 code + ticketType 查询;不存在时创建:
sourceType=INTERNALbizType=NONEstatus=USING
已存在记录不修改。
10.3 backfillRtShopeeWaveCode
RT 使用已有 shopeeWaveCode 或 shipmentCode:
pickingTaskSyncWaveCode为空时回写本地标识。- 创建或更新 RT 类型的
shopee_wave。 - 状态设置为
USING。
11. 本地绑定与内部 wave
11.1 updateLocalShopeeWaveBinding
在 sortingWallCellLockKey(cell.id) 锁内:
- 从出库单解析唯一
ticketType。 - 更新
wcs_sorting_wall_cell的 Shopee 波次、当前规则和 ticketType。 - 更新内部
wave的规则、分播墙、格口、Shopee 波次和 ticketType。 - 更新
shopee_wave.status:一波一单类型置为FULL,普通订单保持USING。
该方法不回写 shipment_header_ext1 的绑定关系;单据与本地 wave 的关系由内部 wave 承载。
11.2 createWave / addToWave
createWave:解析 masterCode,调用waveSvc.createInternalWave,并回写内部 wave 的规则、格口和 ticketType。addToWave:调用shipmentHeaderService.addMultipleToWave后执行waveSvc.run。
12. 失败处理
| 失败点 | 当前处理 |
|---|---|
| 格口占用失败 | 返回错误,不覆盖其他波次 |
| 内部 wave 创建失败 | 新占格口调用 releaseSingleCell |
| Shopee 同步失败 | 释放新占格口并调用 cancelWave |
| Shopee 返回踢单 | markKickOut 写入 shipment_header_ext1.kickOutWave |
| 本地绑定失败 | 释放新占格口并调用 cancelWave |
| 加入或运行内部 wave 失败 | 释放新占格口并调用 cancelWave |
cancelFailedShopeeWaves 供计划任务取消状态为 FAILED 且已绑定格口的内部 wave。
13. 查询与规则匹配
当前候选查询入口:
findSingleShipments:快速拣选候选。findTaskTicketShipments:SALES_TASK / MTO_TASK 候选。findRtTicketShipments:RT 候选。findAvailableShipments/findAvailableShipmentBatch:普通订单首次分配和补单。
规则过滤包括:
appendSingleFilterappendKickOutFilterappendGroupKeyFilterappendOrderStructureFilterappendRuleMatchbuildOrderByClause
普通订单首先确定候选 groupKey,再抓取同组订单;补单通过 resolveBoundShipmentGroup 延续已有波次的组特征。
14. 当前方法关系
assignShopeeWaveToAcceptedWorkStations
└─ matchByStation
├─ assignSingles
└─ BATCH_PICK
├─ fillShortage
│ └─ assignToCell
├─ assignTaskTicket
├─ assignOrder
│ └─ assignAcquiredWaveToCell
│ └─ assignToCell
└─ assignRt
assignSingles / assignTaskTicket / assignRt
├─ occupySingleCell
├─ createWave
├─ updateLocalShopeeWaveBinding
└─ addToWave
assignToCell
├─ occupyCell
├─ createWave
├─ syncShopeePickingTaskAndFilterAcceptedShipments
│ 或 syncShopeeAppendOrderAndFilterAcceptedShipments
├─ bindBatchShipmentWave
├─ addToWave
└─ cancelWave / releaseSingleCell