docs: add shopee interface documentation
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
# docs 目录入口
|
||||
|
||||
## 用途
|
||||
- 本目录当前以一份统一汇总文档作为主入口。
|
||||
- 历史的项目分目录文档保留为参考,不再作为主维护结构。
|
||||
|
||||
## 主入口
|
||||
- [文档统一汇总](统一汇总.md)
|
||||
|
||||
## 接口文档
|
||||
- [Shopee Automation Vendor 接入协议手册出库模块映射 WES 字段 V1.2](Shopee_Automation_Vendor_接入协议手册_出库模块映射WES字段_V1.2.md)
|
||||
|
||||
## 说明
|
||||
- 需要快速了解当前工作时,先看统一汇总。
|
||||
- 需要追溯历史细节时,再进入对应的历史子文档。
|
||||
Binary file not shown.
@@ -0,0 +1,154 @@
|
||||
# Docx 设计文档 vs API 文档 差异对比
|
||||
|
||||
> 对比范围:`SHOPEE_010_出库集波V1.2.docx`(设计文档) vs `SHOPEE_010_出库集波V1.2_findBestMatchedRule_API.md`(API 文档)
|
||||
>
|
||||
> 对比基准:docx 中与 `findBestMatchedRule` 接口直接相关的需求,逐条对照 API 文档覆盖情况和代码落地情况。
|
||||
|
||||
---
|
||||
|
||||
## 图例
|
||||
|
||||
| 标记 | 含义 |
|
||||
|------|------|
|
||||
| ✅ **已覆盖** | API 文档已描述,代码已实现 |
|
||||
| ⚠️ **部分覆盖** | API 文档提及但不够完整,或代码实现与 docx 有偏差 |
|
||||
| ❌ **未覆盖** | docx 有要求但 API 文档未提及,或代码未实现 |
|
||||
| 🔲 **N/A** | 不适用于 API 文档范围(前端/页面/非本接口) |
|
||||
|
||||
---
|
||||
|
||||
## 一、请求与参数
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 1.1 | 用户选择出库类型(销售出库、调拨、RTS、RT),用户权限控制选择类型 | API 入口参数 `shipmentType` 支持 `XSCK/MTO/RTS/RT`,但**未提及用户权限校验** | ⚠️ 部分覆盖 — 参数已支持,权限校验代码未实现(待办事项 P1) |
|
||||
| 1.2 | 同一个工作站不会混做不同类型 | API 文档需补充该约束;代码入口已通过 `USED` 格口关联 Shopee 波次反查当前工作站出库类型 | ⚠️ 部分覆盖 — 后端入口已返回 `MSG_WRM_0014`,前端约束和提示待补 |
|
||||
| 1.3 | 登录工作站校验用户权限,用户权限跟订单类型绑定 | API 文档未提及用户权限校验 | ❌ 未覆盖 — 待办事项 P1 |
|
||||
| 1.4 | 工作站编码或 workstationId 均可 | API 文档 `workStation` 支持编码或数字 ID(代码 `findEnabledWorkStation` 兼容两者) | ✅ 已覆盖 |
|
||||
|
||||
## 二、出库单类型与分流
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 2.1 | `shipmentType`:XSCK、MTO、RTS、RT | API 文档出库类型表已列出四种 | ✅ 已覆盖 |
|
||||
| 2.2 | 销售出库细分 `ticketType`:销售出库任务、销售出库订单 | API 文档提及 `ticketType=1` 任务一波一单 | ✅ 已覆盖 |
|
||||
| 2.3 | MTO 细分 `ticketType`:MTO任务、MTO出库订单 | API 文档提及 `ticketType=3` 任务一波一单 | ✅ 已覆盖 |
|
||||
| 2.4 | RT 单子不需要参与出库等接口,不使用上游波次号,走库内流程 | API 文档 RT 处理方式已描述 | ✅ 已覆盖 |
|
||||
| 2.5 | 集波区分几种单据类型:XSCK、MTO、RTS、RT | API 文档已列出 | ✅ 已覆盖 |
|
||||
| 2.6 | 推拣货任务(命中人工+自动化区)与推出库单(纯命中自动化区)区别:上游同步波次号段,无需取号逻辑 | API 文档推拣货任务 `stationType=2` 已描述 | ✅ 已覆盖 |
|
||||
| 2.7 | 拣货任务 1 单跑 1 个波次,1拣货单1波次1槽口,后续无需补单 | API 文档已描述一单一波一槽口 | ✅ 已覆盖 |
|
||||
| 2.8 | 推拣货任务区分标识待梳理接口后提供 | API 文档用 `stationType=2` 作为标识,**但上游推单接口未联调** | ⚠️ 已实现待联调 |
|
||||
| 2.9 | 推出库单按上文进行集波即可 | API 文档标准集波流程已描述 | ✅ 已覆盖 |
|
||||
|
||||
## 三、规则匹配与优先级
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 3.1 | 按 `wave_rule` 表优先级 `wavePriority` 排序集波(数字越大优先级越高) | API 文档「上墙优先级」已描述 `wavePriority desc` | ✅ 已覆盖 |
|
||||
| 3.2 | 如果工作站有槽口未绑定 wave rule 默认所有规则都可以按优先级去依次匹单 | API 文档格口三层级中 `emptyCells` 兜底,**但「业务上是否启用」标注待确认** | ⚠️ 部分覆盖 — 代码已实现 `matchEmptyCells`,业务口径待确认 |
|
||||
| 3.3 | 抓单优先级:`shipment_header.priority` → `cutOffTime` → `purchaseTime` → `orderTime` | API 文档已完整描述 | ✅ 已覆盖 |
|
||||
| 3.4 | `priority` 数字越大优先级越高 | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 3.5 | `cutOffTime`、`purchaseTime`、`orderTime` 越早越优先 | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 3.6 | 高优先级规则不足 `maxShipments` 时仍优先消费当前规则 | API 文档未显式提及,但代码 `assignCellNumbers` 中有 `logPriorityRuleConsumption` 处理 | ⚠️ API 文档未提及此容错逻辑 |
|
||||
|
||||
## 四、格口分配
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 4.1 | 分拨墙槽口需支持 1 口绑定多波次规则 9+ | API 文档格口 `waveRule` 多值逗号分隔 | ✅ 已覆盖 |
|
||||
| 4.2 | 格口分配:优先用 `currentWaveRule` 相同的格口,其次 `waveRule` 匹配,最后空闲格口 | API 文档三层级分配策略已描述 | ✅ 已覆盖 |
|
||||
| 4.3 | 集波后绑定对应 `wcs_sorting_wall_cell` 表 waveRule 设定相同规则的槽口 | API 文档格口分配后写 `currentWaveRule` | ✅ 已覆盖 |
|
||||
| 4.4 | 格口返回视图需分播墙上下文 | API 文档响应包含 `sortingWallId` / `sortingWallCode` | ✅ 已覆盖 |
|
||||
|
||||
## 五、Shopee 波次绑定
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 5.1 | Shopee 波次号段由上游接口提前落库 | API 文档提及从 `shopee_wave` 表 `status=100` 取号,**未描述申请接口** | ❌ 未覆盖 — 待办事项 P1(号段申请接口) |
|
||||
| 5.2 | 按 `status=100` 抢占为 `200`,避免并发重复取号 | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 5.3 | 出库单头写入 `shopeeWave` | API 文档 `bindShipmentToShopeeWave` 已描述 | ✅ 已覆盖 |
|
||||
| 5.4 | 任务头写入 `shopeeWave`、`waveRule` | API 文档相关表已列出,**但回写链路待验证** | ⚠️ 部分覆盖 — 代码已写回,结果验证待执行 |
|
||||
| 5.5 | Shopee 波次号段用完后继续申请 | API 文档**未提及用完续号逻辑** | ❌ 未覆盖 — 待办事项 P1 |
|
||||
| 5.6 | ESS 请求校验是否允许集入同一个 Shopee 波次 | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 5.7 | ESS 拒绝单据写入 `kickOutWave`,同波次后续过滤 | API 文档已描述 | ✅ 已覆盖 |
|
||||
|
||||
## 六、内部波次与运行
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 6.1 | 集波后自动运行波次 | API 文档 `addShipmentsToInternalWave` → `WaveService#run` 异步提交队列消息 | ✅ 已覆盖 |
|
||||
| 6.2 | 内部波次记录 `waveRule` | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 6.3 | 波次运行如果有库存不足的单据直接踢单,需请求上游撤单接口 | API 文档未明确异步回池职责 | ⚠️ 部分覆盖 — `wms-wave` 回池链路清 Shopee 绑定且不写 `kickOutWave`,上游撤单接口待接入 |
|
||||
| 6.4 | 库存最优分配逻辑:先到期先出→半径最小→低层优先 | API 文档**未提及** | ❌ 未覆盖 — P2 |
|
||||
| 6.5 | 波次运行成功将波次号绑定在拣货任务头 `shopeeWave` + 出库单头 `shopeeWave` | API 文档相关表已列出 | ✅ 已覆盖 |
|
||||
|
||||
## 七、订单结构(shipmentCategory1)
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 7.1 | 出库单自动分析订单结构,打在 `shipmentCategory1`:SSSQ=1、SSAQ=4、MSAQ=3、MSSQ=5、Same SKU Same Qty=2 | API 文档提及 `shipmentCategory1` 用于波次类型匹配,**但未列出编码映射表** | ⚠️ 部分覆盖 — 编码表在待办事项文档中,API 文档未包含 |
|
||||
| 7.2 | `wave_rule.waveType` 与 `shopee_wave.waveType` 口径一致 | API 文档已描述 | ✅ 已覆盖 |
|
||||
|
||||
## 八、并发与异常
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 8.1 | 同一工作站同一出库类型不能重复集波 | API 文档 Redis 锁已描述 | ✅ 已覆盖 |
|
||||
| 8.2 | 集波抓单只抓标记为正常的单据(cancel、挂起、标记异常的单子都不抓) | API 文档异常过滤条件已列出(`cancelTime`/`holdTime`/`processType`) | ✅ 已覆盖 |
|
||||
| 8.3 | 订单池 100 状态单据才允许参与集波 | API 文档 `leadingSts=100` / `trailingSts=100` | ✅ 已覆盖 |
|
||||
|
||||
## 九、Flow Pick 单品单件
|
||||
|
||||
| # | Docx 要求 | API 文档 | 状态 |
|
||||
|---|-----------|----------|------|
|
||||
| 9.1 | 单品单件 wave rule 支持动态加单或踢单 | API 文档仅提及补单机制,踢单由 `wms-wave` 异步回池链路处理 | ⚠️ 部分覆盖 — 加单已实现,库存不足踢单上游撤单待接入 |
|
||||
| 9.2 | `low_threshold` 低阈值补单 | API 文档已描述 | ✅ 已覆盖 |
|
||||
| 9.3 | 槽口放满封箱再换波次 | API 文档已描述 Flow Pick 满槽换箱换波 | ✅ 已覆盖 |
|
||||
| 9.4 | 换箱换波需调用上游换箱接口(区别于普通合波校验) | API 文档**未提及 Flow Pick 接口对接状态** | ⚠️ 部分覆盖 — 代码已占位待联调 |
|
||||
|
||||
## 十、页面/前端能力(不适用 API 文档)
|
||||
|
||||
| # | Docx 要求 | 说明 | 状态 |
|
||||
|---|-----------|------|------|
|
||||
| 10.1 | 出库单界面新增按钮:更新按单拣选 | 页面功能,非 API 范围 | 🔲 N/A |
|
||||
| 10.2 | Dropdown 支持 All、多选、模糊搜索 | 规则配置页面 | 🔲 N/A |
|
||||
| 10.3 | Input 支持输入多个值 | 规则配置页面 | 🔲 N/A |
|
||||
| 10.4 | `Include / Exclude / Only` 语义 | 规则配置页面 | 🔲 N/A |
|
||||
| 10.5 | `Max SKU Pieces Per Order` | 非 `WaveRule` 字段,需基于 `shipment_detail` 聚合 | 🔲 N/A |
|
||||
| 10.6 | `Mix Mode Max SKU Pieces Filter` | MSAQ 规则,需基于明细聚合 | 🔲 N/A |
|
||||
|
||||
---
|
||||
|
||||
## 汇总
|
||||
|
||||
| 分类 | 总数 | ✅ 已覆盖 | ⚠️ 部分覆盖 | ❌ 未覆盖 | 🔲 N/A |
|
||||
|------|------|-----------|-------------|-----------|--------|
|
||||
| 一、请求与参数 | 4 | 1 | 1 | 2 | 0 |
|
||||
| 二、出库单类型与分流 | 9 | 7 | 1 | 0 | 0 |
|
||||
| 三、规则匹配与优先级 | 6 | 4 | 2 | 0 | 0 |
|
||||
| 四、格口分配 | 4 | 4 | 0 | 0 | 0 |
|
||||
| 五、Shopee 波次绑定 | 7 | 5 | 1 | 1 | 0 |
|
||||
| 六、内部波次与运行 | 5 | 3 | 0 | 2 | 0 |
|
||||
| 七、订单结构 | 2 | 1 | 1 | 0 | 0 |
|
||||
| 八、并发与异常 | 3 | 3 | 0 | 0 | 0 |
|
||||
| 九、Flow Pick | 4 | 2 | 2 | 0 | 0 |
|
||||
| 十、页面能力 | 6 | 0 | 0 | 0 | 6 |
|
||||
| **合计** | **50** | **30 (60%)** | **8 (16%)** | **5 (10%)** | **6 (12%)** |
|
||||
|
||||
### 关键缺口(❌ 未覆盖)
|
||||
|
||||
| # | 缺口 | 影响 | 优先级 |
|
||||
|---|------|------|--------|
|
||||
| 1 | 库存不足踢单上游撤单接口 | 波次运行后如库存不足,`wms-wave` 已负责回池和清 Shopee 绑定,但仍无法通知上游撤单 | **P0** |
|
||||
| 2 | 用户权限 + 出库类型绑定 | 工作站用户可越权选择无权操作的单据类型 | **P1** |
|
||||
| 3 | Shopee 波次号段申请接口 & 用完续号 | 号段只能被动消耗,无法主动申请新号段 | **P1** |
|
||||
| 4 | 库存最优分配规则(到期日/半径/低层) | 当前无库存分配算法,docx 明确要求 | **P2** |
|
||||
|
||||
### API 文档可补充项
|
||||
|
||||
| # | 建议补充 | 原因 |
|
||||
|---|---------|------|
|
||||
| 1 | 高优先级规则不足 `maxShipments` 时仍优先消费的容错说明 | 当前代码行为与直觉相反,文档应解释 |
|
||||
| 2 | `shipmentCategory1` 编码映射表(SSSQ=1 / SSAQ=4 / MSAQ=3 / MSSQ=5 / Same SKU Same Qty=2) | docx 明确列出,API 文档未包含 |
|
||||
| 3 | Flow Pick 换箱换波接口对接状态说明 | 当前代码已占位待联调,文档应注明 |
|
||||
| 4 | 推拣货任务上游推单接口联调说明 | `stationType=2` 需上游配合写入,文档应说明前提条件 |
|
||||
@@ -0,0 +1,346 @@
|
||||
# WaveRuleMatchService 功能完成度分析
|
||||
|
||||
对照来源:`C:\Users\zoe\Downloads\SHOPEE_010_出库集波V1.2.docx`
|
||||
|
||||
代码范围:`C:\work\gitlab\shopee\wes-loghub\wms-wave\src\main\groovy\com\ittx\wms\wave\service\hairo\WaveRuleMatchService.groovy`
|
||||
|
||||
更新日期:2026-06-02
|
||||
|
||||
本文只维护 `WaveRuleMatchService` 对照最终需求仍未完成、未闭环或需要接口确认的功能。已落地且逻辑清晰的实现只在“已明确口径”中简要记录,不再作为待办展开。
|
||||
|
||||
## 已明确口径
|
||||
|
||||
- 首次集波入口保留 `ResponseMessage`。
|
||||
- 错误分支继续返回 `ResponseMessageFactory.error(...)`。
|
||||
- 首次集波成功只返回 `ResponseMessageFactory.success()`,不返回分配明细数据。
|
||||
- 首次集波不维护 `allocatedRows` 汇总。
|
||||
- 一波一单、缺货补满、空格口分配的执行结果通过系统处理日志记录。
|
||||
- 当前未保留 `pollReplenishment/pollReplenishmentOnce` 计划任务入口;补缺口能力收口在首次集波入口的 `fillShortageCells(...)`。
|
||||
- 一波一单规则已按当前确认口径修正:`XSCK + ticketType=1`、`ticketType=5`、`pickType=1`、`RT(ticketType=6)` 均进入一波一单,RT 不使用 Shopee 波次号。
|
||||
- `fillShortageCells(...)` 不返回 `rows`,只执行缺货补满副作用并记录系统处理日志。
|
||||
- `findShortageCells(...)` 已改为直接 SQL 查询 `wcs_sorting_wall_cell`。
|
||||
- `findShortageCells(...)` 限制 `useStatus = IDLE`、`shopeeWaveCode` 有值、`currentWaveRule = rule.code`。
|
||||
- `findCells(Long workStationId)` 已改为直接 SQL 查询 `wcs_sorting_wall_cell`。
|
||||
- 单品单件 `calcCellNeedQty(...)` 已改为只统计未拣货任务对应的出库单数量。
|
||||
- 非单品单件补单按 `maxShipments - 当前 Shopee wave 单量` 计算缺口。
|
||||
- `low_threshold` 只用于单品单件 wave rule 的补单触发判断。
|
||||
- 同一规则内抓单排序已按 `shipment_header.priority`、`cutOffTime`、`purchaseTime`、`orderTime`、`id` 处理。
|
||||
- `WAVE_RULE_FIELD_MATCHING` 已实现基础字段映射,字典口径为:`identifier` 是出库单字段,`value1` 是 `wave_rule` 字段,`value2` 是操作符。
|
||||
- ESS 校验失败单据已有基础 `kickOutWave` 记录能力。
|
||||
- 首次集波入口已有 Redis 工作站锁;Shopee 波次绑定使用波次号维度 Redis 锁。
|
||||
- 同工作站不混做不同订单类型已在入口层落地:Redis 锁前通过 `USED` 格口的 `shopeeWaveCode` 反查 `shipment_header.shipmentType`,发现其它出库类型时记录系统处理日志并返回 `MSG_WRM_0014`。
|
||||
- `WaveService#run` 是异步提交队列消息,当前服务不解析同步库存不足踢单结果。
|
||||
- 库存不足踢单不记录 `kickOutWave`,由 `wms-wave` 回池链路清空 Shopee 绑定并预留上游撤单接口。
|
||||
|
||||
## P0 主链路缺口
|
||||
|
||||
### 1. 计划任务轮询补单入口待恢复
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 计划任务轮询正在作业的工作站和槽口。
|
||||
- 单品单件低于 `low_threshold` 时触发补单。
|
||||
- 非单品单件未达到 `maxShipments` 时触发补单。
|
||||
- 推拣货任务后续无需补单。
|
||||
|
||||
当前代码:
|
||||
|
||||
- 未保留 `pollReplenishment(...)`。
|
||||
- 未保留 `pollReplenishmentOnce(...)`。
|
||||
- 未保留 `replenishCell(...)`、`findPickingWorkstations(...)`、`findReplenishmentCells(...)`。
|
||||
- 已有 `fillShortageCells(...)`,但只在首次集波入口中执行,用于当前工作站已绑定 Shopee 波次格口的缺口补满。
|
||||
- 不保留新增测试类;后台轮询入口、工作站/格口扫描、逐格口补单派发仍需按最终调度策略恢复。
|
||||
|
||||
仍需细化点:
|
||||
|
||||
- 需要按系统参数控制是否启用、轮询间隔和仓库范围。
|
||||
- 需要恢复后台调度入口,并复用 `fillShortageCells/assignToCell` 现有补缺口能力。
|
||||
- 需要结合真实波次状态、连续空轮条件和接口响应做联调细化。
|
||||
|
||||
当前实现口径:
|
||||
|
||||
- 现有补缺口业务收口在 `fillShortageCells(...)`。
|
||||
- 后续如恢复计划任务,建议继续复用工作站 Redis 锁,避免和人工首次集波入口并发抢格口。
|
||||
|
||||
### 2. 一波一单规则已按当前确认口径修正,剩余 ticketType 字典待补齐
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 销售出库任务一波一单。
|
||||
- MTO 任务一波一单。
|
||||
- RT 一波一单。
|
||||
- 按单拣选单据一波一单。
|
||||
|
||||
当前代码:
|
||||
|
||||
- 常量已覆盖 `TICKET_TYPE_XSCK_TASK = 1`。
|
||||
- 常量已覆盖 `TICKET_TYPE_MTO_TASK = 5`。
|
||||
- 常量已覆盖 `TICKET_TYPE_RT = 6`。
|
||||
- `appendSingleWaveFilter(...)` 覆盖 `pickType = 1`、`ticketType in (1,5,6)`。
|
||||
- `appendBatchWaveFilter(...)` 排除 `pickType in (1,2)` 和 `ticketType in (1,5,6)`。
|
||||
- RT 按 `ticketType = 6` 整体一波一单,不使用 Shopee 波次号。
|
||||
- 不保留新增测试类;MTO `ticketType=5`、RT `ticketType=6` 仍需结合真实数据联调验证。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要按最新数据字典确认 `ticketType` 1-7 的完整值域。
|
||||
- RT 已确认按 `ticketType = 6` 特殊处理“不使用 Shopee 波次号”,仍需真实数据验证。
|
||||
|
||||
当前实现口径:
|
||||
|
||||
- `appendSingleWaveFilter(...)` 覆盖按单拣选、XSCK 任务、MTO 任务、RT。
|
||||
- `appendBatchWaveFilter(...)` 同步排除 pickType 一波一单和当前出库类型下的一波一单 ticketType。
|
||||
|
||||
### 3. 推拣货任务分流方法未接入首次集波主入口
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 推拣货任务由上游同步 Shopee 波次号段。
|
||||
- WES 不走取号逻辑。
|
||||
- 根据出库类型和 wave rule 抓取该订单。
|
||||
- 一单一波次一槽口。
|
||||
- 后续无需补单。
|
||||
|
||||
当前代码:
|
||||
|
||||
- 当前未保留 `assignPickingTaskSingleWaves(...)`。
|
||||
- 当前未保留 `findPickingTaskShipments(...)`。
|
||||
- 当前未保留 `isPickingTaskReplenishmentCell(...)`。
|
||||
- 普通批量抓单 `appendBatchWaveFilter(...)` 排除了 `pickType = 2`。
|
||||
- 一波一单 `appendSingleWaveFilter(...)` 未包含 `pickType = 2`。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 推拣货任务当前不会进入首次集波主链路。
|
||||
- 需要恢复或新增主入口分流。
|
||||
- 成功、失败、无数据均只记录系统处理日志,不返回明细数据。
|
||||
|
||||
建议实现口径:
|
||||
|
||||
- 在首次集波入口中增加推拣货任务分流。
|
||||
- 分流顺序建议放在普通空格口批量分配之前。
|
||||
- 推拣货任务继续不参与后续补单。
|
||||
|
||||
### 4. 同工作站不混做不同订单类型已落地,待联调验证
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 用户选择出库类型后,同一个工作站不会混做不同类型。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `findBestMatchedRuleByWorkStationAndOutboundType(...)` 已在 Redis 锁前调用 `hasDifferentActiveShipmentType(...)`。
|
||||
- `findActiveWorkstationShipmentTypes(...)` 通过 `wcs_sorting_wall_cell` 已占用 `USED` 格口关联 `shopeeWaveCode`,反查 `shipment_header.shopeeWave` 和 `shipment_header.shipmentType`。
|
||||
- 如果当前工作站已有其它出库类型,记录系统处理日志并返回 `MSG_WRM_0014`。
|
||||
|
||||
仍需验证点:
|
||||
|
||||
- 需要用真实格口、Shopee 波次和出库单数据验证 SQL 关联是否覆盖全部正在作业场景。
|
||||
- 前端仍需配合做出库类型选择限制和提示。
|
||||
|
||||
当前实现口径:
|
||||
|
||||
- 优先按 `wcs_sorting_wall_cell` 已占用格口关联 `shopeeWaveCode` 反查 `shipment_header.shipmentType`。
|
||||
- 返回明确错误码 `MSG_WRM_0014`,并记录系统处理日志。
|
||||
|
||||
## P1 上游接口和异常闭环
|
||||
|
||||
### 5. Shopee 波次号段申请接口未实现
|
||||
|
||||
docx 要求:
|
||||
|
||||
- `shopee_wave` 每天向上游申请波次号段。
|
||||
- 本地号段用完后继续请求上游。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `acquireUnusedShopeeWave(...)` 只从本地 `shopee_wave` 表取 `status = 100` 的号段。
|
||||
- 本地号段为空时直接返回空。
|
||||
- 方法旁已有 TODO 注释。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要接入上游号段申请接口。
|
||||
- 需要明确请求参数、返回结构、失败重试策略。
|
||||
- 需要明确申请后如何落库以及状态初始值。
|
||||
|
||||
### 6. Shopee 波次绑定接口仍是占位
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 用 Shopee wave + 抓取单号请求上游校验是否允许集在一波。
|
||||
- 当前确认口径为上游绑定接口只有整批成功或整批失败。
|
||||
- 失败单据写入 `shipment_header.kickOutWave`。
|
||||
- 后续同 Shopee wave 补单时过滤这些单据。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `bindShipmentShopeeWave(...)` 已有批量绑定和失败单据 `kickOutWave` 记录逻辑。
|
||||
- `bindShipmentShopeeWave(...)` 内使用 Shopee 波次号维度 Redis 锁控制并发。
|
||||
- 获取锁后会重新检查 `shopee_wave` 号段是否仍可用。
|
||||
- `requestShopeeWaveBind(...)` 是真实上游绑定接口预留位置。
|
||||
- 当前按整批成功/整批失败处理:失败整批写 `kickOutWave`,成功整批写 `shipment_header.shopeeWave` 并同步 `shopee_wave.pickType/groupKey/status`。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 真实 ESS service、方法名、请求 DTO、响应 DTO 未确认。
|
||||
- 真实接口成功/失败判断字段未确认。
|
||||
- 生产环境接口缺失时是否允许放行需要确认。
|
||||
|
||||
建议实现口径:
|
||||
|
||||
- 接入正式接口后只补齐 `requestShopeeWaveBind(...)`。
|
||||
- 响应解析只保留整批成功/失败字段。
|
||||
- 生产环境接口缺失时建议失败并记录系统处理日志,不建议静默全部通过。
|
||||
|
||||
### 7. Flow Pick 封箱和换箱换波接口仍是占位
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 单品单件满槽后先封箱。
|
||||
- 请求 Flow Pick 换箱接口。
|
||||
- 上游校验 OK 后,剩余订单切到新 Shopee 波次。
|
||||
- 上游校验不 OK 时,订单回订单池,取消任务下发,通知 AGV 取消回库。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `changeFlowPickWave(...)` 已有本地流程。
|
||||
- `requestFlowPickSealBox(...)` 动态调用 `sealBox`。
|
||||
- `requestFlowPickChangeBox(...)` 动态调用 `changeBoxWave`。
|
||||
- `essFlowPickService == null` 时本地继续。
|
||||
- `handleFlowPickChangeWaveFailure(...)` 只记录系统处理日志。
|
||||
- `isFlowPickCellFull(...)` 仍以 `maxShipments` 作为满槽判断。
|
||||
|
||||
未完成点:
|
||||
|
||||
- Flow Pick 封箱正式接口未接入。
|
||||
- Flow Pick 换箱正式接口未接入。
|
||||
- 换箱失败后的订单回池、任务取消、AGV 取消回库未实现。
|
||||
- 满槽判断还不是 WCS 真实物理满箱信号。
|
||||
|
||||
### 8. 库存不足踢单和上游撤单闭环未完全落在当前链路
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 波次运行如果有库存不足的单据,直接踢单。
|
||||
- 请求上游撤单接口,告知上游集波剔除的单号。
|
||||
- 库存不足踢单后进入后续补单逻辑。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `addShipmentsToInternalWave(...)` 调用 `WaveService#run`。
|
||||
- `WaveService#run` 是异步提交队列消息,当前服务不解析同步踢单结果。
|
||||
- 相关清空绑定和踢单通知逻辑已有部分转移到 `wms-wave` 模块。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要联调确认库存不足踢单由 `ShipmentAllocationService` 完整处理。
|
||||
- 库存不足踢单不记录 `kickOutWave`,只清空 Shopee 集波绑定并预留上游撤单接口。
|
||||
- 需要接入真实上游撤单接口。
|
||||
|
||||
建议实现口径:
|
||||
|
||||
- `WaveRuleMatchService` 保持触发和补单职责。
|
||||
- 库存不足踢单、清绑定、上游撤单优先由 `wms-wave` 的踢单流程统一处理。
|
||||
- 当前服务只需要能识别踢单后的缺口并由计划任务补单。
|
||||
|
||||
### 9. 库存最优分配规则未在当前服务闭环
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 集波后自动运行波次。
|
||||
- 库存最优分配规则:到期日先进先出,其次工作站点位与库存点位半径最小,同半径低层货位优先。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `WaveRuleMatchService` 只创建内部波次、加入出库单、调用 `WaveService#run`。
|
||||
- 当前服务没有库存分配策略参数。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要确认库存分配规则是否已在 `wms-wave` 模块实现。
|
||||
- 如果需要当前服务传入工作站点位或策略参数,需要补充调用契约。
|
||||
- 需要联调验证实际分配结果符合 docx 优先级。
|
||||
|
||||
## P1 订单池过滤和配置口径
|
||||
|
||||
### 10. cancel、挂起、异常单据过滤口径待确认
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 集波抓单只抓正常单据。
|
||||
- 上游取消、cancel、挂起、标记异常的单据都不抓。
|
||||
|
||||
当前代码:
|
||||
|
||||
- 基础 SQL 过滤包含 `leadingSts = 100`。
|
||||
- 基础 SQL 过滤包含 `trailingSts = 100`。
|
||||
- 基础 SQL 过滤包含 `processType = NORMAL`。
|
||||
- 基础 SQL 过滤包含 `waveId = 0`。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要确认 cancel、挂起、异常是否全部映射进现有状态字段。
|
||||
- 如果存在独立字段或独立 processType,需要补 SQL 过滤。
|
||||
- 需要补最小验证用例覆盖异常单据不入池。
|
||||
|
||||
### 11. `WAVE_RULE_FIELD_MATCHING` 生产配置值域仍需锁定
|
||||
|
||||
docx 要求:
|
||||
|
||||
- 数据字典 `WAVE_RULE_FIELD_MATCHING`。
|
||||
- 标识为出库单字段。
|
||||
- `value1` 为 `wave_rule` 表字段。
|
||||
- `value2` 设置匹配条件,例如包含、等于,配置 `in`、`=`。
|
||||
|
||||
当前代码:
|
||||
|
||||
- `toRuleFieldMapping(...)` 已按 `identifier = shipment_header 字段`、`value1 = wave_rule 字段` 转换。
|
||||
- 已有字段白名单。
|
||||
- 已支持 `IN`、`EQ`、`LE`。
|
||||
- 操作符有 normalize 逻辑。
|
||||
|
||||
未完成点:
|
||||
|
||||
- 需要在生产配置文档或初始化 SQL 中固定值域。
|
||||
- 需要明确是否允许中文“包含/等于/小于等于”。
|
||||
- 需要明确是否只允许 `IN`、`EQ`、`LE`,还是支持更多操作符。
|
||||
|
||||
建议配置口径:
|
||||
|
||||
- `identifier`:`shipment_header` 字段名。
|
||||
- `value1`:`wave_rule` 字段名。
|
||||
- `value2`:`IN`、`EQ`、`LE`。
|
||||
|
||||
## P2 代码结构和可维护性
|
||||
|
||||
### 12. 一波一单方法命名已收敛
|
||||
|
||||
当前代码:
|
||||
|
||||
- `assignSingleShipmentWaves(...)` 承担通用一波一单分流。
|
||||
- 方法内部处理按单拣选、销售出库任务、MTO 任务、RT 等候选。
|
||||
- RT 不使用 Shopee 波次号的特殊口径仍保留在流程说明中。
|
||||
|
||||
仍需关注点:
|
||||
|
||||
- RT 不使用 Shopee 波次号的特殊逻辑单独封装。
|
||||
- 推拣货任务仍保留独立方法,因为它使用上游预写 Shopee 波次号。
|
||||
|
||||
## 非 WaveRuleMatchService 主责但仍需联动
|
||||
|
||||
- `wave_rule` 维护界面需要支持新增、修改规则。
|
||||
- 分播墙明细界面需要支持 `waveRule` 多选绑定。
|
||||
- 出库单界面按单拣选按钮需要只允许订单池 100 状态单据更新 `pickType = 1/null`。
|
||||
- 出库单下发后自动分析 `shipmentCategory1`。
|
||||
- 拣货任务头 `shopeeWave`、`waveRule` 字段需要和 `RunWave` 流程回写联调。
|
||||
- `shopee_wave` 每日号段申请接口需要落库。
|
||||
- WCS/AGV 取消任务和取消回库接口需要联调。
|
||||
|
||||
## 建议推进顺序
|
||||
|
||||
1. 接入推拣货任务首次集波分流。
|
||||
2. 接入真实 ESS 集波校验接口。
|
||||
3. 接入 Shopee 波次号段申请接口。
|
||||
4. 接入 Flow Pick 封箱、换箱接口和失败回滚。
|
||||
5. 与 `wms-wave` 联调库存不足踢单上游撤单和库存最优分配。
|
||||
@@ -0,0 +1,741 @@
|
||||
# WaveRuleMatchService 流程文档
|
||||
|
||||
> 对应实现:`C:\work\gitlab\shopee\wes-loghub\wms-wave\src\main\groovy\com\ittx\wms\wave\service\hairo\WaveRuleMatchService.groovy`
|
||||
>
|
||||
> 本文档描述该服务的**当前代码流程**,按调用入口到出口的完整链路展开,包括主流程、分流流程、补缺口流程、回滚流程和详细的规则匹配机制。
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [服务概述](#1-服务概述)
|
||||
2. [入口与总流程](#2-入口与总流程)
|
||||
3. [前置校验与并发控制](#3-前置校验与并发控制)
|
||||
4. [一波一单分流流程](#4-一波一单分流流程)
|
||||
5. [推拣货任务当前口径](#5-推拣货任务当前口径)
|
||||
6. [标准集波主流程](#6-标准集波主流程)
|
||||
7. [格口分配策略](#7-格口分配策略)
|
||||
8. [Shopee 波次绑定与 ESS 校验](#8-shopee-波次绑定与-ess-校验)
|
||||
9. [内部波次创建与运行](#9-内部波次创建与运行)
|
||||
10. [回滚机制](#10-回滚机制)
|
||||
11. [首次集波内补缺口流程](#11-首次集波内补缺口流程)
|
||||
12. [Flow Pick 换箱换波流程](#12-flow-pick-换箱换波流程)
|
||||
13. [字段匹配规则(WAVE_RULE_FIELD_MATCHING)](#13-字段匹配规则wave_rule_field_matching)
|
||||
14. [方法调用关系图](#14-方法调用关系图)
|
||||
|
||||
---
|
||||
|
||||
## 1. 服务概述
|
||||
|
||||
`WaveRuleMatchService` 是 Shopee 出库集波的核心服务,职责:
|
||||
|
||||
- 接收「工作站 + 出库类型」请求
|
||||
- 查询启用的波次规则(`wave_rule`),按优先级排序
|
||||
- 查找工作站下可用的分播墙格口(`wcs_sorting_wall_cell`)
|
||||
- 从订单池(`shipment_header`)中匹配符合条件的出库单
|
||||
- 完成 Shopee 波次号绑定、ESS 合波校验、内部波次创建与运行
|
||||
- 首次集波成功返回 `ResponseMessageFactory.success()`,不返回「格口 + 命中规则 + 波次」明细
|
||||
|
||||
**三种分流入口:**
|
||||
|
||||
| 分支 | 条件 | 处理方式 |
|
||||
|------|------|----------|
|
||||
| 一波一单分流 | `pickType=1`、`XSCK+ticketType=1`、`ticketType=5`、`ticketType=6` | 一单一个内部波次;RT 不使用 Shopee 波次号 |
|
||||
| 已绑波次格口补缺口 | 空闲格口已绑定 `shopeeWaveCode` 且 `currentWaveRule` 匹配当前规则 | 按 `low_threshold/maxShipments` 计算缺口后补单 |
|
||||
| 空格口首次分配 | 其他普通批量候选单 | 按规则优先级逐规则匹配,先抢占格口,再绑定 Shopee 波次,再创建并运行内部波次 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 入口与总流程
|
||||
|
||||
### 外部入口
|
||||
|
||||
```
|
||||
POST wms/automation/waveRuleMatch/findBestMatchedRule
|
||||
→ WaveRuleMatchController.findBestMatchedRule(map)
|
||||
→ WaveRuleMatchService.findBestMatchedRuleByWorkStationAndOutboundType(warehouseCode, workStation, shipmentType)
|
||||
```
|
||||
|
||||
### 调用链总图
|
||||
|
||||
```
|
||||
findBestMatchedRuleByWorkStationAndOutboundType(String, String, String)
|
||||
│
|
||||
├─ 参数校验(warehouseCode / workStation / shipmentType 非空)
|
||||
├─ findEnabledWorkStation(warehouseCode, workStation)
|
||||
│ └─ 支持工作站编码 或 数字 ID 查询
|
||||
│
|
||||
└─ findBestMatchedRuleByWorkStationAndOutboundType(Long, String) ← 统一入口
|
||||
│
|
||||
├─ [1] 工作站校验:存在 / 启用 ENABLE / 仓库匹配
|
||||
├─ [2] hasDifferentActiveShipmentType
|
||||
│ → 已占用 USED 格口关联 Shopee 波次反查当前工作站作业出库类型
|
||||
│ → 有其它出库类型时记录系统处理日志并返回 MSG_WRM_0014
|
||||
│
|
||||
├─ [3] buildRuleMatchLockKey → Redis 锁(仓库+工作站+出库类型)
|
||||
│ 失败 → MSG_WRM_0012 "工作站正在集波中"
|
||||
│
|
||||
├─ [4] findEnabledRules(warehouseCode)
|
||||
│ → wave_rule WHERE warehouseCode=? AND status=ENABLE ORDER BY wavePriority DESC
|
||||
│ 无规则 → MSG_WRM_0007
|
||||
│
|
||||
├─ [5] assignSingleShipmentWaves(先尝试一波一单候选)
|
||||
│ → pickType=1 / ticketType=1,5,6
|
||||
│
|
||||
├─ [6] fillShortageCells(已绑定 Shopee 波次格口补缺口)
|
||||
│ → 空闲 + shopeeWaveCode 有值 + currentWaveRule 匹配
|
||||
│
|
||||
├─ [7] assignEmptyCells(空格口首次分配)
|
||||
│ → 普通批量候选单进入空格口分配
|
||||
│
|
||||
└─ [8] 成功返回 ResponseMessageFactory.success()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 前置校验与并发控制
|
||||
|
||||
### 3.1 工作站校验
|
||||
|
||||
```
|
||||
findEnabledWorkStation(warehouseCode, workStation)
|
||||
```
|
||||
|
||||
- 入参 `workStation` 兼容 **编码**(String)和 **数字 ID**(自动识别)
|
||||
- 校验:`status=ENABLE`、`warehouseCode` 匹配
|
||||
- 失败返回对应 `MSG_WRM_0004/0005/0006`
|
||||
|
||||
### 3.2 Redis 锁
|
||||
|
||||
```
|
||||
buildRuleMatchLockKey → "wave_rule_match:{warehouseCode}:{workstationId}:{shipmentType}"
|
||||
RedissonLockService.getAndTryLock(lockKey)
|
||||
```
|
||||
|
||||
- 锁粒度:**仓库 + 工作站 + 出库类型**
|
||||
- 获取失败时不阻塞等待,直接返回 `MSG_WRM_0012`(前端可提示用户稍后重试)
|
||||
- 在 finally 块中 `WmsRedissionLockService.unlock(lock)`
|
||||
|
||||
### 3.3 同工作站出库类型隔离
|
||||
|
||||
```
|
||||
hasDifferentActiveShipmentType(warehouseCode, workstationId, shipmentType)
|
||||
→ findActiveWorkstationShipmentTypes(warehouseCode, workstationId)
|
||||
```
|
||||
|
||||
- 查询当前工作站已占用的 `USED` 格口。
|
||||
- 通过格口 `shopeeWaveCode` 关联 `shipment_header.shopeeWave`,获取当前工作站正在作业的 `shipmentType`。
|
||||
- 若存在非本次请求的出库类型,入口直接拒绝本次集波。
|
||||
- 拒绝时记录系统处理日志,并返回 `MSG_WRM_0014`。
|
||||
- 该校验位于 Redis 锁之前,避免无效请求占用集波锁。
|
||||
|
||||
---
|
||||
|
||||
## 4. 一波一单分流流程
|
||||
|
||||
### 触发条件
|
||||
|
||||
`pickType=1`、`XSCK+ticketType=1`、`ticketType=5`、`ticketType=6`
|
||||
|
||||
### 方法
|
||||
|
||||
```
|
||||
assignSingleShipmentWaves(warehouseCode, shipmentType, workstationId, rules)
|
||||
```
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
for each WaveRule:
|
||||
findSingleShipmentWaveShipments(warehouseCode, shipmentType, rule)
|
||||
→ buildAvailableShipmentSql + appendSingleWaveFilter + appendRuleFieldMatching
|
||||
→ LIMIT 1(只取 1 单)
|
||||
if shipment found:
|
||||
createInternalWave(warehouseCode, rule) → 创建内部波次
|
||||
addShipmentsToInternalWave([shipmentId], waveId)
|
||||
→ ShipmentHeaderService.addMultipleToWave + WaveService.run
|
||||
return success
|
||||
|
||||
无任何规则命中 → MSG_WRM_0010
|
||||
```
|
||||
|
||||
### 特点
|
||||
|
||||
- **RT 不使用 Shopee 波次号**(`shopeeWaveCode` 返回空字符串 `""`)
|
||||
- **当前一波一单分流不走 ESS 校验**
|
||||
- **不走格口分配**(不绑定格口)
|
||||
- **一单一个内部波次**
|
||||
|
||||
---
|
||||
|
||||
## 5. 推拣货任务当前口径
|
||||
|
||||
### 触发条件
|
||||
|
||||
`pickType=2`(出库单由上游推入时设置,同时预写入 `shopeeWave`)当前作为待恢复的独立分流口径。
|
||||
|
||||
### 方法
|
||||
|
||||
当前代码中未保留 `assignPickingTaskSingleWaves` 和 `findPickingTaskShipments` 方法。
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
当前已落地:
|
||||
appendBatchWaveFilter 排除 pickType=2,避免推拣货任务进入普通批量集波。
|
||||
|
||||
待恢复:
|
||||
上游推单写入 pickType=2 + shopeeWave 后,
|
||||
WES 独立分流入口按一单一波一槽口处理。
|
||||
```
|
||||
|
||||
### 特点
|
||||
|
||||
| 特性 | 说明 |
|
||||
|------|------|
|
||||
| 波次号来源 | 上游预写入 `shipment_header.shopeeWave`,WES 不走取号逻辑 |
|
||||
| 当前状态 | 普通批量集波已过滤 `pickType=2` |
|
||||
| 待实现 | 独立分流入口、一单一波一槽口、内部波次运行 |
|
||||
| 补单 | 后续仍按“不走补单逻辑”处理 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 标准集波主流程
|
||||
|
||||
### 6.1 主循环
|
||||
|
||||
```
|
||||
for (WaveRule rule : rules) {
|
||||
List<WcsSortingWallCell> cells = findCells(workstationId)
|
||||
// 三层级分组
|
||||
List<List<WcsSortingWallCell>> cellGroups = [
|
||||
sameCurRuleCells, // currentWaveRule == rule.code
|
||||
ruleCells, // currentWaveRule 为空 && waveRule 匹配
|
||||
emptyCells // 两者均为空
|
||||
]
|
||||
for (group : cellGroups) {
|
||||
assignCellNumbers(warehouseCode, shipmentType, workstationId, rule, group)
|
||||
// 命中即返回,不继续尝试下一组格口
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 assignCellNumbers 核心流程
|
||||
|
||||
```
|
||||
assignCellNumbers(warehouseCode, shipmentType, workstationId, rule, cells):
|
||||
│
|
||||
├─ 1. findSingleShipmentWaveShipments → 查一波一单候选
|
||||
│ → pickType=1 / XSCK+ticketType=1 / ticketType=5 / RT
|
||||
│ 有 → singleShipmentWave=true, 取 1 单
|
||||
│ 无 → 继续
|
||||
│
|
||||
├─ 2. findAvailableShipments → 查批量集波候选
|
||||
│ → 排除 pickType=1,2 + 排除一波一单 ticketType
|
||||
│ → 规则字段匹配 + 订单结构匹配 + kickOutWave 过滤
|
||||
│ → LIMIT = maxShipments(默认 30)
|
||||
│
|
||||
├─ 3. 仍无候选 → MSG_WRM_0010
|
||||
│
|
||||
├─ 4. logPriorityRuleConsumption — 记录优先级消费日志
|
||||
│
|
||||
├─ 5. createInternalWave(warehouseCode, rule) → 创建内部波次
|
||||
│ 失败 → MSG_WRM_0009
|
||||
│
|
||||
└─ 6. for each cell in cells:
|
||||
│
|
||||
├─ 取出 cell.shopeeWaveCode
|
||||
│
|
||||
├─ [一波一单] singleShipmentWave=true && cell 已有波次号 → continue(不补入已用格口)
|
||||
│
|
||||
├─ [已有波次] cell 已有波次号 → skipSingleRpln 检查
|
||||
│ → 单品单件 且 未低于 low_threshold → continue
|
||||
│
|
||||
├─ [无波次号] → acquireUnusedShopeeWave → 取新号
|
||||
│ 失败 → rollbackInternalWaveIfEmpty + MSG_WRM_0009
|
||||
│
|
||||
├─ [补充新单] 已有波次号 + 非单品单件/低于阈值
|
||||
│ → findAvailableShipments(..., shopeeWaveCode) 过滤 kickOutWave
|
||||
│
|
||||
├─ assignToCell:
|
||||
│ ├─ pickCellShipmentIds → 按格口缺口截断(单品单件=maxShipments, 其他=差额)
|
||||
│ ├─ ensureCellReadyForWave → 先抢占格口 USED
|
||||
│ ├─ bindShipmentShopeeWave → Shopee 波次绑定接口;成功整批写 shopeeWave,失败整批写 kickOutWave
|
||||
│ ├─ addShipmentsToInternalWave → 加入波次 + 运行
|
||||
│ └─ 成功后消费当前候选池
|
||||
│
|
||||
└─ 一个格口消费一批后 break(不再占用其他格口)
|
||||
```
|
||||
|
||||
### 6.3 订单池 SQL 基础条件
|
||||
|
||||
```sql
|
||||
SELECT id FROM shipment_header
|
||||
WHERE warehouseCode = :warehouseCode
|
||||
AND shipmentType = :shipmentType
|
||||
AND leadingSts = 100 -- 订单池状态
|
||||
AND trailingSts = 100 -- 订单池状态
|
||||
AND processType = 'NORMAL' -- 正常处理流程
|
||||
AND ifnull(waveId, 0) = 0 -- 未加入任何波次
|
||||
AND (lockCode IS NULL OR trim(lockCode) = '') -- 未被锁定
|
||||
AND (cancelTime IS NULL OR cancelTime = '') -- 未取消
|
||||
AND (holdTime IS NULL OR holdTime = '') -- 未挂起
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 格口分配策略
|
||||
|
||||
### 7.1 三层级匹配
|
||||
|
||||
| 层级 | 方法 | 条件 | 优先级 |
|
||||
|------|------|------|--------|
|
||||
| 1 | `matchCurRuleCells` | `currentWaveRule == rule.code` | 最高 |
|
||||
| 2 | `matchRuleCells` | `currentWaveRule` 为空 且 `waveRule` 逗号分隔匹配 rule.code | 中 |
|
||||
| 3 | `matchEmptyCells` | `currentWaveRule` 和 `waveRule` 均为空 | 兜底 |
|
||||
|
||||
### 7.2 格口抢占
|
||||
|
||||
```
|
||||
occupySortingWallCell(warehouseCode, cell, rule, shopeeWaveCode)
|
||||
```
|
||||
|
||||
```sql
|
||||
UPDATE wcs_sorting_wall_cell
|
||||
SET useStatus = 'USED',
|
||||
shopeeWaveCode = ?,
|
||||
currentWaveRule = ?,
|
||||
lastUpdatedBy = ?
|
||||
WHERE id = ?
|
||||
AND warehouseCode = ?
|
||||
AND status = 'ENABLE'
|
||||
AND useStatus = 'IDLE'
|
||||
```
|
||||
|
||||
- 使用乐观锁(`useStatus='IDLE'` 条件),同一格口只能被一个请求抢占成功
|
||||
- 已有相同 Shopee 波次和规则的 USED 格口通过 `ensureCellReadyForWave` 复用(计划任务补单场景)
|
||||
|
||||
### 7.3 格口查询
|
||||
|
||||
```
|
||||
findCells(workstationId)
|
||||
→ 找出工作站下所有分播墙 -> 各墙下启用格口 -> 过滤 IDLE 状态格口
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Shopee 波次绑定与 ESS 校验
|
||||
|
||||
### 8.1 波次号抢占
|
||||
|
||||
```
|
||||
acquireUnusedShopeeWave(warehouseCode, waveType)
|
||||
```
|
||||
|
||||
1. 查询 `shopee_wave` 表:`warehouseCode` + `waveType` + `status=100(UNUSED)`,按 id 升序取前 20
|
||||
2. 逐条尝试乐观更新:`SET status=200(USING) WHERE id=? AND status=100`
|
||||
3. 更新成功的第一条即抢占成功,标记 `processStamp='CLAIMED_UNUSED'`
|
||||
4. 全部失败返回 null(号段耗尽)
|
||||
|
||||
### 8.2 Shopee 波次绑定
|
||||
|
||||
```
|
||||
bindShipmentShopeeWave(warehouseCode, shipmentIds, shopeeWaveCode)
|
||||
```
|
||||
|
||||
**流程:**
|
||||
|
||||
```
|
||||
1. buildShopeeWaveBindLockKey
|
||||
→ 同一 Shopee 波次号绑定串行,避免多个入口同时使用同一号段。
|
||||
|
||||
2. isShopeeWaveCodeAvailable
|
||||
→ 获取锁后重新检查 shopee_wave 是否仍可用。
|
||||
|
||||
3. requestShopeeWaveBind
|
||||
→ 预留真实上游绑定接口。
|
||||
→ 当前口径只有整批成功或整批失败,不处理部分成功。
|
||||
|
||||
4. 失败单据 → markKickOutWave(shipmentIds, shopeeWaveCode)
|
||||
→ UPDATE shipment_header SET kickOutWave = CONCAT(已有的, ',', 新波次号)
|
||||
→ 逗号分隔,同波次号去重
|
||||
|
||||
5. 成功单据 → UPDATE shipment_header SET shopeeWave = ? WHERE id IN (...)
|
||||
→ 同步更新 shopee_wave.status/pickType/groupKey
|
||||
|
||||
6. 返回 ResponseMessageFactory.success()
|
||||
```
|
||||
|
||||
### 8.3 接口对接状态
|
||||
|
||||
`requestShopeeWaveBind` 当前预留真实接口调用位置:
|
||||
|
||||
```
|
||||
接口成功 → 本批出库单全部成功绑定 shopeeWave
|
||||
接口失败 → 本批出库单全部写入 kickOutWave
|
||||
```
|
||||
|
||||
正式接口契约确认后,只需补齐 `requestShopeeWaveBind` 的真实调用;当前不再保留柔性拒单解析方法。
|
||||
|
||||
---
|
||||
|
||||
## 9. 内部波次创建与运行
|
||||
|
||||
### 9.1 createInternalWave
|
||||
|
||||
```
|
||||
createInternalWave(warehouseCode, rule)
|
||||
```
|
||||
|
||||
1. `resolveMasterCode(warehouseCode)` — 从系统参数读取波次主表编码(`WCS/EQUIPMENT_MANUFACTURER`)
|
||||
2. `waveSvc.createInternalWave(session, warehouseCode, masterCode, ruleCode)` — 创建内部波次
|
||||
3. 返回 waveId(Long)
|
||||
4. 失败返回 null
|
||||
|
||||
### 9.2 addShipmentsToInternalWave
|
||||
|
||||
```
|
||||
addShipmentsToInternalWave(shipmentIds, waveId)
|
||||
```
|
||||
|
||||
1. `shipmentHeaderService.addMultipleToWave(session, shipmentIds, waveId)` — 加入波次
|
||||
2. `waveSvc.run(session, waveId)` — 异步提交 `wms.wave` 队列消息
|
||||
3. 任一步失败返回错误
|
||||
|
||||
### 9.3 波次运行结果
|
||||
|
||||
`WaveService#run` 只提交异步队列消息并返回提交结果,`WaveRuleMatchService` 不解析同步库存不足踢单明细。
|
||||
|
||||
库存不足踢单由 `wms-wave` 回池链路处理:回池时清空出库单头 `shopeeWave/waveRule`,不记录 `kickOutWave`;上游撤单接口仍需在回池链路接入。
|
||||
|
||||
---
|
||||
|
||||
## 10. 回滚机制
|
||||
|
||||
### 回滚场景与对应方法
|
||||
|
||||
| 场景 | 回滚方法 | 操作 |
|
||||
|------|----------|------|
|
||||
| Shopee 波次绑定失败 | `rollbackShipmentShopeeWave` | 回退 `shipment_header.shopeeWave = null`(仅当 `waveId=0` 时) |
|
||||
| 内部波次空无单据 | `rollbackInternalWaveIfEmpty` | `UPDATE wave SET status=999`(标记异常,不删除数据) |
|
||||
| 格口抢占失败 | `rollbackWaveShipments` + 逐单 `rollbackShipmentShopeeWave` | 从内部波次剔除 + 回退 Shopee 波次号 |
|
||||
| ESS 拒绝 | `markKickOutWave` | 写入 `kickOutWave`,同波次后续补单过滤 |
|
||||
| 库存不足踢单 | `ShipmentAllocationService.clearShopeeWaveBindingAfterKickOut` | 清空 `shopeeWave/waveRule`,不写 `kickOutWave` |
|
||||
| 内部波次加单失败 | `removeShipmentsFromWave` | 调用 `ShipmentHeaderService.batchRemoveFromWave` |
|
||||
| 新 Shopee 波次未使用 | `rollbackClaimedShopeeWaveIfUnused` | 恢复 `shopee_wave.status=100`(仅当无任何引用时) |
|
||||
| 旧波次无未完成任务 | `markShopeeWaveCompletedIfNoOpenTask` | `shopee_wave.status=300(COMPLETED)` |
|
||||
|
||||
### 回滚原则
|
||||
|
||||
- **不删除数据**:波次标记 999 而非 DELETE,Shopee 波次号恢复 100 而非删除
|
||||
- **不取消出库单**:`handleFlowPickChangeWaveFailure` 明确注释"不取消出库单"
|
||||
- **先绑后解**:绑定顺序为 Shopee 波次号 → 格口 → 内部波次,回滚按反序执行
|
||||
|
||||
---
|
||||
|
||||
## 11. 首次集波内补缺口流程
|
||||
|
||||
### 11.1 入口
|
||||
|
||||
当前状态:`pollReplenishment/pollReplenishmentOnce` 已删除。补缺口能力在首次集波入口中通过 `fillShortageCells` 执行。
|
||||
|
||||
已具备的依赖方法:
|
||||
|
||||
- `fillShortageCells(...)`:入口内逐规则处理已绑定 Shopee 波次的可补格口。
|
||||
- `findShortageCells(Long workStationId, WaveRule rule)`:SQL 查询空闲、已绑定 Shopee 波次、`currentWaveRule` 匹配当前规则的格口。
|
||||
- `calcCellNeedQty(...)`:计算单品单件或非单品单件缺口。
|
||||
- `assignToCell(...)`:先抢占格口,再请求 Shopee 波次绑定接口,再创建并运行内部波次。
|
||||
|
||||
入口不返回分配明细;成功、失败和跳过原因通过系统处理日志记录。
|
||||
|
||||
### 11.2 流程
|
||||
|
||||
```
|
||||
findBestMatchedRuleByWorkStationAndOutboundType(...)
|
||||
│
|
||||
└─ fillShortageCells(warehouseCode, shipmentType, workstationId, rules)
|
||||
│
|
||||
└─ for each rule:
|
||||
findShortageCells(workstationId, rule)
|
||||
→ wcs_sorting_wall_cell
|
||||
→ useStatus = IDLE
|
||||
→ shopeeWaveCode 非空
|
||||
→ currentWaveRule = rule.code
|
||||
│
|
||||
└─ for each cell:
|
||||
calcCellNeedQty
|
||||
findAvailableShipments(..., shopeeWaveCode, groupKey)
|
||||
assignToCell
|
||||
```
|
||||
|
||||
### 11.3 fillShortageCells 逻辑
|
||||
|
||||
```
|
||||
fillShortageCells(warehouseCode, shipmentType, workstationId, rules):
|
||||
│
|
||||
├─ 参数校验(warehouseCode / shipmentType / workstationId / rules)
|
||||
│
|
||||
├─ for each rule:
|
||||
│ ├─ findShortageCells → 查当前规则可补格口
|
||||
│ └─ for each cell:
|
||||
│ ├─ calcCellNeedQty → 计算缺口
|
||||
│ │ ├─ 单品单件: 未拣货数量 < low_threshold → need = maxShipments
|
||||
│ │ ├─ 非单品单件: need = maxShipments - 当前 Shopee 波次已绑单量
|
||||
│ │ └─ need <= 0 → 跳过
|
||||
│
|
||||
├─ resolveShopeeWaveGroupKey → 同一 Shopee 波次只补相同 groupKey 单据
|
||||
│
|
||||
├─ findAvailableShipments(..., shopeeWaveCode, groupKey)
|
||||
│ → 排除 kickOutWave 过滤的已拒单
|
||||
│
|
||||
└─ assignToCell
|
||||
├─ ensureCellReadyForWave → 先抢占格口
|
||||
├─ bindShipmentShopeeWave → Shopee 波次绑定接口
|
||||
├─ createInternalWave
|
||||
└─ addShipmentsToInternalWave → WaveService#run
|
||||
```
|
||||
|
||||
### 11.4 缺口计算
|
||||
|
||||
```
|
||||
calcCellNeedQty(warehouseCode, rule, cell, shopeeWaveCode)
|
||||
```
|
||||
|
||||
| 规则类型 | 触发条件 | 补单数量 |
|
||||
|----------|----------|----------|
|
||||
| 单品单件 | `< low_threshold` | `maxShipments`(一次性补满) |
|
||||
| 非单品单件 | 始终尝试 | `maxShipments - 当前波次已绑单量` |
|
||||
| 新格口/无波次号 | — | 返回 null(不截断) |
|
||||
|
||||
---
|
||||
|
||||
## 12. Flow Pick 换箱换波流程
|
||||
|
||||
### 12.1 触发
|
||||
|
||||
当前 Flow Pick 换箱换波接口为占位流程,需结合真实触发入口恢复;原计划任务补单入口已删除。
|
||||
|
||||
`isFlowPickCellFull`:单品单件 + `countShopeeShipments >= maxShipments`
|
||||
|
||||
### 12.2 流程
|
||||
|
||||
```
|
||||
changeFlowPickWave(workstation, cell, rule):
|
||||
│
|
||||
├─ 1. findFlowPickRemainingShipments
|
||||
│ → 当前工作站 + 旧波次 + 规则下 未完成拣货任务的订单
|
||||
│ 无 → markShopeeWaveCompletedIfNoOpenTask + 返回
|
||||
│
|
||||
├─ 2. requestFlowPickSealBox(封箱)
|
||||
│ → essFlowPickService.sealBox(动态调用)
|
||||
│ 未接入 → 记录日志,返回 true(继续本地换波)
|
||||
│ 失败 → 终止
|
||||
│
|
||||
├─ 3. resolveShopeeWaveType(从剩余订单推断波次类型)
|
||||
│
|
||||
├─ 4. acquireUnusedShopeeWave(取新号段)
|
||||
│ 失败 → 返回错误
|
||||
│
|
||||
├─ 5. requestFlowPickChangeBox(换箱)
|
||||
│ → essFlowPickService.changeBoxWave(动态调用)
|
||||
│ 未接入 → 记录日志,返回 true(继续本地回写)
|
||||
│ 失败 → rollbackClaimedShopeeWaveIfUnused + handleFlowPickChangeWaveFailure + 返回错误
|
||||
│
|
||||
├─ 6. updateFlowPickShopeeWave(回写新波次号)
|
||||
│ → UPDATE shipment_header SET shopeeWave = 新号
|
||||
│ → UPDATE wcs_work_station_pick_task_header SET shopeeWave = 新号
|
||||
│ → UPDATE wcs_sorting_wall_cell SET shopeeWaveCode = 新号
|
||||
│
|
||||
└─ 7. markShopeeWaveCompletedIfNoOpenTask(旧波次标记完成)
|
||||
```
|
||||
|
||||
### 12.3 当前状态
|
||||
|
||||
| 步骤 | 实现状态 | 说明 |
|
||||
|------|----------|------|
|
||||
| 剩余订单查询 | ✅ 已实现 | `findFlowPickRemainingShipments` |
|
||||
| 封箱接口 | ⚠️ 动态调用占位 | `essFlowPickService.sealBox`(未接入时本地跳过) |
|
||||
| 新波次取号 | ✅ 已实现 | `acquireUnusedShopeeWave` |
|
||||
| 换箱接口 | ⚠️ 动态调用占位 | `essFlowPickService.changeBoxWave`(未接入时本地跳过) |
|
||||
| 字段回写 | ✅ 已实现 | `updateFlowPickShopeeWave` |
|
||||
| 旧波次完成 | ✅ 已实现 | `markShopeeWaveCompletedIfNoOpenTask` |
|
||||
| 失败回滚 | ⚠️ 仅日志 | `handleFlowPickChangeWaveFailure` 仅记录日志,未实现 AGV 回库/订单池恢复 |
|
||||
|
||||
---
|
||||
|
||||
## 13. 字段匹配规则(WAVE_RULE_FIELD_MATCHING)
|
||||
|
||||
### 13.1 数据字典结构
|
||||
|
||||
通过数据字典表 `config_detail` + `config_value` 配置,`recordType = 'WAVE_RULE_FIELD_MATCHING'`。
|
||||
|
||||
| 字段 | 含义 | 示例 |
|
||||
|------|------|------|
|
||||
| `identifier` | 出库单字段 | `userDef1`、`shipmentCategory1`、`priority` |
|
||||
| `value1` | 规则字段 | `channelId`、`shopId`、`urgentFlag` |
|
||||
| `value2` | 操作符 | `IN` / `EQ` / `LE` |
|
||||
| `warehouseCode` | 仓库级/全局 | 优先匹配当前仓,无配置时读取 `*` |
|
||||
|
||||
### 13.2 支持的操作符
|
||||
|
||||
| 操作符 | SQL 生成 | 说明 |
|
||||
|--------|----------|------|
|
||||
| `IN`(默认) | `shipmentField IN (:values)` | 规则值按逗号/中文逗号拆分多选 |
|
||||
| `EQ` / `=` / `EQUAL` / `EQUALS` | `shipmentField = :value` | 等值匹配 |
|
||||
| `LE` / `<=` / `LESS_OR_EQUAL` | `ifnull(shipmentField, 0) <= :value` | 数值小于等于 |
|
||||
|
||||
### 13.3 字段白名单
|
||||
|
||||
防止字典配置拼出非预期 SQL,白名单校验在 `toRuleFieldMapping` 中执行:
|
||||
|
||||
**出库单字段(30+):**
|
||||
`shipmentType`, `ticketType`, `pickType`, `sourcePlatform`, `sourceErp`, `erpOrderType`, `route`, `carrierCode`, `shipmentSubType`, `shipmentCategory1~8`, `shipToCountry/State/City/District/Town(Code)`, `hostCompanyCode`, `storeCode`, `shipObjType`, `requestedDeliveryType`, `priority`, `userDef1~8`
|
||||
|
||||
**规则字段(16):**
|
||||
`channelId`, `fulfillmentChainId`, `orderSize`, `skuSizeType`, `categoryLevel1Id`, `shopGroup`, `shopId`, `urgentFlag`, `outerPackaging`, `outerPackagingId`, `deliveryRegion`, `fragile`, `liquid`, `highValue`, `battery`, `danger`
|
||||
|
||||
### 13.4 执行流程
|
||||
|
||||
```
|
||||
resolveRuleFieldMappings(warehouseCode)
|
||||
→ 查 config_detail (优先 warehouseCode, 兜底 '*')
|
||||
→ toRuleFieldMapping(detail)
|
||||
→ 白名单校验
|
||||
→ normalizeRuleOperator 规范化操作符
|
||||
→ 返回 RuleFieldMapping(ruleField, shipmentField, operator)
|
||||
|
||||
appendRuleFieldMatching(sql, params, warehouseCode, rule)
|
||||
for each mapping:
|
||||
switch operator:
|
||||
IN → appendIn(sql, params, shipmentField, ruleField + 'Values', splitCandidates(ruleValue))
|
||||
EQ → appendEquals(sql, params, shipmentField, ruleField + 'Value', ruleValue)
|
||||
LE → appendLessOrEqual(sql, params, shipmentField, ruleField + 'Value', toNonNegativeInteger(ruleValue))
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. 方法调用关系图
|
||||
|
||||
### 14.1 首次集波
|
||||
|
||||
```
|
||||
findBestMatchedRuleByWorkStationAndOutboundType(String, String, String) [入口-工作站编码]
|
||||
└─ findEnabledWorkStation
|
||||
└─ findBestMatchedRuleByWorkStationAndOutboundType(Long, String) [统一入口]
|
||||
├─ findEnabledRules
|
||||
├─ assignSingleShipmentWaves [一波一单分流]
|
||||
│ ├─ findSingleShipmentWaveShipments
|
||||
│ ├─ createInternalWave
|
||||
│ └─ addShipmentsToInternalWave
|
||||
├─ fillShortageCells [已绑定 Shopee 波次格口补缺口]
|
||||
│ ├─ findShortageCells
|
||||
│ ├─ calcCellNeedQty
|
||||
│ ├─ resolveShopeeWaveGroupKey
|
||||
│ ├─ findAvailableShipments(..., shopeeWaveCode, groupKey)
|
||||
│ └─ assignToCell
|
||||
└─ (标准集波) for each rule: [标准集波]
|
||||
├─ findCells → matchCurRuleCells / matchRuleCells / matchEmptyCells
|
||||
└─ assignCellNumbers
|
||||
├─ findSingleShipmentWaveShipments
|
||||
├─ findAvailableShipments
|
||||
├─ createInternalWave
|
||||
├─ acquireUnusedShopeeWave
|
||||
└─ for each cell:
|
||||
├─ skipSingleRpln (单品单件)
|
||||
├─ assignToCell
|
||||
│ ├─ pickCellShipmentIds
|
||||
│ ├─ calcCellNeedQty
|
||||
│ ├─ ensureCellReadyForWave → occupySortingWallCell
|
||||
│ ├─ bindShipmentShopeeWave
|
||||
│ │ ├─ requestShopeeWaveBind
|
||||
│ │ ├─ markKickOutWave (整批失败)
|
||||
│ │ └─ updateShopeeWaveBindingFields (整批成功)
|
||||
│ ├─ addShipmentsToInternalWave → run
|
||||
│ └─ 成功后消费当前候选池
|
||||
└─ (回滚)
|
||||
├─ rollbackInternalWaveIfEmpty
|
||||
├─ rollbackWaveShipments → removeShipmentsFromWave
|
||||
└─ rollbackShipmentShopeeWave
|
||||
```
|
||||
|
||||
### 14.2 首次集波内补缺口
|
||||
|
||||
```
|
||||
fillShortageCells
|
||||
└─ for each rule:
|
||||
├─ findShortageCells
|
||||
└─ for each cell:
|
||||
├─ calcCellNeedQty
|
||||
├─ resolveShopeeWaveGroupKey
|
||||
├─ findAvailableShipments(..., shopeeWaveCode, groupKey)
|
||||
└─ assignToCell
|
||||
```
|
||||
|
||||
### 14.3 查询方法
|
||||
|
||||
```
|
||||
订单查询:
|
||||
buildAvailableShipmentSql ← 基础 SQL(异常过滤)
|
||||
buildAvailableShipmentParams ← 基础参数
|
||||
appendBatchWaveFilter ← 排除一波一单
|
||||
appendSingleWaveFilter ← 一波一单条件
|
||||
appendRuleFieldMatching ← WAVE_RULE_FIELD_MATCHING 字典匹配
|
||||
├─ appendIn / appendEquals / appendLessOrEqual
|
||||
└─ resolveRuleFieldMappings → toRuleFieldMapping
|
||||
appendKickOutFilter ← 排除已拒单
|
||||
appendShipmentPriorityOrder ← 排序
|
||||
|
||||
格口查询:
|
||||
findCells(workstationId)
|
||||
findCells(workstationId, rule)
|
||||
matchCurRuleCells / matchRuleCells / matchEmptyCells
|
||||
findActiveWorkstationShipmentTypes(warehouseCode, workStationId)
|
||||
|
||||
规则查询:
|
||||
findEnabledRules(warehouseCode)
|
||||
|
||||
工作站查询:
|
||||
findEnabledWorkStation(warehouseCode, workStation)
|
||||
|
||||
波次查询:
|
||||
countShopeeShipments(warehouseCode, shopeeWaveCode)
|
||||
resolveShopeeWaveGroupKey(warehouseCode, shopeeWaveCode)
|
||||
resolveShopeeWaveType(warehouseCode, shipmentIds)
|
||||
|
||||
工具方法:
|
||||
toLongValue / toNonNegativeInteger
|
||||
ruleStringValue / ruleIntegerValue
|
||||
splitCandidates / matchesCellWaveRule
|
||||
buildRuleMatchLockKey
|
||||
isSingleRule
|
||||
resolveMasterCode / resolveShipmentLimit / resolveLowThreshold
|
||||
normalizeRuleOperator
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 附录:关键常量
|
||||
|
||||
| 常量 | 值 | 用途 |
|
||||
|------|-----|------|
|
||||
| `SHIPMENT_IN_POOL` | `100` | 出库单订单池状态 |
|
||||
| `SHIPMENT_PROCESS_NORMAL` | `'NORMAL'` | 正常处理流程标识 |
|
||||
| `DEFAULT_SHIPMENT_LIMIT` | `30` | 规则未配 `maxShipments` 的兜底上限 |
|
||||
| `PICK_TYPE_PICKING_BY_ORDER` | `1` | 按单拣选标识 |
|
||||
| `PICK_TYPE_PICKING_TASK` | `2` | 推拣货任务标识 |
|
||||
| `TICKET_TYPE_RT` | `6` | RT ticketType,一波一单且不使用 Shopee 波次号 |
|
||||
| `TICKET_TYPE_XSCK_TASK` | `1` | 销售出库任务 |
|
||||
| `TICKET_TYPE_MTO_TASK` | `5` | MTO 任务 |
|
||||
| `WAVE_RULE_FIELD_MATCHING` | `'WAVE_RULE_FIELD_MATCHING'` | 字段匹配字典类型 |
|
||||
|
||||
## 附录:TODO 清单(代码内标注)
|
||||
|
||||
| 位置 | TODO | 优先级 |
|
||||
|------|------|--------|
|
||||
| `findBestMatchedRuleByWorkStationAndOutboundType` | 用户权限与出库类型绑定 | P1 |
|
||||
| `resolveMasterCode` 前注释 | 库存最优分配规则对齐 | P2 |
|
||||
| `acquireUnusedShopeeWave` 前注释 | Shopee 波次号段申请接口 & 用完续号 | P1 |
|
||||
| `requestFlowPickSealBox` Javadoc | Flow Pick 封箱接口正式对接 | P1 |
|
||||
| `requestFlowPickChangeBox` Javadoc | Flow Pick 换箱接口正式对接 | P1 |
|
||||
| `requestShopeeWaveBind` Javadoc | Shopee 波次绑定接口正式契约对接 | **P0** |
|
||||
| `handleFlowPickChangeWaveFailure` Javadoc | 换波失败完整回滚(订单池恢复/取消任务/AGV 回库) | P1 |
|
||||
@@ -0,0 +1,270 @@
|
||||
# 出库集波规则匹配 API 文档
|
||||
|
||||
> 对应实现:`WaveRuleMatchController#findBestMatchedRule` → `WaveRuleMatchService#findBestMatchedRuleByWorkStationAndOutboundType`
|
||||
|
||||
---
|
||||
|
||||
## 概述
|
||||
|
||||
工作站集波的核心入口。用户在 WES 工作站界面选择出库类型后,前端调用本接口触发自动集波流程:
|
||||
|
||||
1. 根据**工作站 + 出库类型**找出当前可用的分播墙格口
|
||||
2. 按规则优先级查找订单池中符合条件的出库单
|
||||
3. 完成 Shopee 波次绑定、ESS 校验、内部波次创建与运行
|
||||
4. 返回「格口 + 命中规则 + 波次」的分配结果
|
||||
|
||||
---
|
||||
|
||||
## 请求
|
||||
|
||||
### URL
|
||||
|
||||
```
|
||||
POST wms/automation/waveRuleMatch/findBestMatchedRule
|
||||
```
|
||||
|
||||
### 请求体 (JSON)
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `warehouseCode` | String | 是 | 仓库编码 |
|
||||
| `workStation` | String | 是 | 工作站编码(或工作站数字 ID) |
|
||||
| `shipmentType` | String | 是 | 出库类型,如 `XSCK`(销售出库)、`MTO`、`RTS`、`RT` |
|
||||
|
||||
示例:
|
||||
|
||||
```json
|
||||
{
|
||||
"warehouseCode": "WH01",
|
||||
"workStation": "WS001",
|
||||
"shipmentType": "XSCK"
|
||||
}
|
||||
```
|
||||
|
||||
### 出库类型说明
|
||||
|
||||
| 出库类型 | 含义 | 处理方式 |
|
||||
|----------|------|----------|
|
||||
| `XSCK` | 销售出库 | 标准集波(按 ticketType 分流:1=销售出库任务 一波一单,其他批量) |
|
||||
| `MTO` | MTO 出库 | 标准集波(按 ticketType 分流:5=MTO任务 一波一单,其他批量) |
|
||||
| `RTS` | RTS 出库 | 标准批量集波 |
|
||||
| `RT` | RT 出库 | 一波一单,不使用 Shopee 波次号,走库内流程 |
|
||||
|
||||
---
|
||||
|
||||
## 响应
|
||||
|
||||
### 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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}`。
|
||||
|
||||
### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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` | `currentWaveRule` 和 `waveRule` 均为空 |
|
||||
|
||||
### 一波一单处理
|
||||
|
||||
以下单据类型按一波一单处理(每次集波只取 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+):`shipmentType`、`ticketType`、`pickType`、`sourcePlatform`、`sourceErp`、`route`、`carrierCode`、`shipToCountry`、`userDef1-8` 等
|
||||
- **规则字段**(16):`channelId`、`fulfillmentChainId`、`orderSize`、`skuSizeType`、`categoryLevel1Id`、`shopGroup`、`shopId`、`urgentFlag`、`outerPackaging`、`deliveryRegion`、`fragile`、`liquid`、`highValue`、`battery`、`danger` 等
|
||||
|
||||
### 并发控制
|
||||
|
||||
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` 等 |
|
||||
| `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` 过滤生效
|
||||
@@ -0,0 +1,252 @@
|
||||
# SHOPEE_010 出库集波 V1.2 待办事项
|
||||
|
||||
本文按 `C:\Users\zoe\Downloads\SHOPEE_010_出库集波V1.2.docx` 重新整理,状态以当前代码实现为准。
|
||||
|
||||
## 一、当前已落地
|
||||
|
||||
| 模块 | 已落地内容 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 基础表 | `wave_rule`、`shopee_wave` | 已通过 `V3_1_2_3__shopee_outbound_wave_create.sql` 创建基础表,并合入 `groupKey` 字段;`ticketType` 保留用于单据细分。 |
|
||||
| 规则实体 | `WaveRule`、`ShopeeWave` | `WaveRule` 已删除 `orderStructure`、`maxSkuPiecesPerOrder`、`mixModeMaxSkuPiecesFilter` 字段。 |
|
||||
| 波次字段 | `wave.waveRule` | 内部波次记录当前命中的 wave rule。 |
|
||||
| 出库单字段 | `ticketType`、`pickType`、`groupKey`、`cutOffTime`、`purchaseTime`、`orderTime`、`shopeeWave`、`waveRule`、`kickOutWave` | `ticketType` 用于单据细分,`pickType` 用于拣选类型,`groupKey` 用于同波次特征一致性。 |
|
||||
| 格口字段 | `wcs_sorting_wall_cell.waveRule`、`currentWaveRule`、`shopeeWaveCode` | 支持格口绑定多个 wave rule,并记录当前执行规则和 Shopee 波次号。 |
|
||||
| 任务头字段 | `wcs_work_station_pick_task_header.shopeeWave`、`waveRule` | 字段已补齐,完整回写链路仍需结合任务生成结果验证。 |
|
||||
| 系统参数 | `WAVE/low_threshold` | 仅单品单件 wave rule 使用,低于阈值触发补单判断。 |
|
||||
| 工作站入口 | `findBestMatchedRuleByWorkStationAndOutboundType` | 支持工作站编码入口和 workstationId 入口。 |
|
||||
| 并发控制 | Redis 锁 | 锁粒度为仓库、工作站、出库类型,避免同一工作站并发重复集波。 |
|
||||
| 工作站类型隔离 | `hasDifferentActiveShipmentType` | 入口层已校验同工作站不可混做不同出库类型,命中时记录系统处理日志并返回 `MSG_WRM_0014`。 |
|
||||
| 规则优先级 | `wavePriority desc` | 高优先级规则不足 `maxShipments` 时仍优先消费该规则下可匹配订单。 |
|
||||
| 抓单排序 | `priority`、`cutOffTime`、`purchaseTime`、`orderTime` | 同一规则内按优先级和时间排序,时间越早越优先。 |
|
||||
| 波次类型口径 | `wave_rule.waveType`、`shopee_wave.waveType`、`shipment_header.shipmentCategory1` | 三者已确认为同一维度,规则筛单和 Shopee 号段取号均按 `shipmentCategory1` 编码处理。 |
|
||||
| 字典匹配 | `WAVE_RULE_FIELD_MATCHING` | 当前口径为 `identifier=shipment_header字段`、`value1=wave_rule字段`、`value2=匹配条件`。 |
|
||||
| Shopee 波次绑定 | `bindShipmentShopeeWave` | 上游绑定接口成功后整批写入 `shipment_header.shopeeWave`,失败后整批写入 `kickOutWave`。 |
|
||||
| ESS 拒单记录 | `kickOutWave` | ESS 拒绝单据写入 `shipment_header.kickOutWave`,同 Shopee 波次后续抓单过滤。 |
|
||||
| 内部波次 | 创建、加单、运行 | 已调用 `WaveService#createInternalWave`、`ShipmentHeaderService#addMultipleToWave`、`WaveService#run` 异步提交运行。 |
|
||||
| 验证方式 | 编译、静态检查、真实业务联调 | 不保留新增测试类;一波一单、轮询补单和同工作站出库类型隔离以编译和真实联调验证为准。 |
|
||||
| Shopee 绑定接口占位 | `requestShopeeWaveBind` | 预留真实接口调用位置,当前按整批成功/整批失败处理,不做部分成功解析。 |
|
||||
| 字段白名单 | `ALLOWED_RULE_FIELDS` / `ALLOWED_SHIPMENT_FIELDS` | shipment_header 白名单 30+ 字段,wave_rule 白名单 16 字段,防止 SQL 拼接注入。 |
|
||||
| 格口三层级匹配策略 | sameCurRuleCells / ruleCells / emptyCells | 优先复用同规则已绑定格口,再匹配规则配置格口,最后分配空闲格口。 |
|
||||
| 一波一单 | `assignSingleShipmentWaves` | 按单拣选、销售出库任务、MTO 任务、RT 等一波一单候选按一单一个内部波次处理;RT 不使用 Shopee 波次号。 |
|
||||
| 一波一单候选 | `findSingleShipmentWaveShipments` | 按单拣选(`pickType=1`)、销售出库任务(`ticketType=1`)、MTO 任务(`ticketType=5`)、RT(`ticketType=6`) 均按一波一单处理。 |
|
||||
| 按单拣选过滤 | `appendBatchWaveFilter` | 批量集波在 SQL 层排除 `pickType=1` 单据。 |
|
||||
| Flow Pick 换箱换波本地闭环 | `changeFlowPickWave` | 封箱/换箱接口动态调用占位,未接入时本地执行换波回写和格口切换。 |
|
||||
| Shopee 波次号回退 | `rollbackClaimedShopeeWaveIfUnused` | 新号段已抢占但未被任何订单引用时恢复为未使用。 |
|
||||
| 旧波次自动完成 | `markShopeeWaveCompletedIfNoOpenTask` | 旧波次无未完成任务时标记为完成状态。 |
|
||||
| 推拣货任务过滤 | `appendBatchWaveFilter` | `pickType=2` 标识推拣货任务,当前普通批量集波排除该类单据;上游预写入波次的独立分流待接口口径确认。 |
|
||||
| 异常订单过滤 | `buildAvailableShipmentSql` | 在基础 SQL 中增加 `cancelTime/holdTime` 过滤,取消/挂起异常单据不进入抓单池。 |
|
||||
|
||||
## 二、数据字典配置口径
|
||||
|
||||
`WAVE_RULE_FIELD_MATCHING` 是 docx 中“波次规则字段匹配”的落地方式。
|
||||
|
||||
| 字段 | 含义 | 例子 |
|
||||
| --- | --- | --- |
|
||||
| `recordType` | 固定字典类型 | `WAVE_RULE_FIELD_MATCHING` |
|
||||
| `warehouseCode` | 仓库编码 | 优先当前仓,未配置时读取 `*` |
|
||||
| `identifier` | 出库单字段,即 `shipment_header` 字段 | `userDef1`、`shipmentCategory1`、`priority` |
|
||||
| `value1` | 规则字段,即 `wave_rule` 字段 | `channelId`、`shopId`、`urgentFlag` |
|
||||
| `value2` | 匹配条件 | `IN`、`=`、`EQ`、`LE`、`<=` |
|
||||
|
||||
当前支持的匹配条件:
|
||||
|
||||
| `value2` | 含义 |
|
||||
| --- | --- |
|
||||
| `IN` | `shipment_header.identifier in (wave_rule.value1 多选值)` |
|
||||
| `=` / `EQ` / `EQUAL` / `EQUALS` | `shipment_header.identifier = wave_rule.value1` |
|
||||
| `LE` / `<=` / `LESS_OR_EQUAL` | `shipment_header.identifier <= wave_rule.value1` |
|
||||
|
||||
当前白名单:
|
||||
|
||||
| 类型 | 允许字段 |
|
||||
| --- | --- |
|
||||
| `shipment_header` 字段 | `shipmentType`、`ticketType`、`pickType`、`sourcePlatform`、`sourceErp`、`erpOrderType`、`route`、`carrierCode`、`shipmentSubType`、`shipmentCategory1-8`、`shipToCountry`、`shipToState`、`shipToCity`、`shipToDistrict`、`shipToTown`、`shipToCountryCode`、`shipToStateCode`、`shipToCityCode`、`shipToDistrictCode`、`shipToTownCode`、`hostCompanyCode`、`storeCode`、`shipObjType`、`requestedDeliveryType`、`priority`、`userDef1-8` |
|
||||
| `wave_rule` 字段 | `channelId`、`fulfillmentChainId`、`orderSize`、`skuSizeType`、`categoryLevel1Id`、`shopGroup`、`shopId`、`urgentFlag`、`outerPackaging`、`outerPackagingId`、`deliveryRegion`、`fragile`、`liquid`、`highValue`、`battery`、`danger` |
|
||||
|
||||
配置示例:
|
||||
|
||||
| warehouseCode | recordType | identifier | value1 | value2 | 说明 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `*` | `WAVE_RULE_FIELD_MATCHING` | `userDef1` | `channelId` | `IN` | 出库单 `userDef1` 匹配规则 `channelId` 多选值。 |
|
||||
| `*` | `WAVE_RULE_FIELD_MATCHING` | `priority` | `urgentFlag` | `LE` | 出库单优先级小于等于规则 `urgentFlag`。 |
|
||||
| `WH01` | `WAVE_RULE_FIELD_MATCHING` | `userDef7` | `shopId` | `=` | 仓库级配置优先于 `*`。 |
|
||||
|
||||
## 三、待实现功能
|
||||
|
||||
### 3.1 上游接口
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 待实现 | Shopee WMS 初始化 `wave_rule` 接口 | docx 要求上游初始化波次规则,WES 支持维护和新增。 |
|
||||
| 待实现 | Shopee 波次号段申请接口 | `shopee_wave` 数据应由上游下发保存,每天号段用完后继续申请。 |
|
||||
| 待确认 | ESS 合波校验正式契约 | 当前有动态调用和常见响应解析,需按真实请求/响应结构收敛。 |
|
||||
| 待实现 | 库存不足踢单上游撤单接口 | `WaveService#run` 为异步提交,库存不足踢单由 `wms-wave` 回池链路清空 Shopee 绑定且不记录 `kickOutWave`;仍需对接上游撤单接口。 |
|
||||
| 占位待联调 | Flow Pick 换箱接口 | `WaveRuleMatchService` 中 `requestFlowPickSealBox/requestFlowPickChangeBox` 已动态调用占位;本地换波闭环(字段回写/格口切换)已实现,待真实接口接入和联调。 |
|
||||
| 待确认 | 推拣货任务与推出库单区分标识 | docx 要求两类单据入口分流,上游需提供标识。 |
|
||||
|
||||
### 3.2 Wave Rule 字段与页面能力
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 待实现 | Dropdown 字段支持 All、多选、模糊搜索 | 涉及 `channelId`、`fulfillmentChainId`、`orderSize`、`shopGroup`、`shopId` 等字段。 |
|
||||
| 待实现 | Input 字段支持输入多个值 | 如 `shop_id` 文本输入。 |
|
||||
| 待实现 | `Include / Exclude / Only` 语义 | docx 中 `SKU Size`、`L1 Category` 等 SKU 维度字段需要该语义;当前 `WAVE_RULE_FIELD_MATCHING` 只支持 IN/EQ/LE,无 Include/Exclude/Only。 |
|
||||
| 待实现 | `Urgent Flag` 区间输入(BETWEEN) | docx 示例为 `3-99`,当前只有 `LE`(小于等于)操作符,需新增 BETWEEN 匹配条件支持。 |
|
||||
| 待实现 | `Max SKU Pieces Per Order` | 不恢复为 `WaveRule` 字段,后续应基于 `shipment_detail` 聚合判断。 |
|
||||
| 待实现 | `Mix Mode Max SKU Pieces Filter` | 仅 MSAQ 规则使用,不恢复为 `WaveRule` 字段,后续基于明细聚合判断。 |
|
||||
| 已落地 | `wave_rule.waveType` 与 `shopee_wave.waveType` 口径 | 已确认同一维度,取号不再使用外层出库单类型,改为按已筛出单据的 `shipmentCategory1` 获取 Shopee 波次号段。 |
|
||||
|
||||
### 3.3 基础数据初始化
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 待实现 | Channel 初始化 | 下拉展示 ID + Name,如 `(100004)SPX`。 |
|
||||
| 待实现 | Fulfillment Chain 初始化 | 下拉展示 ID + Name。 |
|
||||
| 待实现 | L1 Category 初始化 | 变动枚举,同步自 Shopee WMS。 |
|
||||
| 待实现 | Shop Group 初始化 | 变动枚举,同步自 Shopee WMS。 |
|
||||
| 待实现 | Shop 初始化 | 支持下拉和文本输入。 |
|
||||
| 待实现 | Outer Consumable ID 初始化 | 下拉展示外包材 ID + Name。 |
|
||||
| 待实现 | 出库单接口字段落库 | Shopee 匹配字段需按 `WAVE_RULE_FIELD_MATCHING.identifier` 落到现有字段或 `userDef1-8`。 |
|
||||
|
||||
### 3.4 订单结构分析
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | `shipmentCategory1` 自动回填 | 用于 wave rule 匹单。 |
|
||||
| 待验证 | 真实订单样例验证 | 需用 Shopee 样例确认 `SSSQ/SSAQ/MSAQ/MSSQ` 编码。 |
|
||||
| 待实现(P1) | 异常边界处理 | 当前只通过 `processType='NORMAL'` 过滤;取消、挂起、异常、短配等具体状态需显式排除,避免非正常单据误入订单池。 |
|
||||
|
||||
docx 结构编码:
|
||||
|
||||
| 结构 | 编码 | 含义 |
|
||||
| --- | --- | --- |
|
||||
| `SSSQ` | `1` | 单 SKU 单件。 |
|
||||
| `Same SKU Same Qty` | `2` | 与 SSSQ 同逻辑口径。 |
|
||||
| `MSAQ` | `3` | 多 SKU 多件。 |
|
||||
| `SSAQ` | `4` | 单 SKU 多件。 |
|
||||
| `MSSQ` | `5` | 多品单件。 |
|
||||
|
||||
### 3.5 工作站集波
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | 工作站 + 出库类型入口 | 当前可按工作站匹配规则和格口。 |
|
||||
| 已落地 | Redis 锁 | 防止同一工作站同类型重复集波。 |
|
||||
| 已落地 | 格口多规则绑定 | `wcs_sorting_wall_cell.waveRule` 多值逗号分隔。 |
|
||||
| 已落地 | 按 `wavePriority` 高到低抓单 | 高优先级规则不足 `maxShipments` 仍先消费。 |
|
||||
| 已落地 | 同规则内订单优先级排序 | `priority desc`,时间越早越优先。 |
|
||||
| 待实现 | 用户权限和出库类型绑定 | 登录工作站只能选择当前用户有权限的出库类型。 |
|
||||
| 已落地 / 待前端联调 | 同工作站不混做不同订单类型 | 后端入口已通过 `USED` 格口关联 Shopee 波次反查当前作业出库类型,发现其它类型返回 `MSG_WRM_0014`;前端仍需补选择约束和提示。 |
|
||||
| 待确认 | 未绑定 waveRule 的格口是否默认所有规则 | docx 有该口径;当前代码 `matchEmptyCells` 已处理空规则格口作为兜底,但业务上是否启用需确认。 |
|
||||
|
||||
### 3.6 合波校验与 Shopee 波次绑定
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | 抢占未使用 Shopee 波次号 | 按 `status=100` 更新为 `200`,避免并发重复取号。 |
|
||||
| 已落地 | 先写 `shipment_header.shopeeWave` 再加入内部波次 | 符合前置要求。 |
|
||||
| 已落地 | ESS 拒单写 `kickOutWave` | 支持多个 wave 号逗号分隔。 |
|
||||
| 已落地 | 同 Shopee 波次补单过滤 `kickOutWave` | 后续该波次抓单过滤被拒订单。 |
|
||||
| 待验证 | ESS 真实响应结构 | 当前支持常见 ID、单号、Map 结构,需联调验证。 |
|
||||
| 已落地 | 合波校验不通过后持续补单重试策略 | 格口内候选池循环和计划任务轮询补单均复用 `kickOutWave` 过滤。 |
|
||||
|
||||
### 3.7 内部波次与波次运行
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | 创建内部波次 | 当前通过 `WaveService#createInternalWave` 创建。 |
|
||||
| 已落地 | 批量加入内部波次 | 当前调用 `ShipmentHeaderService#addMultipleToWave`。 |
|
||||
| 已落地 | 加入后直接运行 | 当前调用 `WaveService#run` 异步提交 `wms.wave` 队列消息。 |
|
||||
| 待实现 | 库存最优分配规则对齐 | docx 要求先到期先出/先进先出,其次工作站点位与库存点位半径最小,同半径低层优先。 |
|
||||
| 已明确 | 波次运行结果不在当前服务同步解析 | `WaveService#run` 是异步提交,`WaveRuleMatchService` 只判断提交是否成功。 |
|
||||
| 待实现(P0) | 库存不足踢单通知上游撤单 | 库存不足回池不记录 `kickOutWave`,需在 `wms-wave` 回池链路对接上游撤单接口。 |
|
||||
| 待验证 | 任务头字段完整回写 | `wcs_work_station_pick_task_header.shopeeWave`、`waveRule` 需结合任务生成结果验证。 |
|
||||
|
||||
### 3.8 Flow Pick 单品单件动态加单与换箱换波
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | `low_threshold` 基础判断 | 仅单品单件规则使用。 |
|
||||
| 已落地 | 首次集波内补缺口 | 当前在首次集波入口中调用 `fillShortageCells`,对已绑定 Shopee 波次的空闲格口按 `low_threshold/maxShipments` 补满。 |
|
||||
| 已落地 | 槽口放满换箱触发 | 当前以单品单件 `wave_rule.maxShipments` 作为满槽阈值;达到后进入 Flow Pick 换箱换波流程。 |
|
||||
| 已落地 | 放满后剩余订单换波 | 查询当前工作站、旧 Shopee 波次、当前 `waveRule` 下未完成拣货任务订单,并重新取同单据类型的 Shopee 波次号段。 |
|
||||
| 已落地 | Flow pick 换箱接口占位 | `WaveRuleMatchService` 通过可选 `essFlowPickService.sealBox/changeBoxWave` 承接真实接口;接口未接入时记录系统处理日志并执行本地换波闭环。 |
|
||||
| 已落地 | 换波成功后字段回写 | 批量更新剩余订单任务头和出库单头 `shopeeWave`,新 `shopee_wave.status=200`,格口切换到新 `shopeeWaveCode/currentWaveRule`。 |
|
||||
| 待联调(P1) | 换波失败回滚 | 当前 `handleFlowPickChangeWaveFailure` 只记录系统处理日志并回退未使用的新 Shopee 波次状态;恢复订单池、取消任务下发、通知 AGV 取消回库待真实接口接入。 |
|
||||
|
||||
### 3.9 计划任务轮询补单
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 待实现 | 计划任务入口 | 当前已删除 `pollReplenishment/pollReplenishmentOnce`;如需后台轮询补单,需按最终调度策略重新接入计划任务入口。 |
|
||||
| 已落地 | 首次集波内扫描可补格口 | 当前 `fillShortageCells` 通过 `findShortageCells` 查询空闲、已绑定 Shopee 波次且 `currentWaveRule` 匹配的格口。 |
|
||||
| 已落地 | 单品单件补单 | `calcCellNeedQty` 支持未拣货数量低于 `low_threshold` 时按 `wave_rule.maxShipments` 抓单。 |
|
||||
| 已落地 | 非单品单件补单 | `calcCellNeedQty` 支持统计当前 Shopee 波次已绑定订单数并按 `maxShipments` 计算缺口。 |
|
||||
| 已落地 | 补单后 ESS 校验 | `fillShortageCells` 复用 `assignToCell` 和 `bindShipmentShopeeWave`。 |
|
||||
| 部分落地 | 补单失败过滤 | 被 ESS 拒绝的单继续写 `kickOutWave`,同波次后续抓单过滤;库存不足踢单不写 `kickOutWave`。 |
|
||||
| 已落地 | 补单成功自动加内部波次并运行 | 单格口补单成功后创建内部波次,调用 `addMultipleToWave` 和 `WaveService#run` 异步提交运行。 |
|
||||
|
||||
### 3.10 推拣货任务与推出库单分流
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 待实现 | 推拣货任务分流(`pickType=2`) | 当前普通批量集波已通过 `appendBatchWaveFilter` 排除 `pickType=2`,独立分流入口待按上游推单口径恢复。 |
|
||||
| 待实现 | 推拣货任务一单一波一槽口 | 需在独立分流入口中实现每单占一个空闲格口、创建独立内部波次且不走补单逻辑。 |
|
||||
| 已落地 | 推出库单继续标准集波 | 不受影响,推拣货任务分流后剩余订单继续标准集波链路。 |
|
||||
| 已落地 | 异常订单过滤增强 | `buildAvailableShipmentSql` 增加 `cancelTime/holdTime` 过滤,取消/挂起单据不进入抓单池。 |
|
||||
| 待联调 | 上游推单接口对接 | `pickType=2` + `shopeeWave` 预写入需上游在推单时写入;WES 侧当前仅完成普通批量过滤,独立分流待恢复。 |
|
||||
|
||||
### 3.11 按单拣选与单据类型补充
|
||||
|
||||
| 状态 | 待办 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 已落地 | 出库单界面新增“更新按单拣选”按钮 | 支持多选出库单,点击后弹窗选择“是/否”。 |
|
||||
| 已落地 | 限制只允许更新订单池状态单 | 仅 `shipment_header` 处于订单池 `100` 状态的单据可更新。 |
|
||||
| 已落地 | 回写 `shipment_header.pickType` | 选择“是”时更新为 `1`,选择“否”时清空。 |
|
||||
| 已落地 | 集波抓单过滤按单拣选单据 | 工作站普通 Shopee 集波已过滤 `pickType=1` 的单据。 |
|
||||
| 已落地 | 按单拣选一波一单 | `pickType=1` 的单据当前进入 `assignSingleShipmentWaves`,按一单一波一格口处理。 |
|
||||
| 部分落地 | 单据类型细分处理 | `shipmentType` 包含 `XSCK`、`MTO`、`RTS`、`RT`;当前已在 Shopee 集波入口排除 `RT`。 |
|
||||
| 部分落地 | `ticketType` 细分处理 | 字段和页面展示已补齐;`ticketType` 为数字枚举,当前代码已处理 `1=销售出库任务`、`5=MTO任务`、`6=RT` 分流一波一单。 |
|
||||
| 已落地 | 一波一单规则 | 销售出库任务(`XSCK+ticketType=1`)、MTO任务(`ticketType=5`)、RT(`ticketType=6`)、按单拣选单据均按 1 单创建 1 个内部波次;销售出库任务/MTO任务仍走 Shopee 波次校验,RT 不取 Shopee 波次。 |
|
||||
| 部分落地 | RT 库内流程 | 当前 RT 已按一单一个内部波次运行且不取 Shopee 波次;实际外部库内接口如需对接仍待补充。 |
|
||||
|
||||
## 四、验证待办
|
||||
|
||||
| 状态 | 验证项 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 未执行 | `:wms-wave:compileGroovy` | 本轮仅同步文档,按要求不额外执行编译验证。 |
|
||||
| 不适用 | WaveRuleMatchService 新增测试类 | 已按要求删除新增测试类,后续不再新增或修改测试类。 |
|
||||
| 待验证 | 真实规则匹配 | 用真实 `wave_rule` 和出库单字段验证 `IN`、`=`、`LE`。 |
|
||||
| 待验证 | Shopee 波次绑定接口 | 用真实接口验证 `requestShopeeWaveBind` 成功/失败口径。 |
|
||||
| 待验证 | `kickOutWave` 过滤 | 验证同 Shopee 波次二次补单不再抓被拒单。 |
|
||||
| 待验证 | 内部波次运行后字段回写 | 验证出库单、任务头、wave、shopee_wave 状态一致。 |
|
||||
| 待验证 | 按单拣选分流 | 验证 `pickType=1` 单据不会被普通集波抓取,且可通过 `assignSingleShipmentWaves` 一波一单处理。 |
|
||||
| 待验证 | RT 类型分流 | 验证 `RT` 不取 Shopee 波次号、不调用出库上游接口,改走库内流程。 |
|
||||
| 待执行 | Flow Pick 换箱换波完整链路 | 验证 `changeFlowPickWave` 满槽→封箱→取号→回写→旧波次完成的本地闭环。 |
|
||||
| 待执行 | 库存不足踢单处理验证 | 验证 `wms-wave` 回池时清空 `shopeeWave/waveRule`、不写 `kickOutWave`,并在接口接入后通知上游撤单。 |
|
||||
| 待执行 | `rollbackClaimedShopeeWaveIfUnused` 校验 | 验证新 Shopee 波次号段在绑定失败后正确恢复为未使用。 |
|
||||
| 待验证 | `matchEmptyCells` 兜底逻辑 | 若业务启用未绑定 waveRule 格口默认所有规则,需验证兜底匹配正确性。 |
|
||||
| 待执行 | 同工作站不混做不同订单类型验证 | 验证已占用格口存在其它 `shipmentType` 时入口返回错误并写系统处理日志,同类型或空工作站可继续集波。 |
|
||||
|
||||
## 五、建议优先级(基于 docx + 代码交叉分析)
|
||||
|
||||
| 优先级 | 事项 | 代码现状 |
|
||||
| --- | --- | --- |
|
||||
| **P0 🔥** | 补齐库存不足踢单上游撤单 | `WaveService#run` 异步提交,不在 `WaveRuleMatchService` 解析结果;需在 `wms-wave` 回池链路接入上游撤单接口。 |
|
||||
| **P0 🔥** | Shopee 波次绑定接口正式契约对接 & 联调 | `requestShopeeWaveBind` 预留真实接口调用位置,需真实 ESS/WMS 联调收敛。 |
|
||||
| **P1** | Flow Pick 换箱接口正式对接 + 失败回滚 | `requestFlowPickSealBox/requestFlowPickChangeBox` 动态调用占位;`handleFlowPickChangeWaveFailure` 仅为日志,未实现 AGV 回库/订单池恢复。 |
|
||||
| **P1** | 推拣货任务分流 + 上游推单接口联调 | 当前普通批量已排除 `pickType=2`,独立分流入口和上游推单写入 `pickType=2` + `shopeeWave` 待联调恢复。 |
|
||||
| **P1** | 用户权限+出库类型绑定 | 工作站安全控制,当前代码无用户权限校验逻辑。 |
|
||||
| **P1** | 异常订单过滤(取消/挂起/异常/短配) | 当前只靠 `processType='NORMAL'` 过滤,精度不够。 |
|
||||
| **P1** | 按单拣选一波一单联调 | `pickType=1` 当前走 `assignSingleShipmentWaves`,仍需真实数据验证一单一波一格口。 |
|
||||
| **P1** | Shopee 波次号段申请接口 | 当前只从已落库表取号,无上游申请逻辑。 |
|
||||
| **P1** | Shopee WMS 初始化 wave_rule 接口 | 上游初始化波次规则,WES 支持维护新增。 |
|
||||
| **P2** | Urgent Flag 区间输入(BETWEEN) | 当前只有 LE 操作符,需新增 BETWEEN 匹配条件。 |
|
||||
| **P2** | Include / Exclude / Only 语义 | SKU 维度字段需要该语义,当前字典只支持 IN/EQ/LE。 |
|
||||
| **P2** | Max SKU Pieces / Mix Mode Filter | 不恢复为 WaveRule 字段,需基于 `shipment_detail` 聚合判断。 |
|
||||
| **P2** | 库存最优分配规则(到期日/半径/低层优先) | 分配算法增强,docx 明确要求。 |
|
||||
| **P2** | Flow Pick 失败回滚完善(AGV 取消回库/订单池恢复) | 当前仅日志占位。 |
|
||||
| **P2** | 计划任务轮询补单按真实波次状态和连续空轮条件细化 | 调度入口已落地,后续按真实波次状态、连续空轮条件和接口响应做细化。 |
|
||||
| **P3** | 基础数据同步接口(Channel/Fulfillment Chain/Shop 等) | 管理页面能力,非核心链路。 |
|
||||
| **P3** | Dropdown 多选/模糊搜索、Input 多值 | 前端组件能力。 |
|
||||
| **P3** | ticketType 值 2/4/5/6/7 含义补齐 | 当前明确处理 1、5、6,其他值域说明仍需补齐。 |
|
||||
@@ -0,0 +1,710 @@
|
||||
# SHOPEE_010 出库集波 V1.2 改动计划
|
||||
|
||||
## 一、文档目的
|
||||
|
||||
本文档用于把《SHOPEE_010_出库集波V1.2.docx》中的需求先整理成可执行的改动计划,再按代码模块落地。
|
||||
|
||||
目标是先明确:
|
||||
|
||||
- 要改什么
|
||||
- 改到哪些模块
|
||||
- 先后顺序怎么排
|
||||
- 每一步怎么验证
|
||||
|
||||
## 二、需求背景
|
||||
|
||||
本需求围绕“出库集波”展开,核心是把 Shopee WES 的波次规则、波次号段、订单筛选、工作站集波、补单、踢单、换箱换波和执行联动串成一套闭环流程。
|
||||
|
||||
从原文看,主要涉及以下能力:
|
||||
|
||||
- 新增和维护 wave rule
|
||||
- 新增波次号段表 `shopee_wave`
|
||||
- 按订单属性自动分析订单类型
|
||||
- 工作站按订单类型和 wave rule 集波
|
||||
- 按优先级抓单、补单、踢单
|
||||
- 单品单件波次的动态加单和换箱换波
|
||||
- 绑定分拨墙槽口和 wave rule
|
||||
- 与上游接口做波次校验和号段申请
|
||||
|
||||
## 三、需求拆分
|
||||
|
||||
### 3.1 基础数据与规则配置
|
||||
|
||||
需要补齐 wave rule 的规则配置能力,包括:
|
||||
|
||||
- 新增 `wave_rule` 表
|
||||
- 支持波次规则字段配置
|
||||
- 支持初始化和后续新增、修改 wave rule
|
||||
- 支持优先级 `wavePriority`
|
||||
- 支持规则级最大订单数 `wave_rule.maxShipments`
|
||||
- 支持规则字段和出库单字段匹配
|
||||
|
||||
### 3.2 波次号段管理
|
||||
|
||||
需要新增波次号段表 `shopee_wave`,用于:
|
||||
|
||||
- 按天向上游申请号段
|
||||
- 用完后继续请求上游
|
||||
- 记录号段状态
|
||||
- 记录波次类型、编号和使用状态
|
||||
|
||||
### 3.3 订单分析与规则匹配
|
||||
|
||||
需要在出库单下发后自动分析订单:
|
||||
|
||||
- 单 SKU 单件 `SSSQ`,也就是 `Same SKU Same Qty`
|
||||
- 单 SKU 多件 `SSAQ`
|
||||
- 多 SKU 多件 `MSAQ`
|
||||
- 多品单件 `MSSQ`
|
||||
|
||||
分析结果要写入出库单头部字段 `shipmentCategory1`,用于 wave rule 匹单。
|
||||
|
||||
当前代码侧已落地的口径是:
|
||||
|
||||
- 出库单明细发生变化后,自动重新统计并回填 `shipmentCategory1`
|
||||
- `WaveRule.orderStructure` 已删除,波次规则当前按 `wave_rule.waveType` 与 `shipment_header.shipmentCategory1` 编码做基础匹配
|
||||
- 现阶段按代码内已有的四类结构值落地,且 `SSSQ` 与 `Same SKU Same Qty` 视为同一逻辑,保持和既有波次类型一致
|
||||
|
||||
### 3.4 工作站集波
|
||||
|
||||
工作站需要支持:
|
||||
|
||||
- 按用户权限过滤可选订单类型
|
||||
- 按订单类型先命中 wave rule,再按 rule 条件筛单集波
|
||||
- 按工作站槽口绑定的 wave rule 集波
|
||||
- 若槽口未绑定 wave rule,则按全量规则优先级匹单
|
||||
|
||||
### 3.4.1 按用户权限过滤可选订单类型
|
||||
|
||||
这里的“可选订单类型”指的是前端/接口层可让用户选择的 `shipmentType`,不是波次执行后的结果集。权限控制要尽量前置,避免把未授权的订单类型传进后续波次匹配流程。
|
||||
|
||||
当前设计口径如下:
|
||||
|
||||
- 参考 `preference_user_right` 的关系模型,单独新增一张波次订单类型权限表来维护数据,不再复用旧表。
|
||||
- 建议新表名为 `shipment_type_user_right`,按“订单类型 + 用户”维度保存授权关系,字段语义可以参考 `preference_user_right`,但表名和业务语义要更专用,避免和首选项权限混淆。
|
||||
- 新表字段建议为 `shipmentTypeId`、`userCode`、`created`、`createdBy`,其中 `shipmentTypeId` 对应 `config_detail.id`,`userCode` 对应当前用户,唯一约束建议按 `shipmentTypeId + userCode` 控制。
|
||||
- 新表中的订单类型值对应出库类型字典主键,来源统一按系统内 `SHIPMENT_TYPE` 配置字典取值,也就是和 `shipment_header.shipmentType` 对应的那套出库类型字典。
|
||||
- `userCode` 对应当前登录用户,过滤结果只展示该用户已授权的订单类型。
|
||||
- 用户没有对应授权记录时,默认不展示该订单类型,不做“全量兜底放开”。
|
||||
- 前端下拉或多选控件先按权限过滤可选项,再把过滤后的 `shipmentType` 传给波次匹配接口。
|
||||
- 后端进入 `WaveRuleMatchService` 之前应当已经完成权限过滤;该服务只负责按已选 `shipmentType` 做规则和格口候选匹配,不再重复做用户权限判断。
|
||||
- 权限维护侧可以参考现有“首选项权限”页面交互,但底层读写的是新建的波次订单类型权限表。
|
||||
|
||||
建议的接口链路如下:
|
||||
|
||||
1. 前端进入集波或波次规则配置页面时,先获取当前用户可见的出库类型列表。
|
||||
2. 服务端根据当前用户查询 `shipment_type_user_right` 表,取出已授权的订单类型主键。
|
||||
3. 将命中的订单类型主键映射回 `SHIPMENT_TYPE` 字典,返回可选 `shipmentType` 列表。
|
||||
4. 用户只能在这个列表里选择订单类型,然后再进入后续波次规则匹配。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- `WaveRuleMatchService` 已拆分为 `workstationId + 出库类型` 的主入口,旧的工作台编码入口保留兼容。
|
||||
- 该入口当前已按规则逐条查单并返回格口分配结果,后续仍需补齐更完整的字段匹配和执行衔接。
|
||||
|
||||
### 3.5 抓单、补单、踢单
|
||||
|
||||
需要实现三类执行动作:
|
||||
|
||||
- 抓单:按规则和优先级从订单池取单
|
||||
- 补单:在波次未满时补齐订单
|
||||
- 踢单:库存不足或上游校验失败时剔除订单
|
||||
- 轮询补单:在波次创建后按固定间隔回查订单池,持续补入仍然满足规则且未满载的订单,直到达到补单上限或等待窗口结束
|
||||
|
||||
### 3.6 单品单件特殊流程
|
||||
|
||||
单品单件 `SSSQ` 场景需要额外支持:
|
||||
|
||||
- 动态加单
|
||||
- 槽口封箱后换箱换波
|
||||
- 补单和踢单解耦
|
||||
- 尽量保持槽口满载
|
||||
|
||||
### 3.7 上游接口联动
|
||||
|
||||
需要补齐与上游的接口逻辑,包括:
|
||||
|
||||
- 申请波次号段
|
||||
- 校验波次是否允许合波
|
||||
- 踢单时回调撤单
|
||||
- 初始化 wave rule
|
||||
|
||||
### 3.8 分拨墙与槽口绑定
|
||||
|
||||
需要扩展分拨墙格口与 wave rule 的绑定能力:
|
||||
|
||||
- `wcs_sorting_wall_cell` 增加 `waveRule`
|
||||
- 支持多规则绑定,多个规则用逗号分隔
|
||||
- 支持界面多选下拉更新,取值来自 `wave_rule` 表
|
||||
|
||||
### 3.9 号段申请与上游合波校验
|
||||
|
||||
集波完成后,系统需要从 `shopee_wave` 表里取一个与当前出库单类型一致的 `waveType` 号段,向上游请求校验这批单据是否允许集在一波中。
|
||||
|
||||
当前需求口径如下:
|
||||
|
||||
- 从 `shopee_wave` 中选择 `waveType` 与出库单类型一致的波次号段。
|
||||
- 以该波次号段作为本次集波和上游校验的唯一波次标识。
|
||||
- 调用上游接口,确认当前候选单是否允许合波。
|
||||
- 如果上游返回不允许集在一起的订单,则该批单据不能直接成波。
|
||||
- 若当前批次单量少于一波最大订单数,不在这里强行补单重试,而是交给后面的轮询补单逻辑处理。
|
||||
- 补单逻辑要和各流程解耦,推荐在工作站开始作业后再补单,避免把上游合波校验和补单耦合到一起。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 上游合波校验接口还需要后续梳理接口契约后再落实现。
|
||||
- 这一节先把业务口径写清楚,补单动作统一放到后文轮询补单逻辑中维护。
|
||||
|
||||
### 3.10 格口分配逻辑
|
||||
|
||||
这里的“格口分配”不是给格口动态生成一条规则,而是把当前工作站下可执行的格口和对应 wave rule 组装成可直接消费的分配结果,供后续流程继续决策。
|
||||
|
||||
当前理解和代码侧约束如下:
|
||||
|
||||
- 先按工作站查询可用分播墙,再按分播墙查询格口。
|
||||
- 只保留启用状态且使用状态为 `IDLE` 的格口。
|
||||
- `waveRule` 是格口自身的绑定约束,表示该格口能接收的规则范围,不是运行时临时分配出来的结果。
|
||||
- `currentWaveRule` 是格口当前正在使用的规则字段,用来记录本次实际分配到的 `waveRule`,便于补单和执行衔接。
|
||||
- `shopeeWaveCode` 记录的是格口和 Shopee 波次号段的关联,不承担规则分配职责。
|
||||
- 这里不反查格口当前绑定的出库单,也不在本层做出库单候选筛选。
|
||||
- 当前代码会先按仓库和出库类型查启用波次规则,再按规则逐条查单、查格口,形成“格口 + 命中规则 + 可用出库单”的分配结果。
|
||||
- 如果格口配置了多个 `waveRule`,按逗号、中文逗号或分号拆分后做匹配,命中的规则优先回填到返回结果里。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- `WaveRuleMatchService` 已实现分配入口:
|
||||
- `findBestMatchedRuleByWorkStationAndOutboundType(String warehouseCode, String workStation, String shipmentType)`
|
||||
- `findBestMatchedRuleByWorkStationAndOutboundType(Long workstationId, String shipmentType)`
|
||||
- 工作站控制器已暴露同名接口,可直接通过 `wms/automation/wcsWorkStation/findBestMatchedRuleByWorkStationAndOutboundType` 调用该服务。
|
||||
- 服务内部先查启用中的波次规则,再按规则逐条查可用出库单和可用格口,最终返回 `ResponseMessage` 包装的分配结果。
|
||||
- `assignCellNumbers` 已改成单规则处理,当前会先查出库单,再查格口,并按格口顺序回填命中的订单候选。
|
||||
- 返回结果中每个格口会带上 `matchedRule`、`availableShipments`,并保留 `sortingWallId`、`sortingWallCode`、`workStationId`、`col`、`tier`、`shopeeWaveCode`、`currentWaveRule` 等基础字段。
|
||||
- 当前已经接入基础出库单查询、排序和 `WAVE_RULE_FIELD_MATCHING` 字典基础匹配;高级字段语义仍待补齐。
|
||||
|
||||
### 3.11 `maxShipments` 逻辑
|
||||
|
||||
`maxShipments` 需要拆成两层理解,不能混成一个字段口径:
|
||||
|
||||
- `wave_master.maxShipments`:波次内部表字段,只用于波次创建阶段的截单控制,不参与本节可用出库单查找逻辑。
|
||||
- 波次创建时,会先按 `shipmentFilterCode` 对出库单做候选筛选。
|
||||
- 然后再按 `maxShipments` 截断候选单量。
|
||||
- 如果 `maxShipments > 0`,则按该值限制单次创建波次时可取出的最大出库单数量。
|
||||
- 如果 `maxShipments <= 0`,当前实现默认最多取 `100` 单。
|
||||
- 候选单量最终仍需满足 `minShipments`,否则本次不创建波次。
|
||||
- `wave_rule.maxShipments`:规则级单次抓单上限。
|
||||
- 当前已在规则表和配置页中保留。
|
||||
- 规则匹配链路已开始接入,当前查单逻辑会消费该字段作为单次抓单上限。
|
||||
- 后续如需调整上限口径,只修改规则层,不要和其他内部表字段混用。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 波次主流程在创建阶段会读取 `wave_master.maxShipments`,但这里的可用出库单查找逻辑不直接依赖它。
|
||||
- `wave_rule.maxShipments` 当前已在 `findAvailableShipments` 中消费,作为当前规则的单次抓单上限。
|
||||
- 文档中出现 `maxShipments` 时,必须注明它属于哪一层,避免歧义。
|
||||
|
||||
### 3.12 可用出库单查找逻辑
|
||||
|
||||
格口候选和出库单候选是两条独立链路,不能把“查格口”当成“查单”。
|
||||
|
||||
当前需要补齐的可用出库单查找逻辑如下:
|
||||
|
||||
- 先从出库单池里查候选单,再判断是否满足当前波次规则。
|
||||
- 候选单要同时满足仓库、出库类型、订单结构、状态、锁定状态和规则字段匹配条件。
|
||||
- 当前代码已接入仓库、出库类型、`shipmentCategory1`、在池状态、锁定状态、`wave_rule.maxShipments` 和 `WAVE_RULE_FIELD_MATCHING` 字典字段匹配。
|
||||
- 规则字段匹配重点包括:
|
||||
- `channel_id`
|
||||
- `fulfillment_chain_id`
|
||||
- `order_structure`
|
||||
- `order_size` / `max_order_size`
|
||||
- `sku_size_type`
|
||||
- `category_level_1_id`
|
||||
- `shop_group`
|
||||
- `shop_id`
|
||||
- `urgent_flag`
|
||||
- `outer_packaging`
|
||||
- `delivery_region`
|
||||
- `is_fragile`
|
||||
- `is_liquid`
|
||||
- `is_high_value`
|
||||
- `with_battery`
|
||||
- `is_danger`
|
||||
- `max SKU Pieces Per Order`
|
||||
- `Mix Mode Max SKU Pieces Filter`
|
||||
- 多值字段默认支持按“包含”筛选;需要排除或仅保留某些值时,按字段配置约定转换成 `include` / `exclude` / `only` 口径。
|
||||
- `order_structure` 仍以 `shipmentCategory1` 为实际落字段做匹配,`SSSQ` 与 `Same SKU Same Qty` 视为同一逻辑。
|
||||
- `wave_master` 是内部表,不参与这里的可用出库单查找逻辑。
|
||||
- 规则层的 `wave_rule.maxShipments` 已在 `WaveRuleMatchService#findAvailableShipments` 中作为当前规则的单次抓单上限使用。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 这条“可用出库单查找”逻辑已经开始落到 `WaveRuleMatchService#findAvailableShipments`。
|
||||
- `WaveRuleMatchService` 现在已同时负责规则遍历、订单池基础查单和格口分配,但还没有覆盖所有字段匹配条件。
|
||||
- 后续如果要进一步细化为“规则命中后再查单”,应继续在当前服务或独立查询服务里补齐,不要和格口状态、任务回写混写。
|
||||
|
||||
### 3.13 出库单分配后的处理
|
||||
|
||||
出库单分配不是最终结果,而是进入波次执行前的准备阶段。
|
||||
|
||||
当前需要把分配后的动作单独拆开维护,避免只做“查到单”却没有后续状态闭环。
|
||||
|
||||
分配成功后,建议按以下顺序处理:
|
||||
|
||||
- 固化波次和规则关联,保证本次分配对应的 `wave_rule`、波次号段和业务单据能串起来。
|
||||
- 回写出库单的波次关联状态,例如 `shopeeWave`、`kickOutWave` 等字段,防止同一单再次被其他波次重复占用。
|
||||
- 回写工作站任务头的波次信息,例如 `shopeeWave`、`waveRule`,让执行层知道当前任务属于哪一条波次链路。
|
||||
- 同步分拨墙/格口占用状态,并把当前正在使用的规则写入 `wcs_sorting_wall_cell.currentWaveRule`,确保补单和执行层能识别当前槽口实际使用的规则。
|
||||
- 触发后续执行动作,包括拣货、集波、补单和必要的执行校验。
|
||||
|
||||
如果分配后发现库存不足、规则冲突、上游校验失败或并发占用失败,则需要进入踢单或回流流程:
|
||||
|
||||
- 已分配单据从当前波次中移除。
|
||||
- 恢复单据的可分配状态,重新回到候选池。
|
||||
- 记录失败原因,供后续重试或人工排查。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 当前文档层面先把“分配后动作”拆出来,后续再按模块补实现。
|
||||
- 分配后的状态回写和执行联动,不应混在格口候选或出库单查找逻辑里。
|
||||
|
||||
### 3.14 集波后自动运行波次
|
||||
|
||||
集波完成后,系统需要自动进入波次运行阶段,而不是停留在“已分配未执行”的中间状态。
|
||||
|
||||
当前流程建议按以下顺序执行:
|
||||
|
||||
- 先基于 `wave_rule` 对出库单十几个规则属性做完全匹配,确认当前波次可运行。
|
||||
- 再执行库存最优分配逻辑:
|
||||
- 优先先到期先出,保证先进先出。
|
||||
- 其次按工作站点位与库存点位半径最小的库存优先。
|
||||
- 同半径内,低层货位优先。
|
||||
- 运行成功后,回写波次和任务关联字段:
|
||||
- 将 `shopee_wave` 的波次号段绑定到拣货任务头 `shopeeWave` 字段。
|
||||
- 同时绑定到出库单头 `shopeeWave` 字段。
|
||||
- 将当前 `waveRule` 记录到 `wave` 表的 `waveRule` 字段。
|
||||
- 同步记录到拣货任务头 `waveRule` 字段,供拣货执行衔接使用。
|
||||
- 将 `shopee_wave.status` 更新为 `200`,表示使用中。
|
||||
- 如果运行过程中发现库存不足的单据,直接踢单:
|
||||
- 调用上游撤单接口,通知上游本次集波剔除的单号。
|
||||
- 该类库存不足踢单也要进入后续轮询补单逻辑,不直接结束整条波次链路。
|
||||
- 运行成功后,波次进入执行态,后续继续衔接拣货、补单、踢单和执行校验。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- `WaveRuleMatchService#addShipmentsToInternalWave` 当前已在批量加入内部波次后调用 `WaveService#run`。
|
||||
- `WaveService#run` 是异步提交队列消息,`WaveRuleMatchService` 不解析同步踢单结果。
|
||||
- 库存不足踢单由 `wms-wave` 回池链路处理,回池时清空 `shipment_header.shopeeWave/waveRule`,不记录 `kickOutWave`。
|
||||
- 库存不足踢单后的上游撤单接口仍待接入,补单由后续轮询按格口缺口继续处理。
|
||||
|
||||
### 3.15 上墙优先级与字段匹配
|
||||
|
||||
波次上墙和抓单时,优先级和字段匹配需要按照统一口径执行,不能把“先匹规则”写成“先按数量抓单”。
|
||||
|
||||
当前需求口径如下:
|
||||
|
||||
- 先看 `wave_rule` 表的优先级字段 `wavePriority`,数字越大优先级越高。
|
||||
- 按 `wavePriority` 从高到低排序,优先抓取满足 `wave_rule` 的订单。
|
||||
- 抓单时同时参考 `wave_rule.maxShipments`,按规则设定的最大订单数进行截断。
|
||||
- 如果高优先级 `wave_rule` 的订单池暂时不足 `maxShipments`,也要优先匹配该高优先级规则下能拿到的单,不因为数量不满就降级到低优先级规则。
|
||||
- 规则命中的订单池内部,还要按订单下发优先级继续排序:
|
||||
- 先看 `shipment_header.priority`,数字越大优先级越高。
|
||||
- 同一优先级下,先看 `shipment_header.cutOffTime`,按时间到分钟维度越早越优先。
|
||||
- 再看 `shipment_header.purchaseTime`,按时间到小时维度越早越优先。
|
||||
- 最后看 `shipment_header.orderTime`,按订单创建时间越早越优先。
|
||||
- 抓单前需要先做字段匹配,只有 `wave_rule` 字段与出库单字段匹配上的单子,才进入后续抓单优先级判断。
|
||||
- 命中规则后,再绑定该 `wave_rule` 对应的分拣墙槽口,槽口绑定关系优先跟随规则而不是跟随订单数量变化。
|
||||
- 字段匹配规则统一走数据字典 `WAVE_RULE_FIELD_MATCHING`,用于声明:
|
||||
- 出库单字段
|
||||
- `wave_rule` 表字段
|
||||
- 匹配条件类型,例如 `包含`、`等于`
|
||||
- 对应的运算符口径,例如 `in`、`=`
|
||||
|
||||
字段匹配的执行含义:
|
||||
|
||||
- 先按 `WAVE_RULE_FIELD_MATCHING` 逐项判断出库单是否满足规则字段。
|
||||
- 匹配上的单子,再进入优先级排序和抓单数量控制。
|
||||
- 订单下发优先级只在同一规则命中的候选单之间生效,不改变 `wavePriority` 的规则排序结果。
|
||||
- 不同字段可以有不同匹配条件,不要把所有字段强制当成同一种比较方式。
|
||||
- `wave_rule.maxShipments` 只控制当前规则最多抓多少单,当前已在可用出库单查询中作为 `limit` 使用。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 当前代码已按 `wavePriority` 做规则排序,并按 `shipment_header.priority`、`cutOffTime`、`purchaseTime`、`orderTime` 做同规则内候选单排序。
|
||||
- `WaveRuleMatchService#findAvailableShipments` 已接入 `WAVE_RULE_FIELD_MATCHING`,按 `identifier` 读取实际 `shipment_header` 字段,按 `value1` 读取 `wave_rule` 字段,按 `value2` 执行 `IN`、`=` 或 `LE` 匹配。
|
||||
- `WAVE_RULE_FIELD_MATCHING` 已作为统一数据字典维护,当前无同名默认映射;未配置有效 `identifier/value1` 或不在白名单内的配置会被忽略。
|
||||
|
||||
### 3.16 槽口绑定与拣货衔接
|
||||
|
||||
集波后,除了按 `waveRule` 选出可用格口候选外,还需要把绑定结果和拣货执行设计衔接起来。
|
||||
|
||||
当前需求口径如下:
|
||||
|
||||
- 集波后绑定对应 `wcs_sorting_wall_cell.waveRule` 设定相同规则的槽口。
|
||||
- 绑定的槽口需要记录在任务表或波次表中,作为拣货执行衔接依据。
|
||||
- 绑定记录不是重新生成规则,而是把当前波次命中的槽口固化下来,供后续拣货执行使用。
|
||||
- `wcs_sorting_wall_cell` 里的 `waveRule` 负责表达槽口可接收的规则范围。
|
||||
- `shopeeWave`、`waveRule` 等字段负责把波次、任务和槽口串起来,避免执行阶段再重新推导。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 现有 `wcs_sorting_wall_cell` 已具备 `waveRule`、`currentWaveRule` 和 `shopeeWaveCode` 这类基础关联字段。
|
||||
- 后续如果需要更强的执行衔接能力,可以在任务表或波次表补充槽口记录字段,但文档口径先统一为“绑定结果需要可落库”。
|
||||
- 这一节和上墙优先级不是同一件事,上墙优先级负责“选哪条规则、抓哪些单”,槽口绑定负责“这些单最终落到哪个执行槽口”。
|
||||
|
||||
### 3.17 单品单件动态加单与换箱换波
|
||||
|
||||
`SSSQ` 单品单件场景需要支持波次动态加单和踢单,因为这类货品体积不固定,槽口要求是“尽量放满为止”。
|
||||
|
||||
当前需求口径如下:
|
||||
|
||||
- 仅 `SSSQ` 场景使用单独的动态加单阈值参数 `low_threshold`。
|
||||
- `low_threshold` 用于在槽口未放满时触发轮询补单。
|
||||
- 当前代码已新增 `WAVE/low_threshold` 系统参数,默认值为 `0`;当格口已有 `shopeeWaveCode` 且当前 Shopee 波次已绑定出库单量低于该阈值时,允许继续补单,达到或超过阈值时跳过该格口补单。
|
||||
- 计划任务形式的统一入口 `pollReplenishment/pollReplenishmentOnce` 已落地,复用 `WaveRuleMatchService#replenishCell` 处理 `low_threshold` 和已有 Shopee 波次格口的补单。
|
||||
- 如果按当前波次分配后,例如 30 单一波只分到了 27 单,但槽口还没放满,则需要继续加单。
|
||||
- 如果槽口已经放满,则先封箱,再进入换波流程。
|
||||
- 未分拣的单据需要按踢单逻辑重新回到订单池。
|
||||
|
||||
换箱换波的处理口径如下:
|
||||
|
||||
- 当 `SSSQ` 波次槽口已满但当前波次还没跑完时,剩余订单需要重新取一个与单据类型一致的 `shopee_wave` 波次号段。
|
||||
- 这个场景走 `flow pick` 的换箱接口,不是上文 1.7 的上游合波校验接口。
|
||||
- 上游校验通过后:
|
||||
- 将剩余订单的拣货任务头 `shopeeWave` 更新为新波次号段。
|
||||
- 同时更新出库单头 `shopeeWave`。
|
||||
- 同步更新 `shopee_wave.status` 为 `200` 使用中。
|
||||
- 因为剩余订单数量通常不足规则最大订单数,所以仍要继续走轮询补单逻辑。
|
||||
- 上游校验不通过时:
|
||||
- 对订单执行拦截取消出库,恢复到正常订单池逻辑。
|
||||
- 取消对应任务下发。
|
||||
- 同时给 AGV 下发取消回库指令。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 这一节仅针对 `SSSQ` 单品单件场景。
|
||||
- 轮询补单、换箱换波、踢单和 AGV 取消回库要保持解耦,但共享同一套候选回流思想。
|
||||
- 当前 `low_threshold` 已限定只影响 `SSSQ` 单品单件 wave rule,不扩散到其他 wave rule。
|
||||
- 当前实现以 `wave_rule.maxShipments` 作为满槽触发阈值;满槽后查询当前工作站、旧 Shopee 波次、当前 `waveRule` 下未完成任务订单,重新获取同单据类型 Shopee 波次号段,并批量回写任务头、出库单头和格口 `shopeeWaveCode`。
|
||||
- 当前通过可选 `essFlowPickService.sealBox/changeBoxWave` 承接 Flow Pick 真实接口;接口未接入时记录系统处理日志并执行 WES 本地状态闭环。
|
||||
- 换波失败时不会删除 `shopee_wave` 数据;新号段未被引用时仅回退状态为未使用。恢复订单池、取消任务下发、AGV 取消回库仍等待真实接口联调。
|
||||
|
||||
### 3.18 轮询补单逻辑
|
||||
|
||||
轮询补单由计划任务持续扫描,不和集波主流程、上游合波校验、换箱换波强耦合。
|
||||
|
||||
#### 3.18.1 `SSSQ` 单品单件轮询补单
|
||||
|
||||
当前口径如下:
|
||||
|
||||
- 当工作站对应单品单件 `waveRule` 的槽口未完成订单数低于系统参数 `low_threshold` 时,触发补单。
|
||||
- 补单时,拿工作站对应订单类型以及该槽口的 `waveRule` 去订单池抓单。
|
||||
- 抓单优先级与上文 `3.15` 中一致。
|
||||
- 一次性补 `wave_rule.maxShipments` 指定的最大订单数,实际接入后由补单服务消费该字段。
|
||||
- 抓到的单据用该槽口的 `shopeeWave + 单号` 请求上游接口验证是否可以继续合波。
|
||||
- 上游校验 `ok` 时,WES 自动加入波次运行,与上文 `3.14` 逻辑一致。
|
||||
- 上游校验 `不 ok` 时,重新在订单池继续抓单再请求上游校验。
|
||||
- 已抓取但不符合的单子,需要过滤出当前波次号外。
|
||||
- 单子可能被多个波次号请求上游校验失败,技术实现时需要支持多次踢单记录,`kickOutWave` 可用逗号分隔保存。
|
||||
|
||||
#### 3.18.2 非 `SSSQ` 场景轮询补单
|
||||
|
||||
当前口径如下:
|
||||
|
||||
- 轮询扫描正在作业的各工作站和各槽口。
|
||||
- 统计当前槽口绑定的 wave 订单数是否满足 `wave_rule.maxShipments`,该字段当前先按配置口径记录。
|
||||
- 统计范围包含该槽口当前波次进行中、已完成、未开始的单子。
|
||||
- 将汇总结果与 `wave_rule.maxShipments` 比较,若缺少 `X` 单,则去订单池抓 `X` 单。
|
||||
- 抓单时仍按上文 `3.15` 的抓单优先级执行。
|
||||
- 抓到的单据按该槽口的 `shopeeWave + 单号` 请求上游接口验证是否可以继续合波。
|
||||
- 上游校验 `ok` 时,WES 自动加入波次运行,与上文 `3.14` 逻辑一致。
|
||||
- 上游校验 `不 ok` 时,重新在订单池继续抓单再请求上游校验。
|
||||
- 已抓取不符合的单子需要从当前波次号外过滤掉。
|
||||
- 被 ESS 合波校验拒绝的单子,需要在 `shipment_header.kickOutWave` 里记录 Shopee wave 号,多个 wave 号用逗号隔开,后续该波次号再次抓单时过滤;库存不足踢单不记录 `kickOutWave`。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 当前已落地计划任务形式的轮询补单入口 `pollReplenishment/pollReplenishmentOnce`,并复用单格口补单方法 `WaveRuleMatchService#replenishCell`。
|
||||
- 当前入口复用 `findPickingWorkstations`、`findReplenishmentCells`,用于扫描正在作业的工作站和已绑定 Shopee 波次的 `USED` 格口,并逐格口触发补单。
|
||||
- 当前格口分配链路和轮询补单链路均具备“ESS 校验失败写 `kickOutWave`、再次抓单时过滤同 Shopee 波次”的基础能力,并已支持常见失败订单 ID、单号和 Map 结构解析;真实 ESS 响应契约仍待接口联调确认。
|
||||
- `SSSQ` 与非 `SSSQ` 场景的补单策略不同,但都要保持“先抓单、再上游校验、失败过滤、重新抓单”的闭环。
|
||||
|
||||
### 3.19 推拣货任务与推出库单的区别
|
||||
|
||||
`Shopee` 推送过来的单据分两类,后续流程不能混用:
|
||||
|
||||
#### 3.19.1 推拣货任务
|
||||
|
||||
推拣货任务是“命中人工 + 自动化区”的单子,特点如下:
|
||||
|
||||
- 推送时会同步推上游波次号段,不需要上文的取号逻辑。
|
||||
- WES 按推送的拣货任务建立出库单。
|
||||
- 再按上文的集波逻辑,结合工作站、出库类型和 `wave_rule` 抓单。
|
||||
- 这类订单按“1 单跑 1 个波次”处理,且后续无需补单。
|
||||
- 这类订单区分标识待梳理接口后提供。
|
||||
- 这类单子统一按“1 拣货单 1 波次 1 槽口”设计,不走轮询补单逻辑。
|
||||
|
||||
#### 3.19.2 推出库单
|
||||
|
||||
推出库单是“纯命中自动化区”的单子,特点如下:
|
||||
|
||||
- 这类单子不走推拣货任务的特殊流程。
|
||||
- 按上文的正常集波流程处理。
|
||||
- 按波次号段申请、上游合波校验、槽口绑定、轮询补单等标准链路执行。
|
||||
- 这类单据仍需遵守 `wave_rule`、`wavePriority`、`maxShipments`、`low_threshold` 等通用规则。
|
||||
|
||||
当前代码状态说明:
|
||||
|
||||
- 推拣货任务和推出库单需要在入口层就分开,不要进入同一套补单或取号逻辑。
|
||||
- 推拣货任务的区分标识目前还待接口梳理后补充。
|
||||
- 后续实现时,推拣货任务以“一单一波一槽口”为核心约束,推出库单继续走标准集波链路。
|
||||
|
||||
## 四、模块映射
|
||||
|
||||
### 4.1 `wms-wave`
|
||||
|
||||
建议作为波次规则和波次号段的主实现模块,承接:
|
||||
|
||||
- `wave_rule` 配置
|
||||
- `shopee_wave` 号段管理
|
||||
- wave rule 优先级
|
||||
- 波次最大订单数
|
||||
- 波次运行与状态流转
|
||||
|
||||
已落地的代码改动:
|
||||
|
||||
- 新增 `WaveRule` 实体和 `WaveRuleService`
|
||||
- 新增 `ShopeeWave` 实体和 `ShopeeWaveService`
|
||||
- `Wave` 新增 `waveRule`
|
||||
- 新增 Flyway 脚本创建 `wave_rule` 与 `shopee_wave`
|
||||
|
||||
### 4.2 `wms-shipping`
|
||||
|
||||
承接出库单和订单头字段变更,包括:
|
||||
|
||||
- 出库单类型
|
||||
- `shipment_header.priority`
|
||||
- `shipment_header.cutOffTime`
|
||||
- `shipment_header.purchaseTime`
|
||||
- `shipment_header.orderTime`
|
||||
- `shipmentCategory1`
|
||||
- `kickOutWave`
|
||||
- `shopeeWave`
|
||||
|
||||
已落地的代码改动:
|
||||
|
||||
- `ShipmentHeader` 新增 `cutOffTime`、`purchaseTime`、`orderTime`
|
||||
- `ShipmentHeader` 新增 `shopeeWave`、`kickOutWave`
|
||||
- `shipment_header`、`archive_shipment_header`、`deleted_shipment_header` 的 table 配置同步补齐
|
||||
- Flyway 脚本同步补齐三张表字段
|
||||
|
||||
### 4.3 `wms-task`
|
||||
|
||||
承接拣货任务、任务头字段和集波后的执行联动,包括:
|
||||
|
||||
- 拣货任务头 `shopeeWave`
|
||||
- 拣货任务头 `waveRule`
|
||||
- 单品单件动态加单
|
||||
- 任务和波次执行衔接
|
||||
|
||||
已落地的代码改动:
|
||||
|
||||
- `WcsWorkStationPickTaskHeader` 新增 `shopeeWave`、`waveRule`
|
||||
- `wcs_work_station_pick_task_header` table 配置同步补齐
|
||||
|
||||
### 4.4 `wms-core-wave`
|
||||
|
||||
承接波次相关核心算法,比如:
|
||||
|
||||
- wave rule 匹单逻辑
|
||||
- 优先级排序
|
||||
- 订单池筛选
|
||||
- 波次运行前后的核心判定
|
||||
- 当前波次创建顺序已经调整为“先查 `wave_rule`,再按规则条件查出库单”
|
||||
|
||||
### 4.5 `wms-core-task`
|
||||
|
||||
承接任务执行相关的核心能力,包括:
|
||||
|
||||
- 任务生成和执行约束
|
||||
- 拣货和波次联动
|
||||
- 任务优先级衔接
|
||||
|
||||
### 4.6 `wms-common`
|
||||
|
||||
承接共用基础能力,包括:
|
||||
|
||||
- 数据字典 `WAVE_RULE_FIELD_MATCHING`
|
||||
- 通用枚举
|
||||
- 共享字段定义
|
||||
- 通用规则封装
|
||||
|
||||
### 4.7 `wms-automation`
|
||||
|
||||
承接自动化区和 AGV 联动能力,包括:
|
||||
|
||||
- 任务取消
|
||||
- 取消回库指令
|
||||
- 自动化区单据的执行边界
|
||||
|
||||
已落地的代码改动:
|
||||
|
||||
- `WcsSortingWallCell` 新增 `waveRule`
|
||||
- `WcsSortingWallCell` 新增 `currentWaveRule`
|
||||
- `WcsSortingWallCell` 现已支持保存 `shopeeWaveCode`
|
||||
- `UpdateSortingWallCellCmd` 新增 `waveRule`
|
||||
- `UpdateSortingWallCellCmd` 新增 `currentWaveRule`
|
||||
- `WcsSortingWallCellService` 已支持更新 `waveRule`
|
||||
- `WcsSortingWallCellService` 已支持更新 `currentWaveRule`
|
||||
- `wcs_sorting_wall_cell` table 配置和 Flyway 脚本已同步补齐
|
||||
|
||||
### 4.8 `wms-inventory`
|
||||
|
||||
承接库存相关判定和库存不足场景依赖:
|
||||
|
||||
- 库存不足踢单
|
||||
- 可用库存优先分配
|
||||
- 库存点位和工作站半径联动
|
||||
|
||||
### 4.9 配置模块
|
||||
|
||||
建议同步更新以下配置模块:
|
||||
|
||||
- `wms-wave-config`
|
||||
- `wms-shipping-config`
|
||||
- `wms-task-config`
|
||||
- `wms-inventory-config`
|
||||
|
||||
用于承接规则枚举、静态配置和界面配置项。
|
||||
|
||||
## 五、实施计划
|
||||
|
||||
### 第 1 步:补规则和表结构
|
||||
|
||||
先完成以下内容:
|
||||
|
||||
- `wave_rule` 表设计和字段补齐
|
||||
- `shopee_wave` 表设计和字段补齐
|
||||
- 分拨墙槽口表 `wcs_sorting_wall_cell` 增加 `waveRule`
|
||||
- 出库单头和任务头字段补齐
|
||||
|
||||
这一阶段的目标是把所有需求依赖的字段和持久化基础先补齐。
|
||||
|
||||
状态:已完成。
|
||||
|
||||
### 第 2 步:补基础规则引擎
|
||||
|
||||
再完成:
|
||||
|
||||
- wave rule 字段匹配
|
||||
- 波次优先级排序
|
||||
- 订单类型识别
|
||||
- 出库单筛选规则
|
||||
- 分拨墙槽口 wave rule 匹配
|
||||
|
||||
这一阶段的目标是让系统能够判断“哪些单能进哪条规则”。
|
||||
|
||||
状态:基础能力已落地,高级语义待实现。
|
||||
当前已能按规则逐条查单并返回格口分配结果,已接入基础排序、`maxShipments` 截断、`waveType/shipmentCategory1` 匹配和 `WAVE_RULE_FIELD_MATCHING` 字典基础匹配。
|
||||
|
||||
### 第 3 步:补集波主流程
|
||||
|
||||
然后实现:
|
||||
|
||||
- 工作站按订单类型和规则集波
|
||||
- 号段申请
|
||||
- 波次生成
|
||||
- 波次绑定出库单和任务
|
||||
- 集波后自动运行
|
||||
|
||||
备注:
|
||||
|
||||
- 由于完整波次级规则引擎仍在重建阶段,波次主流程仍沿用原有 `shipmentFilterCode` 过滤逻辑。
|
||||
|
||||
这一阶段的目标是跑通主链路。
|
||||
|
||||
状态:基础主链路已落地,接口闭环待实现。
|
||||
当前已具备创建内部波次、批量加入内部波次、异步提交运行、基础字段回写和 ESS 拒单基础解析能力;上游号段申请、真实 ESS 响应契约、库存不足踢单上游撤单和任务头字段完整闭环仍待补齐。
|
||||
|
||||
### 第 4 步:补补单与踢单
|
||||
|
||||
随后实现:
|
||||
|
||||
- 轮询补单
|
||||
- 轮询补单建议拆成以下几层:
|
||||
- 第一层先判断波次是否仍处于允许补单的状态,避免已锁定、已释放、已关闭的波次继续被补。
|
||||
- 第二层按波次规则重新拉取订单池候选单,必须同时满足规则匹配、状态可用、未被其他波次占用。
|
||||
- 第三层按波次剩余容量和订单优先级决定是否补入,补入后同步刷新波次统计和订单池状态。
|
||||
- 第四层若连续若干轮没有新增候选单,则提前结束轮询,避免空转。
|
||||
- 第五层若补单过程中发生库存不足、规则冲突或并发锁失败,应立即停止当前轮询,并保留已成功补入的结果。
|
||||
- 库存不足踢单
|
||||
- 上游校验失败踢单
|
||||
- 失败单据回流订单池
|
||||
|
||||
这一阶段的目标是让系统在异常情况下还能稳定收敛。
|
||||
|
||||
状态:待实现。
|
||||
|
||||
### 第 5 步:补单品单件特殊逻辑
|
||||
|
||||
最后补单品单件特殊流程:
|
||||
|
||||
- 动态加单
|
||||
- 换箱换波
|
||||
- 封箱后的波次切换
|
||||
- 仅对 `SSSQ` 生效的补单/换波策略
|
||||
|
||||
这一阶段的目标是把高频特殊场景单独收口。
|
||||
|
||||
状态:待实现。
|
||||
|
||||
## 六、验证计划
|
||||
|
||||
### 6.1 规则验证
|
||||
|
||||
- 验证 wave rule 字段映射是否正确
|
||||
- 验证规则优先级排序是否正确
|
||||
- 验证多选、包含、等于等匹配条件是否正确
|
||||
|
||||
### 6.2 数据验证
|
||||
|
||||
- 验证 `wave_rule` 表和 `shopee_wave` 表的增删改查
|
||||
- 验证出库单、任务头字段是否能正确落库
|
||||
- 验证分拨墙槽口与 wave rule 的绑定关系
|
||||
|
||||
### 6.3 流程验证
|
||||
|
||||
- 验证集波主流程是否能从订单池成功抓单
|
||||
- 验证补单流程是否能触发
|
||||
- 验证踢单流程是否能正确回流
|
||||
- 验证单品单件换箱换波是否符合预期
|
||||
|
||||
### 6.4 联动验证
|
||||
|
||||
- 验证上游号段申请
|
||||
- 验证上游校验失败时的回退逻辑
|
||||
- 验证自动化区取消回库指令
|
||||
|
||||
### 6.5 当前验证结果
|
||||
|
||||
- 已完成 JSON 表配置静态校验。
|
||||
- 已完成字段名和迁移脚本的人工一致性校对。
|
||||
- 当前环境缺少 `gradlew` 和全局 `gradle`,未执行仓库级编译。
|
||||
|
||||
## 七、风险点
|
||||
|
||||
- wave rule 字段多、匹配条件多,容易出现规则解释不一致。
|
||||
- 单品单件和非单品单件的补单逻辑不同,容易产生分支遗漏。
|
||||
- 上游接口未完全明确时,接口契约和失败处理需要先留好扩展点。
|
||||
- 出库单、任务、波次、槽口四者之间的状态同步需要严格控制。
|
||||
|
||||
## 八、建议落地顺序
|
||||
|
||||
1. 先补表结构和字段。
|
||||
2. 再补规则匹配和基础算法。
|
||||
3. 然后补主集波流程。
|
||||
4. 再补补单、踢单和异常回退。
|
||||
5. 最后补单品单件特殊流程。
|
||||
|
||||
## 九、下一步建议
|
||||
|
||||
- 如果你要,我可以继续把这份计划拆成“按模块的开发任务清单”。
|
||||
- 如果你要,我也可以继续把这份计划细化成“接口级别”的需求拆分文档。
|
||||
@@ -0,0 +1,209 @@
|
||||
␍
|
||||
Shopee WES客户化设计
|
||||
|
||||
文档编号:
|
||||
Shopee_011
|
||||
|
||||
文档内容:
|
||||
AGV分拣出库
|
||||
|
||||
版本:
|
||||
1.0
|
||||
|
||||
项目经理:
|
||||
|
||||
客户经理:
|
||||
|
||||
确认人:
|
||||
|
||||
确认日期:
|
||||
|
||||
修改历史:
|
||||
作者
|
||||
时间
|
||||
版本
|
||||
备注
|
||||
|
||||
张庆辉
|
||||
2026-05-15
|
||||
1.0
|
||||
方案初版
|
||||
|
||||
业务流程
|
||||
主流程
|
||||
流程名称
|
||||
描述
|
||||
应用场景
|
||||
设备类型
|
||||
|
||||
业务描述
|
||||
|
||||
修改范围
|
||||
UI增加AGV分拣出库
|
||||
前提条件
|
||||
N/A
|
||||
新增表/字段
|
||||
AGV分拣首选项
|
||||
agv_preference
|
||||
字段名
|
||||
含义
|
||||
类型
|
||||
长度
|
||||
非空
|
||||
默认值
|
||||
|
||||
id
|
||||
内部号
|
||||
bigint
|
||||
|
||||
Y
|
||||
|
||||
code
|
||||
编码
|
||||
varchar
|
||||
50
|
||||
Y
|
||||
|
||||
name
|
||||
名称
|
||||
varchar
|
||||
50
|
||||
N
|
||||
|
||||
warehouseCode
|
||||
仓库
|
||||
varchar
|
||||
50
|
||||
Y
|
||||
|
||||
initDocType
|
||||
分拣方式
|
||||
varchar
|
||||
500
|
||||
Y
|
||||
固定下拉框选择(批量和按单两种)
|
||||
|
||||
allUsers
|
||||
所有用户
|
||||
int
|
||||
|
||||
N
|
||||
0
|
||||
|
||||
useAsDefault
|
||||
是否默认
|
||||
int
|
||||
|
||||
N
|
||||
0
|
||||
|
||||
参数设置
|
||||
参数
|
||||
取值范围
|
||||
模块
|
||||
描述
|
||||
|
||||
功能设计
|
||||
|
||||
UI
|
||||
一.新增AGV分拣首选项界面
|
||||
界面可以参考包装复合首选项,可以按照人员设置对应权限。
|
||||
|
||||
新增UI界面AGV分拣
|
||||
|
||||
打开界面,选择对应的工作站进行登录;
|
||||
|
||||
扫描工作站后,需要检测当前工作站是否在wcs_work_station表存在。
|
||||
进入管理界面;
|
||||
A点击开始按钮,弹框选择出库单类型。弹框显示的内容为出库单类型,点击单选
|
||||
|
||||
选择后判断工作台的模式currentJobMode=0或者2,则提示成功,并将currentJobMode更新为2; 将选择的出库单类型更新到当前工作台表的tasktype字段。
|
||||
若此工作台的currentJobMode!=0或者2,则提示“此工作台正在进行其他工作,不允许开始”;
|
||||
|
||||
B点击退出,若此工作台的currentJobMode=2,则提示成功,并将currentJobMode更新为0;
|
||||
点击暂停,将接单状态acceptStatus更新为0;图表显示为继续
|
||||
点击继续,将接单状态acceptStatus更新为1;图表显示为暂停
|
||||
|
||||
绑箱:点击绑箱,弹框显示
|
||||
货架号:XXXXXXX
|
||||
周转箱号:XXXXXXX
|
||||
扫描货架号,判断必须在wcs_sorting_wall存在,若不存在,则报错
|
||||
另外wcs_sorting_wall的LPN必须为空为NULL ,否则报错,提醒“当前货架已存在周转箱”
|
||||
扫描周转箱后调用上游WMS的周转箱检查接口,WMS返回成功可用,才可以绑定。将周转箱号更新到wcs_sorting_wall表的LPN。
|
||||
若返回不可用,则提示“当前周转箱不可用”
|
||||
满箱
|
||||
点击满箱,弹框显示
|
||||
货架号:XXXXXXX
|
||||
周转箱号:XXXXXXX
|
||||
扫描货架号,判断必须在wcs_sorting_wall存在,若不存在,则报错
|
||||
另外wcs_sorting_wall的LPN必须为有值,否则报错,提醒“当前货架无箱”
|
||||
扫描周转箱后调用上游WMS的周转箱检查接口,WMS返回成功可用,才可以绑定。将周转箱号更新到wcs_sorting_wall表的LPN。
|
||||
若返回不可用,则提示“当前周转箱不可用”
|
||||
G.封箱:点击封箱,弹框显示
|
||||
货架号:XXXXXXX
|
||||
扫描货架号,判断必须在wcs_sorting_wall存在,若不存在,则报错
|
||||
另外wcs_sorting_wall的sy_status必须=6,任务完成状态。将当前格口Task_ID,lpn清空,sy_status更新=0,还需下发当前格口灭灯指令。(之前下发过亮绿灯指令)
|
||||
G:封箱后面增加缺料按钮
|
||||
点击按钮,弹框进行二次确认,则当前周转箱货品+批次的订单需要重新分配。
|
||||
继续判断当前周转箱是否有其他货品需要分拣,若有则显示下一个货品的分拣信息(注意批量和按单)
|
||||
若当前周转箱无其他货品需要分拣,则下发周转箱回库调度指令
|
||||
同时也生产缺料的盘点单,盘点类型=缺料。盘点单的具体字段见盘点客户化文档
|
||||
|
||||
波次任务分配
|
||||
详情见专属客户化文档
|
||||
3.波次任务分配到分拣墙(计划任务)
|
||||
A.系统用计划任务检测到工作台表存在的currentJobMode=2,acceptStatus=1,status=1的工作台,可能会多个工作台,需要轮询。先找到找到电子标签货架表wcs_sorting_wall,此工作台对应的的货位workStationCode=当前工作台。判断此工作台Task_ID是否有为NULL的货位,若有货位的Task_ID有值,则不下发任务。若存在Task_ID为空或为NULL的货位,则找到符合下面条件的任务。
|
||||
b.波次任务条件:出库单仓库=当前仓库,拣货任务头已释放,任务从货位区域=AGV区域,任务头状态为100,任务头的自定义2字段为空或为null,任务头的自定义1字段(出库任务类型)在电子标签货架表wcs_sorting_wal的cktype类型里包含。(分拣墙的波次任务类型维护多个),而且任务表头的上游波次号自定义4关联上游波次号段表(波次分配客户化确定),上游波次号段表的是否已分配字段自定义1为空为null。
|
||||
|
||||
将任务分配到电子标签货架表wcs_sorting_wal上,将任务表头的上游波次号自定义4更新到Task_ID字段,sy_status更新=2。任务头自定义2更新为当前时间,自定义3更新为电子标签货架货位号。也将上游波次号段表的是否已分配字段自定义1更新=1.
|
||||
|
||||
D、继续执行下一个工作台分配
|
||||
4.下发AGV任务(计划任务)
|
||||
a.(找出库的工作台)工作台表存在的currentJobMode=2,acceptStatus=1,status=1的工作台,可能会多个工作台,需要轮询。工作台对应的分拣墙已经存在执行的任务(Sorting_location表的Task_ID有值,sy_status=2),
|
||||
b. (查询当前为完成的周转箱数量)查询自动化调度表wcs_dispatch_task的状态processStatus是未完成,工作台workStationCode等于当前工作台的数量Y。
|
||||
判断Y是否小于当前工作台workStationCode表ZDagv维护的数量,若小于则继续执行。若大于,则跳过当前工作台,执行下个工作台。
|
||||
C.若小于,则找分拣墙的Task_ID(任务表头的上游波次号自定义4)下的拣货任务的从区域=agv库区,拣货任务头是已释放,拣货明细的从LPN关联周转箱表wcs_container,周转箱表的onHandStatus状态=“10”)的分拣墙分配的拣货任务明细,并按照货品进行排序,找到的周转箱数量最多是workStationCode表ZDagv维护的数量。
|
||||
D.根据周转箱,下发AGV任务,每个周转箱是一个报文。
|
||||
下发到wcs_dispatch_task调度表。
|
||||
|
||||
5.AGV搬运任务完成
|
||||
接口收到AGV完成的搬运回传指令,WMS将调度表的任务完成。
|
||||
|
||||
6.扫描周转箱分拣
|
||||
a电脑扫描枪扫描已经到达工作台的周转箱号,根据周转箱找到分拣墙 下任务对应的此周转箱status=100的任务明细,若不存在,则提示“无此周转箱任务”,
|
||||
b若存在,则电脑分拣界面选择的首选项来判断显示。若首选项initDocType类型是批量。
|
||||
则显示此周转箱第一个货品+批次+库存状态的找到所有分拣墙格口的任务分拣信息。(按照每个货品所有格口任务进行分拣。)
|
||||
若initDocType类型是按单,则显示此周转箱第一个货品+批次+库存状态的找到第一个分拣格口任务的分拣信息。(按照每个货品单个格口任务进行分拣。)
|
||||
|
||||
D.显示内容:左边是当前周转箱的信息,需要根据周转箱表的格口数进行动态显示,格口数存在1,2,4,6,8.当前周转箱分拣货位所在货位格口需要放大蓝色显示。
|
||||
中间显示的是当前分拣的数量,下面是货品的图片,货品名称,货品sku编码(UPC),
|
||||
若
|
||||
|
||||
左边显示的分拣墙的示意图,每个工作台有2组货架,1组是4层*5=20个货架,2组是3层*5=15个货架,共35个货架。显示的内容是工作台wcs_sorting_wall表groupIndex的。若分拣墙货位所在格口需要放大蓝色显示,下面显示对应格口的分拣数量。
|
||||
扫描货品
|
||||
扫描周转箱,显示第一个货品的分拣信息。然后扫描货品SKU编码,盘点当前周转箱货品SKU+批次库存是否冻结,若冻结则弹框提醒”当前货品批次已冻结,需要重新分配”。
|
||||
若点击了确认,则当前周转箱货品+批次的订单需要重新分配。
|
||||
继续判断当前周转箱是否有其他货品需要分拣,若有则显示下一个货品的分拣信息(注意批量和按单)
|
||||
若当前周转箱无其他货品需要分拣,则下发周转箱回库调度指令。
|
||||
|
||||
下发电子标签指令
|
||||
扫描周转箱,显示第一个货品的分拣信息。然后扫描货品SKU编码,当前货品没用冻结。还需判断分拣货架表在wcs_sorting_wall表LPN必须都有值。若无值,则提醒“需要绑定订单箱”
|
||||
若都有值则下发当前周转箱SKU对应分拣墙的电子标签亮红灯。
|
||||
电子标签 id维护在wcs_sorting_wall表的lamp字段。下发成功后将周转箱,货品,批次更新到wcs_sorting_wall表当前货架的fj_lpn,fj_sku,fj_batch字段。并且wcs_sorting_wall表的sy_status更新=4
|
||||
|
||||
G.若货品管控序列号则,扫描SKU后弹框扫描采集序列号。
|
||||
|
||||
任务确认
|
||||
(可参考国电南瑞项目,汤星明技术经理)UI分拣界面需要监测到电子标签拍灯接口,若节课报文返回的分拣墙货位wcs_sorting_wall表的sy_status=4,则是任务确认,根据记录的周转箱,货品,批次进行当前任务的确认。任务确认的时候将当前分拣货架wcs_sorting_wall的订单箱LPN更新到任务确认的任务明细自定义1字段。
|
||||
还要清空当前wcs_sorting_wall货架的fj_lpn,fj_sku,fj_batch字段,sy_status更新=2。
|
||||
界面刷新,若首选项是批量,则显示周转箱下一个货品+批次的所有任务格口的分拣信息,
|
||||
若是按单的首选项,则显示这个货品+批次下一个任务格口的分拣信息,若无其他任务,则找其他货品+批次的分拣信息。
|
||||
若当前周转箱全部货品分拣完成,下发当前周转箱回库。
|
||||
手工确认
|
||||
为防止电子标签出问题,则保留人工手工任务确认。
|
||||
在分拣界面点击右下角的完成指令,是将界面上的周转箱、货品、批次对应的任务格口进行确认。任务确认后,逻辑同上。
|
||||
|
||||
订单分拣完成
|
||||
任务确认的时候,判断wcs_sorting_wall分拣墙格口的任务是否完成,若整个任务分拣完成,则下发当前格口电子标签绿灯。sy_status更新=6.
|
||||
UI分拣界面需要监测到电子标签拍灯接口,若节课报文返回的分拣墙货位wcs_sorting_wall表的sy_status=6,则的封箱。将当前格口Task_ID,lpn清空,sy_status更新=0
|
||||
|
||||
@@ -0,0 +1,527 @@
|
||||
# SHOPEE_011 AGV出库分拣开发计划
|
||||
|
||||
> 依据 `C:/Users/zoe/Downloads/SHOPEE_011_AGV出库分拣(2).docx` 整理。本文档用于维护开发计划和当前完成状态。
|
||||
|
||||
## 1. 目标
|
||||
|
||||
实现 Shopee AGV 出库分拣:工作站登录 AGV 分拣模式后,系统把已释放的 AGV 区域拣货任务分配到分拣墙,按工作站 AGV 并发量下发周转箱搬运任务;周转箱到站后,操作员按批量或按单首选项扫描分拣,通过电子标签或手工确认完成格口任务,支持绑箱、满箱、封箱、缺料重分配和回库调度。
|
||||
|
||||
## 2. 总体模块拆分
|
||||
|
||||
| 阶段 | 模块 | 主要内容 | 状态 |
|
||||
| --- | --- | --- | --- |
|
||||
| P0 | 数据模型与配置 | `agv_preference`、`wcs_sorting_wall` AGV 分拣字段、工作站 AGV 并发量、菜单/字典配置 | 部分完成:`agv_preference` 建表/domain/table JSON/bill JSON 已落地 |
|
||||
| P1 | 工作站 AGV 分拣入口 | 登录工作站、开始/退出/暂停/继续、出库单类型选择 | 部分完成:已存在 `AgvSortingService` 统一服务骨架 |
|
||||
| P1 | 分拣墙箱绑定 | 绑箱、满箱、封箱、缺料按钮 | 待实现 |
|
||||
| P1 | 任务分配计划任务 | 拣货任务分配到分拣墙,绑定上游波次号和分拣墙 | 待实现 |
|
||||
| P1 | AGV 下发计划任务 | 控制工作站未完成 AGV 数量,生成/下发 `wcs_dispatch_task` | 待实现 |
|
||||
| P1 | 扫箱分拣服务 | 扫周转箱、按首选项展示批量/按单分拣信息 | 待实现 |
|
||||
| P1 | 电子标签与确认 | 亮红灯、拍灯确认、手工确认、完成后亮绿灯 | 待实现 |
|
||||
| P2 | 异常闭环 | SKU 批次冻结、缺料重分配、缺料盘点单、周转箱回库 | 待实现 |
|
||||
| P2 | UI | AGV 分拣首选项维护、AGV 分拣工作台页面 | 部分完成:工作站出库菜单已增加 `AGV拣货`,`AGV_PICK.vue` 页面已按参考图绘制 |
|
||||
|
||||
## 2.1 流程图补充口径
|
||||
|
||||
用户补充的两张流程图将 AGV 出库分拣拆成两条入口:
|
||||
|
||||
| 流程 | UI 入口 | 核心差异 | 交付差异 |
|
||||
| --- | --- | --- | --- |
|
||||
| 按单拣货 | 选择“按单拣货” | 订单准备后选择订单类型并点确认,分配任务到工作站;扫 SKU 后按分配货位逐个指引拣货 | 增加“交付”阶段:停止拣货订单、机器人搬运待交付料箱至分播位、人员离开、PTL 绿灯闪烁、PTL 关闭分播口 |
|
||||
| 批量拣货 | 选择“批量拣货” | 订单准备后选择订单类型并点确认,按 SKU/UID 统计数量,PTL 开始拣货对应分配货位 | 无独立交付泳道,完成分配订单后可继续找新的潜在货位或停止分配返回工作站 |
|
||||
|
||||
共同主流程:
|
||||
- Shopee-WMS 向 HAIQ 下发拣货任务,HAIQ 接收任务并创建订单。
|
||||
- HAIQ 预分配库存。
|
||||
- HAIQ UI 登录工作站并选择拣货模式。
|
||||
- 若存在进行中任务,需先换人/结束并清除当前任务,或继续执行可操作员执行的其它任务。
|
||||
- HAIQ 基于订单波次、优先级、释放规则动态生成波次,并将任务分配到工作站。
|
||||
- 生成料箱取用任务并分配给机器人,机器人接收任务。
|
||||
- 拣货任务收集后同步到 WMS 仓储系统。
|
||||
- 操作员绑定订单箱或料箱,系统确认绑定成功后进入扫码拣货。
|
||||
- SKU 扫描后判断 UID 是否受库存管理:受管理则逐件扫描 UID 后计数,不受管理则直接统计 SKU 数量。
|
||||
- HAIQ 根据分配货位指引拣货,PTL 按货位亮灯/分播。
|
||||
- 若需要更换料箱或继续拣货,系统查找新的潜在货位;否则标记本批次/本订单完成。
|
||||
|
||||
计划影响:
|
||||
- `agv_preference.initDocType` 需要明确支持 `SINGLE_ORDER`(按单)和 `BATCH`(批量)两种值。
|
||||
- UI 工作台入口需按模式切换文案、后续按钮和完成逻辑。
|
||||
- 后端查询/确认接口需要带 `pickMode`,不能只依赖默认首选项。
|
||||
- 按单模式需要新增“交付”服务或状态流,批量模式可以先不实现交付泳道。
|
||||
|
||||
## 3. 数据库与领域对象
|
||||
|
||||
### 3.1 新增表 `agv_preference`(部分完成)
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `id` | bigint | 主键 |
|
||||
| `code` | varchar(50) | 编码,必填 |
|
||||
| `name` | varchar(50) | 名称 |
|
||||
| `warehouseCode` | varchar(50) | 仓库,必填 |
|
||||
| `initDocType` | varchar(500) | 分拣方式:`BATCH` 批量、`SINGLE_ORDER` 按单 |
|
||||
| `allUsers` | int | 所有用户可用,默认 0 |
|
||||
| `useAsDefault` | int | 是否默认,默认 0 |
|
||||
|
||||
落地状态:
|
||||
- 已完成:建表 SQL 已合并到 `wes-loghub/src/main/resources/db/migration/mysql/V3_1_2_3__shopee_outbound_wave_create.sql`。
|
||||
- 已完成:领域对象 `wes-loghub/wms-automation/src/main/groovy/com/ittx/wms/automation/domain/hairo/AgvPreference.groovy`。
|
||||
- 已完成:表配置 `wes-loghub/src/main/resources/config/wes/table/agv_preference.json`。
|
||||
- 已完成:单据配置 `wes-loghub/src/main/resources/config/wes/bill/agv_preference.json`。
|
||||
- 已完成:维护页面配置 `wes-loghub/src/main/resources/config/wes/view/ttx.wso.TabbedBill/agv_preference.json`。
|
||||
- 已完成:出库配置菜单 `agv_preference_config` 已挂载到 `wes-loghub/src/main/resources/config/wes/navigator/admin.json`。
|
||||
- 已完成:服务 `wes-loghub/wms-automation/src/main/groovy/com/ittx/wms/automation/service/hairo/AgvPreferenceService.groovy`,承接平台通用 CRUD。
|
||||
|
||||
### 3.2 扩展 `wcs_sorting_wall`
|
||||
|
||||
docx 将分拣墙货架作为 AGV 分拣任务载体,现有 `WcsSortingWall.groovy` 仅有基础字段,需要补齐以下字段:
|
||||
|
||||
| 字段 | 建议字段名 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 周转箱 | `lpn` | 订单箱/周转箱号 |
|
||||
| 当前任务 | `taskId` 或 `agvTaskId` | docx 的 `Task_ID`,绑定上游波次号或任务标识需最终确认 |
|
||||
| 分拣状态 | `syStatus` | 0 空闲、2 已分配、4 分拣中、6 任务完成 |
|
||||
| 电子标签 | `lamp` | 电子标签 ID |
|
||||
| 分拣周转箱 | `fjLpn` | 当前正在分拣的周转箱 |
|
||||
| 分拣 SKU | `fjSku` | 当前正在分拣的 SKU |
|
||||
| 分拣批次 | `fjBatch` | 当前正在分拣批次 |
|
||||
| 出库类型范围 | `ckType` | 可绑定的出库任务类型,多值 |
|
||||
| 组号 | `groupIndex` | UI 显示分拣墙组 |
|
||||
| AGV 并发量 | `zdAgv` | 当前工作站最多未完成周转箱数,docx 写在 workStationCode 表,需确认是放工作站还是分拣墙 |
|
||||
|
||||
计划文件:
|
||||
- 修改迁移:`wes-loghub/src/main/resources/db/migration/mysql/V3_1_2_x__agv_sorting_wall_fields.sql`
|
||||
- 修改领域对象:`wes-loghub/wms-automation/src/main/groovy/com/ittx/wms/automation/domain/WcsSortingWall.groovy`
|
||||
- 如 `zdAgv` 放工作站,修改:`wes-loghub/wms-automation/src/main/groovy/com/ittx/wms/automation/domain/WcsWorkStation.groovy`
|
||||
|
||||
### 3.3 任务头/明细字段映射
|
||||
|
||||
docx 多次提到任务头自定义字段:
|
||||
- 自定义1:出库任务类型
|
||||
- 自定义2:任务分配到分拣墙时间
|
||||
- 自定义3:电子标签货架货位号
|
||||
- 自定义4:上游波次号
|
||||
|
||||
当前 `TaskHeader.groovy` 没有这些显式字段,计划采用两种方案之一:
|
||||
|
||||
| 方案 | 做法 | 优点 | 风险 |
|
||||
| --- | --- | --- | --- |
|
||||
| 推荐 A | 新增明确字段:`shipmentType/agvAssignedAt/agvSortingWallCode/upstreamWaveCode` | 语义清楚,后续维护稳定 | 需要迁移和上游字段映射 |
|
||||
| 备选 B | 使用现有 `EntityUserDef` 自定义字段 | 改动小 | 字段语义隐性,后续易混淆 |
|
||||
|
||||
建议先确认任务头“自定义1-4”在当前数据库实际列名,再决定字段落点。
|
||||
|
||||
## 4. 后端服务计划
|
||||
|
||||
### 4.1 AGV 分拣工作站服务(部分完成)
|
||||
|
||||
当前落点:`com.ittx.wms.wave.service.hairo.AgvSortingService`
|
||||
|
||||
状态:已创建 AGV 出库分拣统一服务骨架,具体登录、开始、退出、暂停、继续逻辑仍待补齐。
|
||||
|
||||
原计划服务:`com.ittx.wms.automation.service.hairo.AgvSortingStationService`
|
||||
|
||||
职责:
|
||||
- `loginStation(session, warehouseCode, workStationCode)`:校验 `wcs_work_station` 存在且启用。
|
||||
- `startSorting(session, workStationId, shipmentType)`:校验 `currentJobMode` 为 0 或 2,更新为 2,写入当前出库单类型。
|
||||
- `exitSorting(session, workStationId)`:`currentJobMode=2` 时更新为 0。
|
||||
- `pauseAccept(session, workStationId)`:`acceptStatus=0`。
|
||||
- `resumeAccept(session, workStationId)`:`acceptStatus=1`。
|
||||
|
||||
注意:
|
||||
- 现有 `WcsWorkStation.acceptStatus` 是 String,docx 写 0/1,需要确认字典值。计划中先按现有常量或字典,不硬编码数字。
|
||||
- `currentJobMode=2` 表示 AGV 出库分拣模式,需要补常量注释。
|
||||
|
||||
### 4.2 分拣墙箱绑定服务
|
||||
|
||||
新增服务:`com.ittx.wms.automation.service.hairo.AgvSortingWallBoxService`
|
||||
|
||||
接口:
|
||||
- `bindBox(session, warehouseCode, sortingWallCode, lpn)`:校验分拣墙存在、`lpn` 为空、调用 WMS 周转箱检查接口、回写 `wcs_sorting_wall.lpn`。
|
||||
- `replaceFullBox(session, warehouseCode, sortingWallCode, oldLpn, newLpn)`:满箱换箱;docx 此处描述仍写“检查可用并更新 LPN”,需确认是否要先封箱旧箱。
|
||||
- `sealBox(session, warehouseCode, sortingWallCode)`:要求 `syStatus=6`,清空 `taskId/lpn`,`syStatus=0`,下发灭灯。
|
||||
- `shortage(session, warehouseCode, sortingWallCode)`:二次确认后触发缺料重分配、缺料盘点单、继续显示下一货品或回库。
|
||||
|
||||
依赖待确认:
|
||||
- 上游 WMS 周转箱检查接口。
|
||||
- 电子标签灭灯接口。
|
||||
- 缺料盘点单创建接口/字段。
|
||||
|
||||
### 4.3 波次任务分配计划任务
|
||||
|
||||
新增服务:`com.ittx.wms.automation.service.hairo.AgvWaveTaskAssignService`
|
||||
|
||||
入口:
|
||||
- 建议先不加 `@Scheduled`,提供 `assignOnce()`;计划任务开关确认后再接调度入口。
|
||||
|
||||
筛选工作站:
|
||||
- `wcs_work_station.currentJobMode=2`
|
||||
- `acceptStatus=1`
|
||||
- `status=1`
|
||||
|
||||
筛选分拣墙:
|
||||
- `wcs_sorting_wall.workStationCode = 当前工作站`
|
||||
- 存在 `taskId is null`
|
||||
- 若分拣墙已有 `taskId`,该货架不再下发任务。
|
||||
|
||||
筛选任务头:
|
||||
- 仓库 = 当前仓库
|
||||
- 拣货任务头已释放
|
||||
- 任务从货位区域 = AGV 区域
|
||||
- 任务头状态 = 100
|
||||
- AGV 分拣分配时间为空
|
||||
- 任务头出库任务类型包含在分拣墙 `ckType`
|
||||
- 任务头上游波次号关联上游波次号段表,且号段未分配
|
||||
|
||||
分配动作:
|
||||
- `wcs_sorting_wall.taskId = task_header.上游波次号`
|
||||
- `wcs_sorting_wall.syStatus = 2`
|
||||
- `task_header.agvAssignedAt = now`
|
||||
- `task_header.agvSortingWallCode = wcs_sorting_wall.code`
|
||||
- 上游波次号段表标记已分配
|
||||
|
||||
需要复用/衔接:
|
||||
- Shopee 集波里已有 `shopee_wave` 号段逻辑,需确认 “上游波次号段表” 是否就是 `shopee_wave`。
|
||||
|
||||
### 4.4 AGV 下发计划任务
|
||||
|
||||
新增服务:`com.ittx.wms.automation.service.hairo.AgvDispatchService`
|
||||
|
||||
可复用现有:
|
||||
- `wes-loghub/wms-automation/src/main/groovy/com/ittx/wms/automation/service/WcsDispatchTaskService.groovy`
|
||||
- `AgvTaskCreateWcsCmd.groovy`
|
||||
- `AgvTaskCancelWcsCmd.groovy`
|
||||
|
||||
流程:
|
||||
- 轮询 AGV 分拣工作站。
|
||||
- 查询当前工作站 `wcs_dispatch_task.processStatus` 未完成数量 Y。
|
||||
- 比较工作站 AGV 并发量 Z,`Y < Z` 才继续。
|
||||
- 查询当前分拣墙 `taskId` 下的拣货明细:
|
||||
- 从区域 = AGV 库区
|
||||
- 任务头已释放
|
||||
- 明细状态 = 100
|
||||
- 明细 `fromLPN` 关联 `wcs_container`
|
||||
- `wcs_container.onHandStatus = 10`
|
||||
- 按货品排序,最多取 `Z - Y` 个周转箱。
|
||||
- 每个周转箱创建一条 `wcs_dispatch_task`,并下发 AGV 搬运任务。
|
||||
|
||||
待确认:
|
||||
- AGV 库区标识来自系统参数、库区配置还是任务明细字段。
|
||||
- `wcs_container.onHandStatus=10` 是否已有常量。
|
||||
- `processStatus` 未完成状态集合是否复用现有 `WcsDispatchTaskService` 常量。
|
||||
|
||||
### 4.5 AGV 到站与扫箱分拣服务
|
||||
|
||||
新增服务:`com.ittx.wms.automation.service.hairo.AgvOutboundSortingService`
|
||||
|
||||
接口:
|
||||
- `scanContainer(session, workStationCode, containerCode, preferenceCode, pickMode)`:扫周转箱,读取首个待分拣货品。
|
||||
- `scanSku(session, containerCode, skuCode, pickMode)`:校验 SKU、冻结状态、订单箱是否绑定齐全,返回分拣指引。
|
||||
- `scanUid(session, containerCode, skuCode, uid)`:UID 受库存管理时逐件扫描并累计 SKU 数量。
|
||||
- `confirmByLamp(session, lampCallback)`:电子标签拍灯确认。
|
||||
- `manualConfirm(session, currentSortingContext)`:手工确认。
|
||||
- `nextSortingItem(session, containerCode, mode)`:批量/按单切换下一任务。
|
||||
|
||||
批量模式:
|
||||
- 同一周转箱第一个 `SKU + 批次 + 库存状态` 下,展示所有分拣墙格口任务。
|
||||
|
||||
按单模式:
|
||||
- 同一周转箱第一个 `SKU + 批次 + 库存状态` 下,只展示第一个格口任务;完成后切下一个格口。
|
||||
|
||||
确认动作:
|
||||
- 任务明细确认。
|
||||
- 将 `wcs_sorting_wall.lpn` 回写到任务明细自定义1字段。
|
||||
- 清空 `wcs_sorting_wall.fjLpn/fjSku/fjBatch`。
|
||||
- `syStatus` 回到 2。
|
||||
- 若整个格口任务完成,亮绿灯并 `syStatus=6`。
|
||||
- 若当前周转箱全部完成,下发周转箱回库。
|
||||
|
||||
### 4.7 按单拣货交付服务
|
||||
|
||||
流程图中“按单拣货”比批量拣货多一个交付阶段,建议新增服务:`com.ittx.wms.automation.service.hairo.AgvSingleOrderDeliveryService`
|
||||
|
||||
接口:
|
||||
- `stopPickingOrder(session, workStationCode, taskCode)`:点击“停止拣货订单”。
|
||||
- `bindNewBoxToSortPosition(session, workStationCode, sortingLocationCode, lpn)`:继续拣货时绑定新料箱至分播位。
|
||||
- `finishAssignedTaskToStation(session, workStationCode)`:没有继续拣货时,将未分配完的拣货任务返回本工作站。
|
||||
- `handoverToPtl(session, workStationCode, sortingLocationCode)`:机器人搬运待交付料箱至分播位,人员离开后触发 PTL 进行确认。
|
||||
- `ptlConfirmDelivery(session, ptlCallback)`:PTL 绿灯闪烁、完成分播、关闭分播口后同步状态。
|
||||
|
||||
状态同步:
|
||||
- HAIQ 接收拣货任务状态。
|
||||
- 同步拣货任务状态至 Shopee WMS。
|
||||
- 更新拣货任务/订单状态。
|
||||
|
||||
待确认:
|
||||
- PTL 分播口编码与 `wcs_sorting_wall`、`wcs_sorting_wall_cell` 还是其它表关联。
|
||||
- “机器人搬运待交付料箱至分播位”是否复用 `wcs_dispatch_task`,还是需要新任务类型。
|
||||
- “人员离开,无待搬运料箱”由 UI 点击确认、机器人回调还是 PTL 回调触发。
|
||||
|
||||
可参考:
|
||||
- `wms-shipping/src/main/groovy/com/ittx/wms/shipping/service/RebinService.groovy`
|
||||
- `wms-task/src/main/groovy/com/ittx/wms/task/service/TaskHeaderService.groovy`
|
||||
- `wms-task/src/main/groovy/com/ittx/wms/task/service/TaskDetailService.groovy`
|
||||
|
||||
### 4.6 电子标签接口
|
||||
|
||||
新增/复用 WCS 接口命令:
|
||||
- 亮红灯:按 `wcs_sorting_wall.lamp` 下发当前 SKU 对应格口分拣数量。
|
||||
- 灭灯:封箱时下发。
|
||||
- 亮绿灯:格口整个任务完成。
|
||||
- 拍灯回调:根据 `lamp` 找 `wcs_sorting_wall`,按 `syStatus` 判断是任务确认还是封箱确认。
|
||||
|
||||
待确认:
|
||||
- 电子标签接口路径、报文结构、回调结构。
|
||||
- `lamp` 是否唯一绑定到 `wcs_sorting_wall`。
|
||||
|
||||
## 5. UI 计划
|
||||
|
||||
### 5.1 AGV 分拣首选项维护(部分完成)
|
||||
|
||||
新增菜单:AGV 分拣首选项。
|
||||
|
||||
功能:
|
||||
- 编码、名称、仓库。
|
||||
- 分拣方式:批量/按单。
|
||||
- 所有用户。
|
||||
- 是否默认。
|
||||
- 用户权限配置,参考“包装复合首选项”。
|
||||
|
||||
已完成:
|
||||
- `agv_preference` table/bill/TabbedBill JSON 已新增。
|
||||
- 出库配置菜单已增加 `AGV分拣首选项`。
|
||||
|
||||
待实现/待确认:
|
||||
- 用户权限配置。
|
||||
|
||||
### 5.2 AGV 分拣工作台(部分完成)
|
||||
|
||||
入口:
|
||||
- 打开页面后扫描/选择工作站。
|
||||
- 校验工作站存在。
|
||||
- 进入管理界面。
|
||||
|
||||
操作区:
|
||||
- 开始:弹框选择出库单类型。
|
||||
- 退出:退出 AGV 分拣模式。
|
||||
- 暂停/继续:切换 `acceptStatus`。
|
||||
- 绑箱:扫货架号 + 周转箱号。
|
||||
- 满箱:扫货架号 + 周转箱号。
|
||||
- 封箱:扫货架号。
|
||||
- 缺料:二次确认后触发缺料流程。
|
||||
|
||||
分拣区:
|
||||
- 左侧:当前周转箱格口示意,支持 1/2/4/6/8 格,当前格口放大蓝色显示。
|
||||
- 中间:分拣数量、商品图片、商品名称、SKU/UPC。
|
||||
- 右侧:当前工作站两组分拣墙,共 35 个货架:
|
||||
- 第 1 组:4 层 * 5 = 20
|
||||
- 第 2 组:3 层 * 5 = 15
|
||||
- 分拣墙当前货位放大蓝色显示,并显示对应格口分拣数量。
|
||||
|
||||
已完成:
|
||||
- `cbt-ui/src/views/wes/workStation/utils.ts` 出库菜单已增加 `AGV拣货`。
|
||||
- `cbt-ui/src/views/wes/workStation/home.vue` 已接入 `AGV_PICK` 同级页面,后端作业模式映射为 `PICK`。
|
||||
- `cbt-ui/src/views/wes/workStation/mode/AGV_PICK.vue` 已按参考图绘制页面,并增加自适应防覆盖样式。
|
||||
|
||||
待实现:
|
||||
- 页面真实数据绑定。
|
||||
- AGV 首选项弹窗/选择逻辑。
|
||||
- 开始/退出/暂停/绑箱/满箱/封箱/任务确认按钮接口联动。
|
||||
|
||||
## 6. 接口清单
|
||||
|
||||
| 接口 | 方向 | 状态 |
|
||||
| --- | --- | --- |
|
||||
| 周转箱检查 | WES -> 上游 WMS | 待接口 |
|
||||
| AGV 任务创建 | WES -> WCS/AGV | 可复用现有 `AgvTaskCreateWcsCmd`,需补出库分拣参数 |
|
||||
| AGV 任务完成回调 | WCS/AGV -> WES | 现有回调需确认是否覆盖 |
|
||||
| AGV 任务取消/回库 | WES -> WCS/AGV | 可复用 `AgvTaskCancelWcsCmd`,回库任务需确认 |
|
||||
| 电子标签亮红灯 | WES -> WCS | 待接口 |
|
||||
| 电子标签灭灯 | WES -> WCS | 待接口 |
|
||||
| 电子标签亮绿灯 | WES -> WCS | 待接口 |
|
||||
| 电子标签拍灯回调 | WCS -> WES | 待接口 |
|
||||
| PTL 分播口开始分播 | WES/HAIQ -> PTL | 按单交付阶段待接口 |
|
||||
| PTL 完成分播 | PTL -> WES/HAIQ | 按单交付阶段待接口 |
|
||||
| PTL 关闭分播口 | PTL -> WES/HAIQ | 按单交付阶段待接口 |
|
||||
| PTL 绿灯闪烁/确认 | PTL -> WES/HAIQ | 按单交付阶段待接口 |
|
||||
| 缺料盘点单创建 | WES -> 盘点模块/上游 | 待字段与接口 |
|
||||
|
||||
## 7. 实施任务拆分
|
||||
|
||||
### Task 1:数据模型与配置落地(部分完成)
|
||||
|
||||
- 已完成:新增 `agv_preference` 建表 SQL。
|
||||
- 已完成:新增 `AgvPreference` domain 和 `AgvPreferenceService` 通用 CRUD 服务。
|
||||
- 扩展 `wcs_sorting_wall` AGV 分拣字段。
|
||||
- 视确认结果扩展 `wcs_work_station` 或系统参数保存 AGV 并发量。
|
||||
- 增加常量:AGV 分拣模式、分拣墙状态、首选项模式。
|
||||
- 已完成:增加 `agv_preference` UI 表/单配置。
|
||||
|
||||
### Task 2:工作站 AGV 分拣入口(部分完成)
|
||||
|
||||
- 部分完成:已新增 `AgvSortingService` 统一服务骨架。
|
||||
- 新增 controller endpoint。
|
||||
- 实现登录、开始、退出、暂停、继续。
|
||||
- 记录系统处理日志。
|
||||
- 验证 currentJobMode/acceptStatus 状态切换。
|
||||
|
||||
### Task 3:AGV 分拣首选项(部分完成)
|
||||
|
||||
- 实现首选项 CRUD。
|
||||
- 实现用户权限过滤和默认首选项选择。
|
||||
- 已完成:`agv_preference` table/bill/TabbedBill JSON 和出库配置菜单入口。
|
||||
- 已完成:`AgvPreferenceService` 通用 CRUD 服务。
|
||||
- 待实现:用户权限过滤和默认首选项选择业务逻辑。
|
||||
|
||||
### Task 4:分拣墙绑箱/满箱/封箱/缺料
|
||||
|
||||
- 新增 `AgvSortingWallBoxService`。
|
||||
- 实现货架校验、LPN 校验、周转箱检查接口占位。
|
||||
- 实现封箱清空和灭灯接口占位。
|
||||
- 实现缺料入口:先记录待重分配和待盘点,等接口确认后补全。
|
||||
|
||||
### Task 5:波次任务分配到分拣墙
|
||||
|
||||
- 新增 `AgvWaveTaskAssignService.assignOnce()`。
|
||||
- 查询 AGV 分拣工作站。
|
||||
- 查询空闲分拣墙。
|
||||
- 查询符合条件任务头。
|
||||
- 绑定任务头、分拣墙、上游波次号段。
|
||||
- 增加 Redis 锁,避免多工作站/多计划任务重复分配。
|
||||
|
||||
### Task 6:AGV 任务下发
|
||||
|
||||
- 新增 `AgvDispatchService.dispatchOnce()`。
|
||||
- 控制未完成 AGV 任务数量。
|
||||
- 查询待搬运周转箱。
|
||||
- 创建 `wcs_dispatch_task`。
|
||||
- 调用现有 WCS API 下发 AGV 搬运。
|
||||
- 失败记录系统处理日志。
|
||||
|
||||
### Task 7:扫箱与分拣展示
|
||||
|
||||
- 新增 `AgvOutboundSortingService.scanContainer()`。
|
||||
- 实现批量/按单两种模式的数据查询,接口显式传 `pickMode`。
|
||||
- 返回周转箱格口示意、商品信息、分拣墙示意和分拣数量。
|
||||
- SKU 扫描时校验冻结状态和订单箱绑定状态。
|
||||
- UID 受库存管理时,支持逐件扫描 UID 并累计 SKU 数量。
|
||||
|
||||
### Task 8:电子标签与任务确认
|
||||
|
||||
- 实现亮红灯、亮绿灯、灭灯命令。
|
||||
- 实现拍灯回调确认。
|
||||
- 实现手工确认。
|
||||
- 确认后更新任务明细、分拣墙状态、当前分拣字段。
|
||||
- 当前周转箱完成后触发回库调度。
|
||||
|
||||
### Task 9:按单交付阶段
|
||||
|
||||
- 新增 `AgvSingleOrderDeliveryService`。
|
||||
- 实现“停止拣货订单”。
|
||||
- 实现“继续拣货?”判断。
|
||||
- 继续拣货时查找并绑定新的潜在货位。
|
||||
- 不继续拣货时将未分配完任务返回本工作站。
|
||||
- 触发机器人搬运待交付料箱至分播位。
|
||||
- 对接 PTL 分播口开始分播、完成分播、关闭分播口、绿灯闪烁。
|
||||
- 同步拣货任务状态至 Shopee WMS,并更新本地任务/订单状态。
|
||||
|
||||
### Task 10:异常与缺料闭环
|
||||
|
||||
- SKU 批次冻结时触发重分配。
|
||||
- 缺料按钮触发重分配。
|
||||
- 生成缺料盘点单。
|
||||
- 判断当前周转箱是否还有其它货品,若无则回库。
|
||||
|
||||
### Task 11:UI 页面(部分完成)
|
||||
|
||||
- AGV 分拣首选项页面。
|
||||
- 已完成:AGV 分拣工作台静态页面和自适应样式。
|
||||
- 工作站登录/开始/暂停/退出操作。
|
||||
- 绑箱/满箱/封箱/缺料弹框。
|
||||
- 分拣动态图和电子标签/手工确认交互。
|
||||
- 按单模式增加交付阶段按钮和 PTL 分播口状态展示。
|
||||
|
||||
## 8. 工时预估拆分
|
||||
|
||||
> 预估单位为人日,按 1 名熟悉当前 WES/WMS 代码的开发人员口径估算。外部接口报文未确认、现场 AGV/PTL 联调等待、真实设备排期不计入纯开发人日;若接口或设备行为与计划差异较大,需要另行追加。
|
||||
|
||||
### 8.1 总体预估
|
||||
|
||||
| 范围 | 后端 | 前端 | 联调/验证 | 合计 |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| P0 数据模型与配置 | 2 - 3 | 1 - 2 | 1 | 4 - 6 |
|
||||
| P1 核心出库分拣闭环 | 13 - 19 | 6 - 10 | 3 - 5 | 22 - 34 |
|
||||
| P2 异常、交付与设备闭环 | 8 - 13 | 3 - 5 | 6 - 8 | 17 - 24 |
|
||||
| 合计 | 23 - 35 | 10 - 17 | 10 - 14 | 43 - 64 |
|
||||
|
||||
建议排期:
|
||||
- 最小可用版本:先完成 P0 + P1,约 `26 - 40` 人日,可覆盖工作站入口、任务分配、AGV 下发、扫箱分拣、确认闭环。
|
||||
- 完整版本:完成 P0 + P1 + P2,约 `43 - 64` 人日,覆盖按单交付、缺料、冻结、PTL 和现场设备闭环。
|
||||
- 若上游 WMS、WCS/AGV、PTL 接口可提前提供稳定 mock,联调人日可压缩约 `20% - 30%`。
|
||||
|
||||
### 8.2 按任务拆分
|
||||
|
||||
| Task | 内容 | 后端 | 前端 | 联调/验证 | 合计 | 备注 |
|
||||
| --- | --- | ---: | ---: | ---: | ---: | --- |
|
||||
| Task 1 | 数据模型与配置落地 | 2 - 3 | 1 | 0 - 1 | 3 - 5 | 包含迁移、domain/service、表单配置和常量 |
|
||||
| Task 2 | 工作站 AGV 分拣入口 | 1 - 2 | 1 | 0 - 1 | 2 - 4 | currentJobMode、acceptStatus、系统日志 |
|
||||
| Task 3 | AGV 分拣首选项 | 1 - 2 | 1 - 2 | 0 - 1 | 2 - 5 | CRUD、默认首选项、权限过滤 |
|
||||
| Task 4 | 分拣墙绑箱/满箱/封箱/缺料入口 | 2 - 3 | 1 - 2 | 1 | 4 - 6 | 周转箱检查、灭灯接口先可占位 |
|
||||
| Task 5 | 波次任务分配到分拣墙 | 3 - 4 | 0 | 1 | 4 - 5 | 包含 Redis 锁、任务头/分拣墙回写 |
|
||||
| Task 6 | AGV 任务下发 | 2 - 3 | 0 | 1 - 2 | 3 - 5 | 复用现有 dispatch task,需确认 AGV 参数 |
|
||||
| Task 7 | 扫箱与分拣展示 | 3 - 5 | 2 - 3 | 1 - 2 | 6 - 10 | 批量/按单查询差异、SKU/UID 扫描 |
|
||||
| Task 8 | 电子标签与任务确认 | 3 - 4 | 1 - 2 | 2 - 3 | 6 - 9 | 红灯/绿灯/灭灯、拍灯回调、手工确认 |
|
||||
| Task 9 | 按单交付阶段 | 3 - 5 | 1 - 2 | 2 - 3 | 6 - 10 | PTL 分播口与机器人搬运接口风险较高 |
|
||||
| Task 10 | 异常与缺料闭环 | 3 - 4 | 1 | 1 - 2 | 5 - 7 | 冻结、缺料、盘点单、回库调度 |
|
||||
| Task 11 | UI 页面整合 | 1 | 3 - 5 | 1 - 2 | 5 - 8 | 工作台主界面、动态图、按钮与状态展示 |
|
||||
|
||||
### 8.3 外部依赖风险工时
|
||||
|
||||
| 依赖项 | 风险 | 可能追加 |
|
||||
| --- | --- | ---: |
|
||||
| 上游 WMS 周转箱检查接口 | 报文和校验规则未定,可能影响绑箱/满箱 | 1 - 2 人日 |
|
||||
| WCS/AGV 任务创建与回库接口 | 现有接口可复用程度待确认,可能需要新任务类型 | 1 - 3 人日 |
|
||||
| 电子标签接口与拍灯回调 | 灯号映射、回调幂等、异常补偿需现场验证 | 1 - 3 人日 |
|
||||
| PTL 分播口接口 | 按单交付阶段依赖强,接口未确认时无法闭环 | 2 - 4 人日 |
|
||||
| 缺料盘点单接口 | 字段和生成入口未确认 | 1 - 2 人日 |
|
||||
| 真实 AGV/PTL 现场联调 | 设备排队、网络、回调时序和异常重试不可控 | 3 - 6 人日 |
|
||||
|
||||
### 8.4 里程碑建议
|
||||
|
||||
| 里程碑 | 范围 | 验收口径 | 预估 |
|
||||
| --- | --- | --- | ---: |
|
||||
| M1 基础配置可用 | Task 1 - 3 | 可维护 AGV 首选项,工作站可进入/退出 AGV 分拣模式 | 7 - 12 人日 |
|
||||
| M2 核心分拣可跑 | Task 4 - 7 | 任务可分配到分拣墙,AGV 可下发,扫箱可返回批量/按单分拣指引 | 17 - 26 人日 |
|
||||
| M3 确认闭环可跑 | Task 8 + Task 11 基础界面 | 支持电子标签/手工确认,分拣墙与任务状态可闭环 | 10 - 14 人日 |
|
||||
| M4 异常与交付闭环 | Task 9 - 10 + Task 11 完整界面 | 按单交付、缺料、冻结、回库、PTL 状态完成闭环 | 14 - 22 人日 |
|
||||
|
||||
## 9. 验证计划
|
||||
|
||||
| 验证项 | 方法 |
|
||||
| --- | --- |
|
||||
| 编译 | `:wms-automation:compileGroovy`、涉及 shipping/task 时分别编译对应模块 |
|
||||
| 数据迁移 | 本地 MySQL 执行迁移脚本,确认字段/表存在 |
|
||||
| 工作站状态 | 手工调用接口验证 `currentJobMode/acceptStatus/taskType` |
|
||||
| 任务分配 | 构造已释放 AGV 区任务,执行 `assignOnce()` 验证分拣墙和任务头回写 |
|
||||
| AGV 下发 | 使用模拟 WCS API 验证 `wcs_dispatch_task` 创建和报文 |
|
||||
| 扫箱分拣 | 构造周转箱和任务明细,验证批量/按单返回差异 |
|
||||
| UID 扫描 | 构造受 UID 管理的 SKU,验证逐件扫描和数量统计 |
|
||||
| 确认闭环 | 模拟拍灯/手工确认,验证任务明细、分拣墙状态和回库触发 |
|
||||
| 按单交付 | 模拟停止拣货、继续拣货、绑定新货位、PTL 完成分播 |
|
||||
| 异常流程 | 冻结、缺料、无箱、无任务、AGV 超并发 |
|
||||
|
||||
## 10. 待确认事项
|
||||
|
||||
1. `wcs_sorting_wall.Task_ID` 存“上游波次号”还是“任务头 ID/任务号”。
|
||||
2. `task_header` 自定义1-4在当前数据库中的实际列名。
|
||||
3. `wcs_work_station.acceptStatus` 取值是 `0/1` 还是现有字符串字典。
|
||||
4. AGV 并发量 `ZDagv` 放在工作站表、分拣墙表还是系统参数。
|
||||
5. AGV 区域判断使用库区编码、库区类型还是系统参数。
|
||||
6. 上游波次号段表是否复用 `shopee_wave`。
|
||||
7. 周转箱检查接口报文和返回结构。
|
||||
8. 电子标签接口和拍灯回调报文。
|
||||
9. 缺料盘点单字段和创建入口。
|
||||
10. SKU 批次冻结判断使用库存状态、冻结标识还是库存 holdCode。
|
||||
11. UID 受库存管理的判断字段和 UID 扫描校验接口。
|
||||
12. PTL 分播口、分播位、分拣墙/格口之间的表关系。
|
||||
13. 按单交付阶段是否必须同步 Shopee WMS,接口报文是什么。
|
||||
14. “换人拣货/结束并清除当前任务”的状态清理范围。
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,100 @@
|
||||
# 文档统一汇总
|
||||
|
||||
## 目标
|
||||
|
||||
把 `docs/` 下当前分散的需求、计划、评估和模块说明,统一收敛到一份入口文档里维护。
|
||||
|
||||
## 维护原则
|
||||
|
||||
- 以主题归档,不以项目目录分拆主线内容。
|
||||
- 目录中的历史子文档保留为参考,不作为新的主入口。
|
||||
- 已落地内容和待实现内容要分开写,避免计划和现状混在一起。
|
||||
- 代码、配置、迁移脚本和文档必须保持一致。
|
||||
|
||||
## 当前主线
|
||||
|
||||
### 出库集波 V1.2
|
||||
|
||||
当前已经整理并落地的内容:
|
||||
|
||||
- 新增 `wave_rule` 和 `shopee_wave` 两张表。
|
||||
- 新增 `WaveRule`、`ShopeeWave` 实体和对应 service。
|
||||
- `Wave` 新增 `waveRule`。
|
||||
- `shipment_header` 新增 `cutOffTime`、`purchaseTime`、`orderTime`、`shopeeWave`、`kickOutWave`。
|
||||
- `archive_shipment_header` 和 `deleted_shipment_header` 同步补齐上述字段。
|
||||
- `wcs_sorting_wall_cell` 新增 `waveRule` 和 `currentWaveRule`。
|
||||
- `wcs_work_station_pick_task_header` 新增 `shopeeWave`、`waveRule`。
|
||||
- `wcs_sorting_wall` 明细页的 `waveRule` 已改为多选下拉,支持多规则逗号分隔保存。
|
||||
- `wave_rule` 匹配能力已落地基础链路,当前 `WaveRuleMatchService` 已支持以 `workstationId + 出库类型` 按规则逐条查单并返回格口分配结果;当前版本已接入基础订单池查询、规则优先级、订单优先级排序和 `WAVE_RULE_FIELD_MATCHING` 字典字段匹配。
|
||||
- 可用出库单查找逻辑已和格口分配链路一起维护,`WAVE_RULE_FIELD_MATCHING` 当前支持 `identifier=shipment_header字段`、`value1=wave_rule字段`、`value2=匹配条件`,并支持 `IN`、`=`、`LE` 操作符;`Include / Exclude / Only`、SKU 维度聚合和区间高级语义仍待补齐。
|
||||
- 出库单分配成功后,当前已能回写 `shipment_header.shopeeWave`、占用格口并记录 `currentWaveRule` / `shopeeWaveCode`,再批量加入内部波次并异步提交运行;计划任务轮询补单和 Flow Pick 本地换箱换波闭环已落地,库存不足踢单清绑定已在 `wms-wave` 回池链路处理,上游撤单接口仍待联调。
|
||||
- 集波完成后,需要从 `shopee_wave` 里取出与出库单类型一致的 `waveType` 号段,请求上游做合波校验;当前已有 ESS 校验调用入口和失败订单基础解析,真实接口契约仍待联调确认。
|
||||
- 当前集波运行已调用内部波次 `run`,该方法只异步提交 `wms.wave` 队列消息,`WaveRuleMatchService` 不解析同步运行结果;库存不足踢单由 `wms-wave` 回池流程清空 Shopee 绑定,不记录 `kickOutWave`,上游撤单仍待接口联调。
|
||||
- 波次运行成功后,需要把 `shopee_wave` 号段绑定到出库单头 `shopeeWave`、任务头 `shopeeWave` / `waveRule`,并把当前 `waveRule` 回写到 `wave` 表,同时把 `shopee_wave.status` 更新为 `200` 使用中;当前仅部分链路已落地。
|
||||
- 上墙优先级已按 `wavePriority` 从高到低排序,同规则内已按出库单优先级和时间字段排序;`WAVE_RULE_FIELD_MATCHING` 基础字段匹配已实现。
|
||||
- 同一规则命中的订单池内部,再按 `shipment_header.priority`、`shipment_header.cutOffTime`、`shipment_header.purchaseTime`、`shipment_header.orderTime` 做抓单优先级排序,其中后面三个时间维度均越早越优先。
|
||||
- 命中规则后,再绑定对应 `wave_rule` 的分拣墙槽口,槽口绑定关系跟随规则,不随订单数量变化而改变。
|
||||
- 集波后绑定的槽口需要落到任务表或波次表中,作为拣货执行衔接依据。
|
||||
- `SSSQ` 单品单件已接入 `low_threshold` 系统参数的低阈值判断;槽口已有 `shopeeWaveCode` 时,低于阈值允许继续补单,达到或超过阈值则跳过该格口补单。
|
||||
- `SSSQ` 单品单件已补齐槽口放满后的本地封箱换波闭环:以 `wave_rule.maxShipments` 作为满槽阈值,剩余未完成订单重新取 Shopee 波次并回写任务头、出库单头和格口;真实 Flow Pick 接口、失败后恢复订单池、取消任务下发和 AGV 取消回库仍待联调。
|
||||
- 计划任务补单入口 `pollReplenishment/pollReplenishmentOnce` 已落地,并按 `SSSQ` 与非 `SSSQ` 分两条线处理:`SSSQ` 低于 `low_threshold` 时触发补单,非 `SSSQ` 按 `maxShipments` 缺口补单,并复用 ESS 合波校验失败产生的 `kickOutWave` 过滤。
|
||||
- 推拣货任务与推出库单分流已在 WES 侧落地:推拣货任务同步上游波次号段,按“一单一波一槽口”处理且不补单;推出库单继续走标准集波链路,待上游推单接口联调。
|
||||
- 同工作站不混做不同订单类型已在后端入口落地:集波前通过已占用格口关联 Shopee 波次反查当前工作站作业出库类型,发现其它类型时返回 `MSG_WRM_0014` 并记录系统处理日志。
|
||||
- 出库单结构分类 `shipmentCategory1` 已按 `SSSQ`、`SSAQ`、`MSAQ`、`MSSQ` 口径自动分析,其中 `SSSQ` 与 `Same SKU Same Qty` 视为同一逻辑。
|
||||
|
||||
当前仍待实现的内容:
|
||||
|
||||
- `WAVE_RULE_FIELD_MATCHING` 的 `Include / Exclude / Only`、SKU 维度聚合和区间高级语义。
|
||||
- ESS 合波校验真实接口契约联调;当前已有常见失败订单结构的基础解析,新增测试类已按要求删除,后续以真实联调验证为准。
|
||||
- 上游号段申请、库存不足踢单上游撤单接口和任务头字段完整回写验证。
|
||||
- 轮询补单已具备计划任务入口、USED 格口扫描、`SSSQ`/非 `SSSQ` 分支、ESS 校验和失败过滤能力;后续仍需按真实波次状态、连续空轮条件和接口响应做联调细化。
|
||||
- 单品单件 `SSSQ`,也就是 `Same SKU Same Qty`,的动态加单和换箱换波已落地本地闭环;真实 Flow Pick 封箱/换箱接口失败处理仍待联调。
|
||||
- 推拣货任务和推出库单的上游推单接口联调。
|
||||
- 上游接口联动与异常回退。
|
||||
|
||||
## 主题汇总
|
||||
|
||||
### 基础数据与规则
|
||||
|
||||
- 规则表:`wave_rule`
|
||||
- 波次号段表:`shopee_wave`
|
||||
- 规则优先级:`wavePriority`
|
||||
- 数据字典:`WAVE_RULE_FIELD_MATCHING`
|
||||
- 最大订单数:
|
||||
- `wave_master.maxShipments`:`wave_master` 内部字段,只用于波次创建阶段的截单,不参与可用出库单查找逻辑;未配置时默认最多取 100 单,且必须满足 `minShipments` 才会创建波次。
|
||||
- `wave_rule.maxShipments`:规则级单次抓单上限,当前已在 `WaveRuleMatchService#findAvailableShipments` 中作为候选单数量限制使用。
|
||||
- `shopee_wave.status`:状态值使用 `100/200/900`,分别表示未使用、使用中、使用完成。
|
||||
- `low_threshold`:`WAVE` 系统参数,仅 `SSSQ` 单品单件 wave rule 使用,默认 `0` 表示不启用低阈值拦截。
|
||||
|
||||
### 出库单与任务字段
|
||||
|
||||
- 出库单:`cutOffTime`、`purchaseTime`、`orderTime`、`shopeeWave`、`kickOutWave`
|
||||
- 出库单头结构分类:`shipmentCategory1`
|
||||
- 波次:`waveRule`
|
||||
- 工作站任务头:`shopeeWave`、`waveRule`
|
||||
- 分拨墙格口:`waveRule`、`currentWaveRule`、`shopeeWaveCode`
|
||||
- 波次匹配引擎:`wms-automation/WaveRuleMatchService`(当前主入口为 `workstationId + 出库类型`,按规则逐条查单、按格口绑定 Shopee 波次并返回分配结果)
|
||||
|
||||
### 主题文档
|
||||
|
||||
- [Shopee Automation Vendor 接入协议手册出库模块映射 WES 字段 V1.2](Shopee_Automation_Vendor_接入协议手册_出库模块映射WES字段_V1.2.md)
|
||||
- [Shopee 出库接口 WES 字段映射实现计划](superpowers/plans/2026-06-04-shopee-outbound-api-wes-mapping.md)
|
||||
- [出库集波改动计划](SHOPEE_010_出库集波V1.2_改动计划.md)
|
||||
- [待办事项](SHOPEE_010_出库集波V1.2_待办事项.md)
|
||||
- [工时评估拆分](SHOPEE_010_出库集波_工时评估拆分.md)
|
||||
|
||||
## 模块对应
|
||||
|
||||
- `wms-wave`:波次规则、号段管理、波次主流程。
|
||||
- `wms-wave-config`:波次规则配置与静态定义。
|
||||
- `wms-shipping`:出库单头字段扩展。
|
||||
- `wms-task`:任务相关波次字段。
|
||||
- `wms-automation`:分拨墙和工作站任务联动字段。
|
||||
|
||||
## 当前状态
|
||||
|
||||
- 计划文档已同步当前真实状态,已落地内容与待重建内容已分开。
|
||||
- `WaveRuleMatchService` 当前已承担规则查询、基础订单池查单、`WAVE_RULE_FIELD_MATCHING` 字典基础匹配、格口分配、Shopee 波次绑定、ESS 拒单基础解析、轮询补单和 `SSSQ` Flow Pick 本地换箱换波;高级字段语义和真实上游接口仍需继续补齐。
|
||||
- 出库单候选查询与格口候选查询拆开维护,避免把查单和查格口混为一体。
|
||||
- 代码字段和迁移脚本已补齐基础结构。
|
||||
- 当前使用 JDK 25 执行 `:wms-automation:compileGroovy` 作为主验证方式;不保留新增测试类,Gradle problems report 文件冲突时需使用 `--no-problems-report`。
|
||||
Reference in New Issue
Block a user