Files
huachuang/docs/superpowers/specs/2026-07-27-wms-move-inventory-design.md

165 lines
6.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WMS 移库管理功能设计
## 1. 目标
基于现有 `wms_moveinv``wms_moveinvdtl` 表实现完整的移库管理功能,包括移库单列表、新增、修改、删除、详情、可用库存选择、目标仓位选择,以及供“一键设置”直接调用的自动建单接口。
## 2. 功能范围
### 2.1 移库单列表
- 分页查询移库单主表,默认按主键倒序。
- 展示单据编码、单据类型、业务日期、仓库、总数量、明细数、单据状态、生成方式、创建人、创建时间和备注。
- 单据编码可进入详情页。
- 生成状态的单据允许修改、删除;其他状态不允许修改、删除。
### 2.2 新增和修改
- 页面交互与现有出库单新增、修改保持一致。
- 新增时先选择仓库及库区,再选择该库区内可用库存。
- 库存按载具选择,每个载具生成一条 `wms_moveinvdtl`
- 每条明细必须单独选择一个目标仓位。
- 同一张移库单内,不允许多条明细选择同一个目标仓位。
- 修改页面回填主表和全部明细。
- 修改保存时更新主表,释放旧明细关联的仓位锁,删除旧明细,插入新明细,并按新明细重新加锁。
- 主表的 `total_qty``detail_count` 根据保存的明细汇总生成。
### 2.3 可用库存
库存来源为组盘数据和载具所在仓位,必须同时满足:
- 组盘数据未删除,并处于入库可用状态。
- 载具编码不为空。
- 载具所在仓位已启用且未删除。
- 来源仓位未被其他业务锁定。
- 来源仓位属于当前选择的仓库和库区。
选择结果回填载具编码、来源仓位、来源库区、物料编码、批次、数量、计量单位及来源单号。
### 2.4 手工目标仓位选择
目标仓位必须满足:
- 与来源仓位属于同一个仓库。
- 与来源仓位属于同一个库区。
- 与来源仓位具有相同的 `layer_num`
- 仓位已启用且未删除。
- `lock_type = 0`,即仓位未锁定。
- `storagevehicle_code` 为空,即仓位上没有载具。
- 不能是来源仓位。
- 不能是当前移库单其他明细已经选择的目标仓位。
## 3. 自动目标仓位选择器
新增独立的 `MoveTargetStructSelector`,集中封装自动找位规则。业务 Service 不直接编写找位排序逻辑,方便后续替换算法。
选择器输入:
- 来源仓位。
- 当前批次已经选择的目标仓位标识集合。
选择器输出:
- 一个满足条件的目标仓位。
默认规则:
1. 筛选同仓库、同库区、同层的空闲仓位。
2. 排除来源仓位及当前批次已经选择的目标仓位。
3. 优先选择与来源仓位 `col_num` 距离较近的仓位。
4. 距离相同时按 `row_num``col_num``block_num``struct_id` 升序选择。
5. 找不到目标仓位时抛出业务异常。
仓位候选查询 SQL 统一放在 `StrucAttrMapper.xml` 中,选择器只负责候选校验和顺序选择。
## 4. 一键设置自动建单接口
在 WMS API 模块开放自动创建移库单接口,供出库“一键设置”等跨模块业务调用。
请求参数:
- 来源载具编码列表。
处理流程:
1. 校验载具编码不可重复。
2. 批量查询每个载具对应的来源仓位和可用库存。
3. 对每个载具调用 `MoveTargetStructSelector`,自动选择同库区、同层目标仓位。
4. 本次已选择的目标仓位加入排除集合,确保一车一目标且目标不重复。
5. 生成一张移库单及对应明细。
6. 任意载具不存在、库存不可用或找不到目标仓位时,整个事务回滚。
7. 返回创建成功的移库单标识和单据编码。
接口生成方式使用接口创建对应的字典值,初始单据状态为“生成”。
## 5. 仓位锁定
锁定类型来自字典 `wms_lock_type`
- `4`:移出锁。
- `5`:移入锁。
创建成功后:
- 来源仓位设置 `lock_type = 4`
- 目标仓位设置 `lock_type = 5`
- 两类锁均写入 `inv_type``inv_id``inv_code`,关联当前移库单。
修改时:
1. 校验单据处于生成状态。
2. 仅释放 `inv_id` 等于当前移库单标识的旧来源、目标仓位锁。
3. 更新主表并重建明细。
4. 对新来源仓位加移出锁,对新目标仓位加移入锁。
删除时:
- 仅允许删除生成状态单据。
- 释放当前单据持有的来源和目标仓位锁。
- 删除主表和明细。
建单、修改、删除、加锁和解锁必须处于同一数据库事务。
## 6. 数据一致性与并发
- 保存前再次在数据库中校验来源仓位和目标仓位状态,不能只依赖页面查询结果。
- 仓位加锁更新必须带上当前未锁定条件,受影响行数不为 1 时视为仓位已被占用并回滚。
- 同一载具不能在一张单据中重复出现。
- 同一目标仓位不能在一张单据中重复出现。
- 主表、明细和仓位锁任一步失败,整笔事务回滚。
## 7. 前端结构
- 新增移库管理 API 文件。
- 新增移库列表页面。
- 新增全屏移库新增/修改页面。
- 新增库存选择弹窗。
- 新增目标仓位选择弹窗。
- 新增移库详情页面。
- 表格列沿用系统全局分隔线、勾选框颜色和操作按钮图标规范。
## 8. 错误处理
需要提供明确的中文业务异常:
- 移库单不存在。
- 当前状态不允许修改或删除。
- 来源载具不存在或库存不可用。
- 来源仓位已锁定。
- 目标仓位已占用或已锁定。
- 目标仓位与来源仓位不在同一库区或同一层。
- 目标仓位在当前单据中重复。
- 未找到同库区、同层的可用目标仓位。
## 9. 验证范围
- 后端编译通过。
- 前端类型检查通过。
- 新增、修改时主表和明细正确保存。
- 修改时旧锁释放、新锁正确创建。
- 删除时来源和目标仓位锁正确释放。
- 自动找位只选择同库区、同层、未锁定、无载具的仓位。
- 批量自动建单目标仓位不重复。
- 任意一条自动找位失败时不产生主表、明细或残留锁。
- 起点锁定类型为 `4`,目的点锁定类型为 `5`