16 KiB
出库集波规则匹配 API 文档
对应实现:
WaveRuleMatchController#findBestMatchedRule→WaveRuleMatchService#findBestMatchedRuleByWorkStationAndOutboundType需求标准来源:
C:\work\gitlab\shopee\ttx-project-doc\集波\SHOPEE_010_出库集波V1.2.docx(V1.4,2026-06-04 逻辑修改 / 匹单字段逻辑更新)。
概述
工作站集波的核心入口。用户在 WES 工作站界面选择出库类型后,前端调用本接口触发自动集波流程:
- 根据工作站 + 出库类型找出当前可用的分播墙格口
- 按规则优先级查找订单池中符合条件的出库单
- 完成 Shopee 波次绑定、ESS 校验、内部波次创建与运行
- 当前实现成功后返回
ResponseMessageFactory.success(),不返回「格口 + 命中规则 + 波次」明细
请求
URL
POST wms/automation/waveRuleMatch/findBestMatchedRule
请求体 (JSON)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
warehouseCode |
String | 是 | 仓库编码 |
workStation |
String | 是 | 工作站编码(或工作站数字 ID) |
shipmentType |
String | 是 | 出库类型,如 XSCK(销售出库)、MTO、RTS、RT |
示例:
{
"warehouseCode": "WH01",
"workStation": "WS001",
"shipmentType": "XSCK"
}
出库类型说明
| 出库类型 | 含义 | 处理方式 |
|---|---|---|
XSCK |
销售出库 | 标准集波(按 ticketType 分流:1=销售出库任务 一波一单,其他批量) |
MTO |
MTO 出库 | 标准集波(按 ticketType 分流:5=MTO任务 一波一单,其他批量) |
RTS |
RTS 出库 | 标准批量集波 |
RT |
RT 出库 | 一波一单,不使用 Shopee 波次号,走库内流程 |
标准要求补充
wave_rule.wavePriority先决定上墙优先级,maxShipments决定抓单数量;即使高优规则订单不足,也要优先匹高优规则的单。- 同一规则内抓单优先级按
shipment_header.priority降序、cutOffTime升序、purchaseTime升序、orderTime升序。 shipment_header.orderStructure若为空,出库单下发后需自动分析并写回:SSSQ=1、SSAQ=2、MSAQ=3。wave_rule.waveType与shipment_header.orderStructure按 docx 表格做包含关系匹配,表中命名/编码有歧义处保留原文并按 docx 待确认。- 匹单还要求
shipment_header.groupKey一致才能集在一起。 multi_attr_list采用全包含匹配:规则值A,B,C对单据A,B可匹配;规则值B,C对单据A,B不匹配。wcs_sorting_wall_cell.waveRule支持多选,多个规则逗号分隔。- 工作站选择出库类型受用户权限控制,同一工作站不混做不同出库类型。
- 仅抓正常单据,取消/挂起/异常单不抓。
shipment_header.pickType=1/0仅允许在订单池100状态切换。XSCK、MTO、RTS、RT的ticketType映射按 docx 口径分别为:销售任务1/ 销售订单2,MTO 任务5/ MTO 订单4,RTS3,RT6。- 推拣货任务标准要求为:上游同步 wave 号段,WES 不走取号逻辑,1 拣货单 1 波次 1 槽口,不走补单。
- Flow Pick 标准要求覆盖
SSSQ/MSSQ以及 RTS/MTO 下发单据;满槽换箱换波走 Flow Pick 换箱接口。 - 集波后需按单据类型取得
shopee_wave并请求上游校验:销售 create_picking_task 走 3.2.7,RTS/MTO 走 3.3.6;失败订单后续通过补单/踢单处理。
响应
成功响应
{
"success": true,
"data": [
{
"shipmentId": 12345,
"waveId": 67890,
"shopeeWaveCode": "SW20260520001",
"waveRule": "RULE_XSCK_SSSQ",
"sortingWallId": 1001,
"sortingWallCode": "WALL_A01",
"cellId": 2001,
"cellCode": "A01-01"
}
]
}
标准要求:返回格口 + 命中规则 + 波次分配明细。
当前实现:成功时通常仅返回
ResponseMessageFactory.success(),不保证返回上述明细;若调用链未产出分配结果,请以 success 为准。
| 响应字段 | 类型 | 说明 |
|---|---|---|
shipmentId |
Long | 已集波出库单 ID |
waveId |
Long | 内部波次 ID |
shopeeWaveCode |
String | Shopee 波次号(RT 类型返回空字符串 "") |
waveRule |
String | 命中的波次规则编码 |
sortingWallId |
Long | 分播墙 ID |
sortingWallCode |
String | 分播墙编码 |
cellId |
Long | 格口 ID |
cellCode |
String | 格口编码 |
特殊:RT 和推拣货任务返回简化结构
{shipmentId, waveId, shopeeWaveCode, waveRule, shipmentType}。
错误响应
{
"success": false,
"messageCode": "MSG_WRM_0001",
"message": "参数不完整:warehouseCode、workStation、shipmentType 不能为空"
}
错误码
| 消息码 | 说明 | 触发条件 |
|---|---|---|
MSG_WRM_0001 |
参数不完整 | warehouseCode/workStation/shipmentType 任意为空 |
MSG_WRM_0002 |
工作站不可用 | 工作站不存在、仓库不匹配或未启用 |
MSG_WRM_0003 |
参数不完整 | workstationId/shipmentType 为空(内部入口) |
MSG_WRM_0004 |
工作站[{0}]不存在 | 工作站 ID 无效 |
MSG_WRM_0005 |
工作站[{0}]未启用 | 工作站状态非 ENABLE |
MSG_WRM_0006 |
工作站[{0}]仓库编码为空 | 工作站未关联仓库 |
MSG_WRM_0007 |
未找到可用波次规则 | 仓库下无启用规则 |
MSG_WRM_0008 |
无可用格口 | 工作站下所有格口已被占用 |
MSG_WRM_0009 |
规则匹配到但无格口可用 | 当前规则下无空闲格口承接 |
MSG_WRM_0010 |
当前规则下无可匹配出库单 | 订单池无符合条件的出库单 |
MSG_WRM_0011 |
规则或工作站为空 | 内部校验 |
MSG_WRM_0012 |
工作站正在集波中 | Redis 锁获取失败,同一工作站同一出库类型正在集波 |
MSG_WRM_0014 |
工作站已有其它出库类型作业 | 同一工作站已存在其它 shipmentType 的占用格口/波次 |
处理流程
POST /findBestMatchedRule
│
├─ 1. 参数校验 (warehouseCode / workStation / shipmentType)
│
├─ 2. 工作站校验 (存在 / 启用 / 仓库匹配)
│
├─ 3. 同工作站出库类型隔离 (不允许一个工作站混做不同 shipmentType)
│
├─ 4. Redis 锁 (仓库+工作站+出库类型, 防重复集波)
│
├─ 5. 查询启用波次规则 (按 wavePriority desc)
│
├─ [分支 A] 一波一单
│ └─ assignSingleShipmentWaves
│ 按单拣选、销售任务、MTO 任务、RT 一单一波;RT 不使用 Shopee 波次号
│
├─ [分支 B] 已绑定 Shopee 波次格口补缺口
│ └─ fillShortageCells
│ 仅处理空闲、已绑定 shopeeWaveCode、currentWaveRule 匹配当前规则的格口
│
└─ [分支 C] 空格口首次分配 (逐规则按优先级循环)
│
├─ 6. 查可用格口 (三层级):
│ ├─ sameCurRuleCells — currentWaveRule 同当前规则
│ ├─ ruleCells — waveRule 配置匹配当前规则
│ └─ emptyCells — 完全空闲格口
│
├─ 7. 按规则查询出库单:
│ ├─ 一波一单候选项 (pickType=1 / ticketType 任务 / RT)
│ └─ 批量集波候选项 (排除一波一单)
│
├─ 8. 创建内部波次 (WaveService#createInternalWave)
│
├─ 9. 格口循环处理:
│ ├─ 已有波次号 → 补单缺口判断
│ └─ 无波次号 → 抢占 Shopee 波次号 (acquireUnusedShopeeWave)
│
├─ 10. assignToCell:
│ ├─ pickCellShipmentIds — 按格口缺口截断候选单
│ ├─ ensureCellReadyForWave — 先抢占格口 (USED)
│ ├─ bindShipmentShopeeWave — ESS 绑定校验
│ │ ├─ 成功 → 写入 shipment_header.shopeeWave,并更新 shopee_wave pickType/groupKey
│ │ └─ 失败 → 写入 kickOutWave, 同波次后续过滤
│ └─ addShipmentsToInternalWave → WaveService#run
│
└─ 11. 成功返回 ResponseMessageFactory.success(),不返回格口分配明细
核心规则
规则优先级
- 上墙优先级 —
wave_rule.wavePriority(数字越大越优先) - 抓单优先级(同一规则内):
priority数字越大越优先- 同优先级按
cutOffTime越早越优先 - 同截单时间按
purchaseTime越早越优先 - 同购买时间按
orderTime越早越优先 - 同时间按
id升序兜底
V1.4 标准要求与当前实现
| 标准要求 | 当前实现/待实现 |
|---|---|
| 修改历史 V1.4:匹单字段逻辑更新 | 本文按 docx V1.4 同步 waveType/orderStructure、groupKey、规则字段匹配和新增字段说明 |
wave_rule 字段按 WES 小驼峰与 base 字段命名规范维护 |
当前规则域已包含 waveType、wavePriority、maxShipments 及多项规则属性;主数据字段命名以代码和迁移为准 |
新增/强调 Max SKU Pieces Per Order |
标准要求:单订单任一 SKU 件数超过阈值时排除本规则;当前 WaveRule/匹单 SQL 未见对应规则字段,待实现 |
新增/强调 Mix Mode Max SKU Pieces Filter |
标准要求:仅 Mix-mode/MSAQ 规则使用,用于排除单 SKU 件数过高的混合订单;当前未见对应匹单实现,待实现 |
出库单 orderStructure 为空时自动分析 |
当前由订单明细分析后写入 shipment_header.orderStructure:SSSQ=1、SSAQ=2、MSAQ=3 |
| 工作站出库类型权限控制 | 标准要求:登录工作站按用户权限下拉可选出库类型;当前服务已做同工作站不同出库类型隔离,用户权限绑定仍为待实现 |
| Shopee 波次号获取与上游合波校验 | 当前 acquireUnusedShopeeWave 抢占 shopee_wave 未使用号段;requestShopeeWaveBind 是上游校验预留入口,create_picking_task / RTS-MTO 真实接口契约仍待接入 |
| 库存最优分配与库存不足踢单 | 标准要求:效期/FIFO、工作站与库存点位半径优先、同半径低层货位优先;当前集波入口只触发 WaveService#run,库存不足踢单回池与上游撤单通知仍需在库存/回池链路接入 |
格口分配优先级
| 优先级 | 格口类型 | 条件 |
|---|---|---|
| 1(最高) | sameCurRuleCells |
currentWaveRule 与当前规则相同 |
| 2 | ruleCells |
currentWaveRule 为空且 waveRule 匹配当前规则 |
| 3(兜底) | emptyCells |
currentWaveRule 和 waveRule 均为空 |
标准要求:
wcs_sorting_wall_cell.waveRule支持分播墙明细界面多选,一个格口可绑定多个wave_rule,多个规则用逗号分隔存储;当前匹配按逗号拆分后判断是否包含当前规则编码。
一波一单处理
以下单据类型按一波一单处理(每次集波只取 1 单,创建独立内部波次):
| 类型 | 标识 | 说明 |
|---|---|---|
| 按单拣选 | pickType=1 |
按单拣选专用 |
| 销售出库任务 | shipmentType=XSCK + ticketType=1 |
一波一单 |
| MTO 任务 | ticketType=5 |
一波一单 |
| RT | ticketType=6 |
不使用 Shopee 波次号 |
订单结构与 Flow Pick
| 项 | 标准要求 | 当前实现/说明 |
|---|---|---|
waveType/orderStructure 包含关系 |
按 docx 表:SSSQ(1)->SSSQ(1)、MSSQ(5)->SSSQ(1)、SSAQ(4)->SSSQ/SSAQ(1/2)、SSSQ(Same SKU same Qty)(2)->MSAQ(3)、MSAQ(3)->SSSQ/SSAQ/MSAQ(1/2/3) |
当前通过 appendWaveTypeOrderStructureFilter 固定过滤。SSSQ(Same SKU same Qty) 与 SSSQ 命名相近,按 docx 待确认 |
groupKey |
同一 Shopee 波次只能集相同 shipment_header.groupKey 特征值订单 |
当前首次抓单按首个候选单确定 groupKey,补单按 shopee_wave.groupKey 过滤 |
| Flow Pick | 标准定义:SSSQ/MSSQ 为 Flow Pick,RTS/MTO 下发单据也按 Flow Pick 处理 | 当前已有 Flow Pick 换箱换波本地流程与接口占位,真实 ESS/AGV 接口待接入 |
| 推拣货任务 | 上游推送 Shopee 波次号,WES 不走取号逻辑;1 拣货任务 / 1 波次 / 1 槽口;不走补单 | 当前普通批量已过滤 pickType=2,专用分流入口待恢复 |
字段匹配
通过数据字典 WAVE_RULE_FIELD_MATCHING 配置出库单字段与规则字段的匹配关系:
| 操作符 | 含义 | 示例 |
|---|---|---|
IN |
多值包含 | userDef1 IN (channelId 多选值) |
= / EQ / EQUAL / EQUALS |
等值匹配 | userDef7 = shopId |
LE / <= / LESS_OR_EQUAL |
小于等于 | priority <= urgentFlag |
字段白名单(防 SQL 拼接注入):
- 出库单字段(30+):
shipmentType、ticketType、pickType、sourcePlatform、sourceErp、route、carrierCode、shipToCountry、userDef1-8等 - 规则字段(16):
channelId、fulfillmentChainId、orderSize、skuSizeType、categoryLevel1Id、shopGroup、shopId、urgentFlag、outerPackagingType、deliveryRegion、fragile、liquid、highValue、battery、danger等
补充口径:
- 标准要求:只对
wave_rule中对应订单类型列标记Y的字段做匹配;SKU 来源字段需与单据所有明细 SKU 主档字段全部匹配。 - 标准要求:
multi_attr_list多值字段匹配时按 docx 示例为“规则值全包含单据值”,例如规则A,B,C可匹配单据A,B,规则B,C不匹配单据A,B;该包含方向按 docx 待确认。 - 当前实现:逗号多值字段目前按任一值命中生成条件,
multi_attr_list全包含匹配仍待调整。
并发控制
Redis 分布式锁,锁 Key:wave_rule_match:{warehouseCode}:{workstationId}:{shipmentType}
同一工作站 + 同一出库类型同时只有一个请求能进入集波流程;同一工作站如果已有其它出库类型作业,入口直接拒绝,避免混做。
异常过滤
出库单必须同时满足以下条件才能进入抓单池:
leadingSts = 100(订单池状态)trailingSts = 100(订单池状态)processType = 'NORMAL'(正常处理流程)waveId is null or waveId = 0(未加入任何波次)lockCode is null or lockCode = ''(未被锁定)cancelTime is null or cancelTime = ''(未取消)holdTime is null or holdTime = ''(未挂起)
补单机制(当前代码口径)
当前代码未保留后台计划任务 pollReplenishment/pollReplenishmentOnce。补缺口能力收口在首次集波入口中的 fillShortageCells,用于处理当前工作站已绑定 Shopee 波次且规则一致的空闲格口。
- 触发方式:调用首次集波入口时顺带执行
- 扫描范围:当前工作站 + 已绑定 Shopee 波次 +
currentWaveRule匹配的空闲格口 - 单品单件:低于
WAVE/low_threshold时触发,一次性按maxShipments抓单 - 非单品单件:缺口 =
maxShipments - 当前波次已绑单量 - Flow Pick 满槽:达到
maxShipments时触发换箱换波 - 后台轮询:如需恢复,需按最终调度策略重新接入计划任务入口
相关表
| 表名 | 说明 | 关键字段 |
|---|---|---|
wave_rule |
波次规则 | code, waveType, wavePriority, maxShipments, status, channelId, shopId 等;V1.4 标准新增 Max SKU Pieces Per Order、Mix Mode Max SKU Pieces Filter 待实现 |
shopee_wave |
Shopee 波次号段 | code, waveType, warehouseCode, pickType, groupKey, flow_pick, status (100=未使用, 200=使用中, 900=使用完成) |
shipment_header |
出库单头 | shopeeWave, kickOutWave, ticketType, pickType, groupKey, orderStructure, waveId |
wcs_sorting_wall_cell |
分播墙格口 | waveRule, currentWaveRule, shopeeWaveCode, useStatus |
wcs_work_station_pick_task_header |
拣货任务头 | shopeeWave, waveRule, shipmentId |
wave |
内部波次 | waveRule |
测试与验证
推荐验证顺序:
- 编译:按需执行
:wms-wave:compileGroovy,本轮文档同步未执行 - 静态检查:确认无新增测试类和旧测试类引用残留
- 手工验证:使用实际 wave_rule 和出库单数据调用本接口,验证系统处理日志、格口占用和订单波次绑定
- ESS 联调:验证
bindShipmentShopeeWave中 ESS 绑定接口成功/失败结果 - 补单验证:确认
fillShortageCells能补满已绑定 Shopee 波次格口且kickOutWave过滤生效