Files
ttx-project-doc/SHOPEE_010_出库集波V1.2_findBestMatchedRule_API.md
T

10 KiB
Raw Blame History

出库集波规则匹配 API 文档

对应实现:WaveRuleMatchController#findBestMatchedRuleWaveRuleMatchService#findBestMatchedRuleByWorkStationAndOutboundType


概述

工作站集波的核心入口。用户在 WES 工作站界面选择出库类型后,前端调用本接口触发自动集波流程:

  1. 根据工作站 + 出库类型找出当前可用的分播墙格口
  2. 按规则优先级查找订单池中符合条件的出库单
  3. 完成 Shopee 波次绑定、ESS 校验、内部波次创建与运行
  4. 返回「格口 + 命中规则 + 波次」的分配结果

请求

URL

POST wms/automation/waveRuleMatch/findBestMatchedRule

请求体 (JSON)

字段 类型 必填 说明
warehouseCode String 仓库编码
workStation String 工作站编码(或工作站数字 ID
shipmentType String 出库类型,如 XSCK(销售出库)、MTORTSRT

示例:

{
  "warehouseCode": "WH01",
  "workStation": "WS001",
  "shipmentType": "XSCK"
}

出库类型说明

出库类型 含义 处理方式
XSCK 销售出库 标准集波(按 ticketType 分流:1=销售出库任务 一波一单,其他批量)
MTO MTO 出库 标准集波(按 ticketType 分流:5=MTO任务 一波一单,其他批量)
RTS RTS 出库 标准批量集波
RT RT 出库 一波一单,不使用 Shopee 波次号,走库内流程

响应

成功响应

{
  "success": true,
  "data": [
    {
      "shipmentId": 12345,
      "waveId": 67890,
      "shopeeWaveCode": "SW20260520001",
      "waveRule": "RULE_XSCK_SSSQ",
      "sortingWallId": 1001,
      "sortingWallCode": "WALL_A01",
      "cellId": 2001,
      "cellCode": "A01-01"
    }
  ]
}
响应字段 类型 说明
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 锁获取失败,同一工作站同一出库类型正在集波

处理流程

POST /findBestMatchedRule
│
├─ 1. 参数校验 (warehouseCode / workStation / shipmentType)
│
├─ 2. 工作站校验 (存在 / 启用 / 仓库匹配)
│
├─ 3. Redis 锁 (仓库+工作站+出库类型, 防重复集波)
│
├─ 4. 查询启用波次规则 (按 wavePriority desc)
│
├─ [分支 A] 一波一单
│   └─ assignSingleShipmentWaves
│       按单拣选、销售任务、MTO 任务、RT 一单一波;RT 不使用 Shopee 波次号
│
├─ [分支 B] 已绑定 Shopee 波次格口补缺口
│   └─ fillShortageCells
│       仅处理空闲、已绑定 shopeeWaveCode、currentWaveRule 匹配当前规则的格口
│
└─ [分支 C] 空格口首次分配 (逐规则按优先级循环)
    │
    ├─ 5. 查可用格口 (三层级):
    │   ├─ sameCurRuleCells — currentWaveRule 同当前规则
    │   ├─ ruleCells — waveRule 配置匹配当前规则
    │   └─ emptyCells — 完全空闲格口
    │
    ├─ 6. 按规则查询出库单:
    │   ├─ 一波一单候选项 (pickType=1 / ticketType 任务 / RT)
    │   └─ 批量集波候选项 (排除一波一单)
    │
    ├─ 7. 创建内部波次 (WaveService#createInternalWave)
    │
    ├─ 8. 格口循环处理:
    │   ├─ 已有波次号 → 补单缺口判断
    │   └─ 无波次号 → 抢占 Shopee 波次号 (acquireUnusedShopeeWave)
    │
    ├─ 9. assignToCell:
│   ├─ pickCellShipmentIds — 按格口缺口截断候选单
    │   ├─ ensureCellReadyForWave — 先抢占格口 (USED)
    │   ├─ bindShipmentShopeeWave — ESS 绑定校验
    │   │   ├─ 成功 → 写入 shipment_header.shopeeWave,并更新 shopee_wave pickType/groupKey
    │   │   └─ 失败 → 写入 kickOutWave, 同波次后续过滤
│   └─ addShipmentsToInternalWave → WaveService#run
│
    └─ 10. 成功返回 ResponseMessageFactory.success(),不返回格口分配明细

核心规则

规则优先级

  1. 上墙优先级wave_rule.wavePriority(数字越大越优先)
  2. 抓单优先级(同一规则内):
    • priority 数字越大越优先
    • 同优先级按 cutOffTime 越早越优先
    • 同截单时间按 purchaseTime 越早越优先
    • 同购买时间按 orderTime 越早越优先
    • 同时间按 id 升序兜底

格口分配优先级

优先级 格口类型 条件
1(最高) sameCurRuleCells currentWaveRule 与当前规则相同
2 ruleCells currentWaveRule 为空且 waveRule 匹配当前规则
3(兜底) emptyCells currentWaveRulewaveRule 均为空

一波一单处理

以下单据类型按一波一单处理(每次集波只取 1 单,创建独立内部波次):

类型 标识 说明
按单拣选 pickType=1 按单拣选专用
销售出库任务 shipmentType=XSCK + ticketType=1 一波一单
MTO 任务 ticketType=5 一波一单
RT ticketType=6 不使用 Shopee 波次号

字段匹配

通过数据字典 WAVE_RULE_FIELD_MATCHING 配置出库单字段与规则字段的匹配关系:

操作符 含义 示例
IN 多值包含 userDef1 IN (channelId 多选值)
= / EQ / EQUAL / EQUALS 等值匹配 userDef7 = shopId
LE / <= / LESS_OR_EQUAL 小于等于 priority <= urgentFlag

字段白名单(防 SQL 拼接注入):

  • 出库单字段30+):shipmentTypeticketTypepickTypesourcePlatformsourceErproutecarrierCodeshipToCountryuserDef1-8
  • 规则字段16):channelIdfulfillmentChainIdorderSizeskuSizeTypecategoryLevel1IdshopGroupshopIdurgentFlagouterPackagingdeliveryRegionfragileliquidhighValuebatterydanger

并发控制

Redis 分布式锁,锁 Keywave_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
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

测试与验证

推荐验证顺序:

  1. 编译:按需执行 :wms-wave:compileGroovy,本轮文档同步未执行
  2. 静态检查:确认无新增测试类和旧测试类引用残留
  3. 手工验证:使用实际 wave_rule 和出库单数据调用本接口,验证系统处理日志、格口占用和订单波次绑定
  4. ESS 联调:验证 bindShipmentShopeeWave 中 ESS 绑定接口成功/失败结果
  5. 补单验证:确认 fillShortageCells 能补满已绑定 Shopee 波次格口且 kickOutWave 过滤生效