Files
huachuang/docs/superpowers/specs/2026-08-05-empty-box-transport-design.md
2026-08-05 15:34:35 +08:00

6.0 KiB
Raw Blame History

空木箱出入库设计规格

目标

在 WMS 中增加空木箱入库、出库及任务回调能力。木箱规格统一读取 wms_boxtype,实际木箱保存在 wmw_boxinfo,仓位通过锁类型避免并发重复分配。

方案比较

  1. SQL 完成全部选位与锁定:数据库往返少,但同规格同排、新排回退和并发重试会形成复杂 SQL后续调整策略困难。
  2. 加载全部仓位后由 Java 选位:规则直观,但仓位量增长后内存和数据库传输成本较高。
  3. SQL 筛选有限候选排Java 执行优先级,条件更新抢锁:兼顾性能、并发安全和规则可维护性。

采用方案 3。Mapper XML 只返回少量候选排或候选木箱Service 按优先级逐个尝试条件更新;更新行数为 0 时继续下一个候选。

数据模型

木箱规格表 wms_boxtype

字段为:

  • id:主键。
  • material_code:木箱规格编码,业务唯一。
  • material_name:规格名称。
  • lash_num:捆扎次数。
  • box_lengthbox_widthbox_height:长、宽、高。

空木箱业务只通过 material_code 接收规格,名称、尺寸和捆扎次数均从该表读取,不信任调用方传入的规格属性。

木箱实例表 wmw_boxinfo

保留现有字段,并增加:

  • status0 待入库、1 在库、2 已出库。
  • out_time:实际出库完成时间,未出库时为空。

insert_time 表示实际入库完成时间。创建入库任务时先生成待入库记录;任务完成后写入实际入库时间并改为在库。出库完成后保留记录,更新状态和出库时间。

仓位锁

在字典 wms_lock_type 增加:

  • 8:木箱入库锁。
  • 9:木箱出库锁。

锁定时将任务预占码写入 task_code,任务创建成功后替换为任务 ID。完成或取消时必须同时清空 task_code 并恢复未锁定状态。

模块边界

  • nl-module-wms-api:提供其他模块可调用的 EmptyBoxApi、请求对象和响应对象。
  • nl-module-wms-server:提供控制器、规格和木箱 Mapper、仓位候选 SQL、空木箱领域服务及 EmptyBoxTask
  • nl-module-task-api:复用现有任务创建、下发和目的点未完成任务数接口,不修改任务模块内部业务。
  • nl-module-base-api:复用编码生成接口,通过规则编码 BOX_CODE 生成木箱编码。

任务回调类只转发 taskId,完成与取消的事务逻辑封装在空木箱 Service 中。

入库流程

  1. 接口接收 deviceCodematerialCode,校验木箱规格存在。
  2. 查询候选排:第一优先级为已经存放同规格空木箱、没有其他规格木箱和实载载具且仍有空仓位的排;第二优先级为整排没有载具的排。
  3. 每个候选排只查询一个可用仓位,使用 lock_type = 1、载具为空作为条件更新为木箱入库锁。并发抢锁失败时尝试下一候选。
  4. 调用 BOX_CODE 生成木箱编码,根据规格表属性插入状态为待入库的 wmw_boxinfo
  5. 创建并下发任务:起点为 deviceCode,终点为目标仓位编码,载具编码为新木箱编码,业务处理器为 EMPTYBOXTASK
  6. 任务完成后,将木箱编码绑定至仓位,数量置为 1仓位解锁木箱状态改为在库并写入实际入库时间。
  7. 任务取消后解锁仓位,并物理删除对应的待入库木箱记录。

任一步骤异常都回滚本地事务;远程任务创建或下发失败时抛出业务异常,依赖现有任务回滚接口处理已创建任务。

出库流程

  1. 接口接收 materialCode,只查询状态为在库、已绑定可用仓位且仓位未锁定的同规格木箱。
  2. insert_time 升序、box_id 升序取得有限候选,逐条通过条件更新增加木箱出库锁;并发抢锁失败时继续下一条。
  3. 当前临时出库点为 ZXQ_01ZXQ_02。负载计算为“对应点位未完成任务数 + 点位当前占用库存数”,选择负载较小的点位,相同则选择 ZXQ_01
  4. 点位占用库存数暂由 WMS 内部扩展方法获取。代码保留清晰扩展标记,后续替换为 LMS 接口同时返回候选出库点及其占用情况,不改变空木箱业务主流程。
  5. 创建并下发任务:起点为木箱所在仓位,终点为选定出库点,载具编码为木箱编码。
  6. 任务完成后解锁仓位并清空载具编码和数量;木箱状态改为已出库并写入 out_time,历史记录保留。
  7. 任务取消后只解除仓位锁,木箱记录仍为在库且继续绑定原仓位。

对外接口

  • 入库创建:请求包含 deviceCodematerialCode;响应包含 taskIdboxNotargetStructCode
  • 出库创建:请求包含 materialCode;响应包含 taskIdboxNodestinationPoint

服务端管理接口复用相同请求和响应语义。所有参数使用注解校验,对外 API 类型放在 WMS API 模块。

一致性与异常

  • 未找到规格、候选排、空仓位或可出库木箱时抛出明确的 ServiceException
  • 仓位锁使用带原状态条件的更新保证并发安全,不使用“先查后无条件更新”。
  • 木箱完成或取消回调必须按任务 ID 精确匹配一个锁定仓位;匹配数量异常时拒绝静默成功。
  • 重复完成或重复取消属于幂等冲突,抛出业务异常以暴露任务状态不一致。
  • 所有查询和更新 SQL 写入 Mapper XML不使用 @Select@Update

验收范围

  • 同规格排存在空位时优先入同排;不存在时选择整排为空的排。
  • 不同规格空木箱和带组盘记录的载具不会被安排在同一排。
  • 入库创建、完成、取消均正确维护木箱状态和仓位锁。
  • 出库严格按实际入库时间先进先出,并在并发条件下不会重复选择木箱。
  • 出库点按任务数和占用库存数综合负载选择,并在响应中返回目的点。
  • 出库完成后木箱历史记录仍可查询,仓位已清空。
  • WMS 模块编译通过Mapper XML 可正常加载。