From c15e9a37dd4b70cc8b5133a9776ac20078e7765f Mon Sep 17 00:00:00 2001 From: zhouz <> Date: Wed, 22 Jul 2026 14:16:38 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E5=AE=8C=E5=96=84=E5=87=BA=E5=BA=93?= =?UTF-8?q?=E5=8D=95=E6=96=B0=E5=A2=9E=E5=8A=9F=E8=83=BD=E8=AE=BE=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../2026-07-22-outbound-create-design.md | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 docs/superpowers/specs/2026-07-22-outbound-create-design.md diff --git a/docs/superpowers/specs/2026-07-22-outbound-create-design.md b/docs/superpowers/specs/2026-07-22-outbound-create-design.md new file mode 100644 index 00000000..bf815e8f --- /dev/null +++ b/docs/superpowers/specs/2026-07-22-outbound-create-design.md @@ -0,0 +1,117 @@ +# 出库单新增功能设计 + +## 目标与范围 + +按照 `.image/出库新增.png` 重构出入库单主表的新增布局,支持从仓库可用库存选择和手工新增物料汇总两种明细添加方式,并将主表与明细作为一个聚合事务保存。 + +本次仅实现出库新增,不新增数据库字段,不扩展入库、明细编辑、分配、确认或回传流程。主表使用 `wms_iostorinv`,明细写入 `wms_iostorinvdtl`。 + +## 页面布局 + +新增页采用已确认的参考图布局: + +- 顶部操作区提供“保存”和“关闭”。 +- 主表区域展示单据号、仓库、业务类型、单据状态、明细数、总重量、业务日期和备注。 +- 明细区域提供“选择库存”和“新增汇总”两个入口。 +- 明细表展示序号、物料编码、物料名称、箱号、子卷号、SAP 批次号、出库重量、单位、源单号、明细备注和操作。 +- 初次打开时明细表为空。 + +## 主表字段与默认值 + +| 页面字段 | `wms_iostorinv` 字段 | 行为 | +| --- | --- | --- | +| 单据号 | `billCode` | 只读;保存时通过 base 模块编码生成 API 生成 | +| 仓库 | `storId`、`storCode`、`storName` | 必填,可选择 | +| 业务类型 | `billType` | 必填,可选择 | +| 出入类型 | `ioType` | 后端固定为出库 | +| 单据状态 | `billStatus` | 默认并固定为“生成” | +| 明细数 | `detailCount` | 根据明细条数自动计算 | +| 总重量 | `totalWeight` | 汇总明细的出库重量 | +| 业务日期 | `bizDate` | 默认当天,可修改 | +| 备注 | `remark` | 选填 | + +前端在明细增删和重量变化时即时更新明细数与总重量。后端保存时必须根据请求明细重新计算,不能直接信任前端汇总字段。 + +## 明细字段与持久化边界 + +明细使用 `wms_iostorinvdtl` 的现有字段: + +| 业务含义 | 明细字段 | 保存规则 | +| --- | --- | --- | +| 主表关联 | `iostorinvId` | 主表插入后回填 | +| 序号 | `seqNo` | 从 1 开始连续生成 | +| 物料 | `materialId`、`materialCode` | 必填 | +| 子卷号 | `pcsn` | 库存明细带入;手工汇总为空 | +| 出库重量 | `planQty` | 必须大于 0 | +| 已分配数量 | `assignQty` | 新增时为 0 | +| 未分配数量 | `unassignQty` | 新增时等于出库重量 | +| 单位 | `qtyUnitId`、`qtyUnitName` | 从库存或物料信息带入 | +| 来源单据 | `sourceBillCode`、`sourceBillType`、`sourceBilldtlId` | 库存存在来源时带入 | +| 备注 | `remark` | 选填 | + +箱号、物料名称和独立 SAP 批次号在 `wms_iostorinvdtl` 中没有对应字段,只用于新增页面展示,不落库,也不与其他字段混用。手工汇总明细的箱号、子卷号和 SAP 批次号均为空。 + +## 明细新增方式 + +### 从库存选择 + +1. 用户必须先选择仓库。 +2. 库存弹窗查询该仓库下的可用库存,并支持按物料、箱号、子卷号等现有库存字段筛选。 +3. 用户可独立勾选库存记录,界面不自动联动勾选同箱的其他子卷。 +4. 确认时以后端为准,提取已选记录涉及的箱号,去重后重新查询这些箱号在所选仓库下的全部可用子卷。 +5. 将查询出的每个子卷逐条带回出库明细表;默认出库重量为该子卷当前可用重量。 +6. 同一箱号重复选择只展开一次,避免重复明细。 + +### 新增物料汇总 + +1. 用户选择物料并输入总出库重量,可填写备注。 +2. 单位从物料现有信息带出。 +3. 新增一条汇总明细,箱号、子卷号和 SAP 批次号保持为空。 + +## 接口与事务设计 + +采用主表与明细聚合保存方案: + +- 新增“创建出库单(含明细)”接口,接收主表可编辑字段和明细列表。 +- 新增按仓库和筛选条件查询可用库存的接口。 +- 库存确认或保存前由后端按箱号展开全部可用子卷,确保展开结果属于当前仓库且仍然可用。 +- 保存服务开启事务,先调用 base 模块编码生成 API 获取单据号,再构造主表、计算汇总、插入主表,最后插入全部 `wms_iostorinvdtl` 明细。 +- 编码生成、主表插入或任一明细插入失败时整体回滚。 + +单据号规则沿用项目已有的出入库编码规则配置和 `CodeGenApi` 调用方式,不在本功能中创建新的编码规则或字段。 + +## 数据校验与错误处理 + +- 仓库、业务类型和业务日期必填。 +- 保存时至少存在一条明细。 +- 每条明细必须包含物料,且出库重量大于 0。 +- 切换仓库时清空当前明细,避免跨仓库数据混用。 +- 库存带入时校验箱号属于所选仓库,并以当前可用库存重新展开;库存已不可用时返回明确的业务错误。 +- 重复箱号在展开前去重。 +- 编码 API 返回失败或空编码时终止保存并回滚。 +- 后端固定出库类型和生成状态,并重新计算明细数、总重量、序号及初始分配数量,防止客户端篡改。 + +## 测试与验收 + +后端测试覆盖: + +- base 编码 API 生成的单据号写入主表。 +- 默认出库类型和生成状态正确。 +- 后端根据明细重算明细数和总重量。 +- 主表与明细在同一事务中写入,异常时整体回滚。 +- 库存查询限定所选仓库和可用数量。 +- 任意选中一个箱号下的记录后,返回该箱号全部可用子卷。 +- 多条选中记录包含重复箱号时只展开一次。 +- 物料缺失、重量非正数、空明细及失效库存被拒绝。 + +前端测试或可自动化验证覆盖: + +- 新增页业务日期默认为当天,状态为生成,明细为空。 +- 明细增删和重量修改会更新明细数与总重量。 +- 未选择仓库不能打开库存选择流程。 +- 库存确认结果逐子卷进入明细表。 +- 手工汇总行的箱号、子卷号和 SAP 批次号为空。 +- 切换仓库会清空现有明细。 +- 提交数据只使用现有主表和明细字段。 + +完成后运行 WMS 模块相关单元测试、前端类型检查和构建,并对照参考图检查新增页布局与两种明细添加流程。