feat:出库单一键设置功能及移库单CRUD
This commit is contained in:
164
docs/superpowers/specs/2026-07-27-wms-move-inventory-design.md
Normal file
164
docs/superpowers/specs/2026-07-27-wms-move-inventory-design.md
Normal file
@@ -0,0 +1,164 @@
|
||||
# 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`。
|
||||
Reference in New Issue
Block a user