更新装配、销售、精工车间、技术中心、仓储多个模块,整理文档和SQL脚本

This commit is contained in:
Developer
2026-06-29 13:36:34 +08:00
parent 137e276340
commit be0ff91e24
54 changed files with 5066 additions and 723 deletions

View File

@@ -0,0 +1,108 @@
# 01-项目功能内容
## 功能名称
库存盘点组件库存调拨功能。
## 应用场景
本功能用于仓储管理中的库存盘点页面。现场盘点时,用户发现某个物料的库存需要从当前库位转移到另一个库位,或者目标库位尚未在系统中维护,需要在调拨时一键新建库位,并把调拨数量从原库位库存中扣减、增加到目标库位库存中。
应用页面:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
```
## 功能目标
1. 在库存盘点列表行内增加“调拨”操作。
2. 点击“调拨”打开库存调拨弹窗。
3. 弹窗自动带出物料名称、图号/型号、原库位、原库存数。
4. 支持选择已有目标库位。
5. 支持输入新库位名称并一键新建库位。
6. 新库位创建成功后自动刷新库位下拉并回填目标库位。
7. 用户输入调拨数量后,提交时从原库位库存数扣减该数量。
8. 如果目标库位已有同物料库存,则目标库位库存累加调拨数量。
9. 如果目标库位没有同物料库存,则新增目标库位的物料库存记录。
10. 调拨成功后刷新库存盘点列表。
11. 后端记录调拨流水,便于追溯操作人、原库位、目标库位、调拨前后库存。
## 功能边界
本次实现的是库存盘点组件内的轻量级库存调拨,不做完整调拨单流程。
包含:
| 功能点 | 说明 |
| --- | --- |
| 行内调拨 | 在库存盘点表格中直接对单行库存发起调拨 |
| 选择目标库位 | 从现有库位下拉中选择 |
| 一键新建库位 | 新建库位后回填为目标库位 |
| 原库位扣减 | 调拨数量从原库位库存中扣除 |
| 目标库位增加 | 已存在则累加,不存在则新增 |
| 调拨记录 | 记录调拨前后库存和操作信息 |
不包含:
| 不包含内容 | 原因 |
| --- | --- |
| 独立调拨单页面 | 当前需求聚焦盘点现场快速调整 |
| 调拨审批 | 未纳入本次业务流程 |
| 打印调拨单 | 未纳入本次验收 |
| 调出确认、调入确认 | 本次为单步原子调拨 |
| 跨仓库复杂调拨 | 当前只有库位级调拨 |
| 外协调拨 | 外协调拨已有独立业务范围 |
## 关键业务规则
| 规则编号 | 规则内容 |
| --- | --- |
| BR-001 | 调拨数量必须大于 0 |
| BR-002 | 调拨数量不能大于原库位当前库存 |
| BR-003 | 目标库位不能为空 |
| BR-004 | 目标库位不能等于原库位 |
| BR-005 | 新库位名称不能为空 |
| BR-006 | 新库位名称不能重复 |
| BR-007 | 后端必须以数据库当前库存重新校验,不能只信任前端原库存数 |
| BR-008 | 原库位扣减、目标库位增加、调拨记录写入必须在同一事务中完成 |
| BR-009 | 调拨后原库位库存为 0 时保留库存记录 |
## 涉及数据对象
| 数据对象 | 用途 |
| --- | --- |
| `库存管理_物料与货位对照表` | 普通物料库位库存 |
| `库存管理_半成品与货位对照表` | 通用件库位库存 |
| `库存管理_货位主文件` | 库位基础数据 |
| `库存盘点_调拨记录` | 库存调拨日志 |
| `库存盘点_修改记录` | 保留原库存修改记录能力 |
## 涉及接口
| 接口/过程 | 类型 | 用途 |
| --- | --- | --- |
| `仓储管理_库存盘点_查询` | 查询 | 调拨前后刷新库存盘点列表 |
| `仓储管理_库位_查询` | 查询 | 获取库位下拉 |
| `仓储管理_库位_验证是否存在` | 查询 | 新建库位前校验重复 |
| `仓储管理_库位_增加数据` | 增改 | 新增目标库位 |
| `仓储管理_库存盘点_库存调拨` | 增改 | 执行原子调拨 |
## 用户操作流程
```mermaid
flowchart TD
A["进入库存盘点页面"] --> B["选择一行库存记录"]
B --> C["点击调拨"]
C --> D["打开库存调拨弹窗"]
D --> E{"目标库位是否已存在"}
E -- "存在" --> F["选择目标库位"]
E -- "不存在" --> G["输入新库位名称并新建"]
G --> F
F --> H["输入调拨数量和备注"]
H --> I["提交调拨"]
I --> J["后端事务扣减原库位并增加目标库位"]
J --> K["写入调拨记录"]
K --> L["刷新库存盘点列表"]
```

View File

@@ -0,0 +1,264 @@
# 02-项目程序开发详细步骤
## 开发入口
前端页面:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
```
SQL 脚本:
```text
sql/仓储管理_库存盘点_库存调拨.sql
```
## 第 1 步:梳理现有库存盘点页面
确认页面已有能力:
| 已有能力 | 说明 |
| --- | --- |
| 库存查询 | 调用 `仓储管理_库存盘点_查询` |
| 编辑库存 | 调用 `仓储管理_库存盘点_货位数量_编辑数据` |
| 库位下拉 | 调用 `仓储管理_库位_查询` |
| 新增物料存货 | 页面已有新增库存相关逻辑 |
确认表格已有字段:
```text
物料编码
物料流水号
物料名称
图号或型号
物料与货位流水号
类型
库存
货位流水号
货位名称
批次编号
```
## 第 2 步:增加表格调拨入口
在库存盘点表格操作列增加“调拨”按钮。
实现要求:
1. 原操作列宽度调整为可容纳“编辑”和“调拨”。
2. 行处于编辑状态时不显示调拨按钮。
3. 行不处于编辑状态时显示调拨按钮。
关键逻辑:
```html
<el-button v-if="!scope.row.edit" type="text" size="mini" @click="openTransfer(scope.row)">调拨</el-button>
```
## 第 3 步:增加调拨状态和表单对象
`data()` 中增加:
```js
transferDialogVisible: false,
transferLocationAdding: false,
transferSubmitting: false,
transferForm: {
物料与货位流水号: '',
物料流水号: '',
物料名称: '',
图号或型号: '',
类型: '',
原货位流水号: '',
原货位名称: '',
原库存数: 0,
目标货位流水号: '',
目标货位名称: '',
新货位名称: '',
调拨数量: 1,
调拨备注: ''
}
```
## 第 4 步:增加库存调拨弹窗
新增 `el-dialog`,标题为:
```text
库存调拨
```
弹窗内容:
| 字段 | 控件 | 是否可编辑 |
| --- | --- | --- |
| 物料名称 | 文本 | 否 |
| 图号/型号 | 文本 | 否 |
| 原库位 | 文本 | 否 |
| 原库存数 | 文本 | 否 |
| 目标库位 | `el-select` | 是 |
| 新库位 | `el-input` | 是 |
| 调拨数量 | `el-input-number` | 是 |
| 调拨备注 | `el-input` | 是 |
## 第 5 步:打开调拨弹窗
新增方法:
```js
openTransfer(row)
```
处理内容:
1. 校验当前行是否有 `物料与货位流水号`
2. 校验当前行库存是否大于 0。
3. 将当前行物料、库位、库存信息填入 `transferForm`
4. 清空目标库位、新库位、备注。
5. 打开调拨弹窗。
## 第 6 步:选择目标库位
新增方法:
```js
handleTransferLocationChange(value)
```
处理内容:
1. 根据选择的 `货位流水号`,从 `storageLocation` 中找到货位名称。
2. 回填 `transferForm.目标货位名称`
## 第 7 步:一键新建库位
新增方法:
```js
addTransferLocation()
```
处理流程:
1. 校验 `transferForm.新货位名称` 不能为空。
2. 调用 `仓储管理_库位_验证是否存在`
3. 如果库位已存在,提示并按库位名称回填已有库位。
4. 如果库位不存在,调用 `仓储管理_库位_增加数据`
5. 新增成功后调用 `getLocateName()` 刷新库位下拉。
6. 调用 `selectTransferLocation(locationName)` 回填目标库位。
## 第 8 步:提交库存调拨
新增方法:
```js
submitTransfer()
```
前端校验:
| 校验项 | 提示 |
| --- | --- |
| 目标库位为空 | 请选择目标库位 |
| 目标库位等于原库位 | 目标库位不能与原库位相同 |
| 调拨数量小于等于 0 | 调拨数量必须大于0 |
| 调拨数量大于原库存 | 调拨数量不能大于原库存数 |
提交参数:
| 序号 | 参数名 |
| --- | --- |
| 0 | 物料与货位流水号 |
| 1 | 物料流水号 |
| 2 | 原货位流水号 |
| 3 | 目标货位流水号 |
| 4 | 调拨数量 |
| 5 | 原库存数 |
| 6 | 调拨备注 |
| 7 | 操作者 |
| 8 | 类型 |
调用接口:
```js
var Data = this.CreateData('12', '仓储管理_库存盘点_库存调拨', param)
```
成功后:
1. 提示“调拨成功”。
2. 关闭调拨弹窗。
3. 调用 `searchTable()` 刷新列表。
## 第 9 步:后端脚本设计
脚本文件:
```text
sql/仓储管理_库存盘点_库存调拨.sql
```
脚本内容:
1. 如果 `库存盘点_调拨记录` 不存在,则创建该表。
2. 删除并重建存储过程 `dbo.仓储管理_库存盘点_库存调拨`
3.`@类型` 判断库存表:
- `@类型 = N'通用件'` 使用 `库存管理_半成品与货位对照表`
- 其他类型使用 `库存管理_物料与货位对照表`
4. 使用事务处理扣减、增加、新增目标记录、写入日志。
5. 出错时回滚并返回失败信息。
## 第 10 步:后端事务流程
```text
BEGIN TRAN
锁定原库存记录
校验原库存记录存在
校验目标库位不等于原库位
校验当前库存 >= 调拨数量
扣减原库位库存
查询目标库位同物料库存
如果存在则增加目标库存
如果不存在则新增目标库存记录
写入库存盘点_调拨记录
COMMIT TRAN
```
失败处理:
```text
ROLLBACK TRAN
返回 result = 0 和 msg
```
## 第 11 步:数据库部署
部署目标:
```text
SQL Server: 192.168.1.27
Database: ERPTOOL_JY_20250826Back
```
部署对象:
```text
库存盘点_调拨记录
仓储管理_库存盘点_库存调拨
```
## 第 12 步:验证
验证项:
1. SQL 脚本编译通过。
2. 数据库对象存在。
3. 存储过程参数完整。
4. 前端模板解析通过。
5. 前端脚本解析通过。
6. 页面实际选择库存记录调拨。
7. 原库位库存减少。
8. 目标库位库存增加或新增。
9. 调拨记录写入。

View File

@@ -0,0 +1,48 @@
# 03-推进台账
## 台账说明
本文记录库存调拨功能每轮推进情况,包括做了什么、改了哪些文件、验证了什么、下一步是什么。后续继续开发或验收时,应优先查看本台账,避免重复分析。
## 推进台账
| 轮次 | 做了什么 | 改了哪些文件/对象 | 验证了什么 | 下一步 |
| --- | --- | --- | --- | --- |
| 1 | 生成初版库存调拨方案,偏完整调拨单流程 | `库存调拨功能设计方案.md` | 参考仓储模块已有调拨、库存查询页面 | 根据实际场景收敛设计 |
| 2 | 按用户补充场景重写方案,聚焦库存盘点组件内调拨 | `docs/库存调拨/库存调拨功能设计方案.md` | 确认目标是盘点页内一键新建库位并扣减原库位库存 | 开始开发 |
| 3 | 梳理库存盘点页面现状 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 确认已有库存、库位、物料货位字段和查询接口 | 增加前端交互 |
| 4 | 增加表格“调拨”按钮 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 操作列支持编辑和调拨两个入口 | 增加弹窗 |
| 5 | 增加库存调拨弹窗和 `transferForm` | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 弹窗可展示物料、图号、原库位、原库存数等字段 | 增加库位选择 |
| 6 | 增加目标库位选择和库位名称同步 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 选择货位流水号后可同步目标货位名称 | 增加一键新建库位 |
| 7 | 增加一键新建库位逻辑 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 调用 `仓储管理_库位_验证是否存在``仓储管理_库位_增加数据` | 增加调拨提交 |
| 8 | 增加 `submitTransfer()` 调拨提交逻辑 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 前端校验目标库位、调拨数量、原库存限制 | 设计后端原子接口 |
| 9 | 编写 SQL 调拨脚本 | `sql/仓储管理_库存盘点_库存调拨.sql` | 脚本包含记录表和调拨存储过程 | 编译检查 |
| 10 | 执行 SQL 编译检查 | `sql/仓储管理_库存盘点_库存调拨.sql` | `SET NOEXEC ON` 编译输出 `sql compile ok` | 部署数据库对象 |
| 11 | 在 SQL Server 创建调拨对象 | 数据库对象:`库存盘点_调拨记录``仓储管理_库存盘点_库存调拨` | 查询 `sys.objects` 确认对象存在 | 验证参数和字段 |
| 12 | 查询存储过程参数和记录表字段 | SQL Server 元数据 | 确认 9 个存储过程参数和调拨记录表字段 | 做前端静态验证 |
| 13 | 前端模板和脚本解析 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | 输出 `template ok``script ok` | 页面联调 |
| 14 | 生成开发说明文档 | `docs/库存调拨/库存调拨功能开发说明.md` | 汇总功能、步骤、证据、任务矩阵、决策记录 | 按用户要求拆分 7 份文档 |
| 15 | 拆分项目矩阵化文档 | `docs/库存调拨/01-项目功能内容.md` 等 7 份文档 | 文档目录可作为后续推进索引 | 后续补页面截图或实际业务数据验收 |
## 当前状态
| 类型 | 状态 |
| --- | --- |
| 前端开发 | 已完成基础开发 |
| 后端脚本 | 已完成并执行 |
| 数据库对象 | 已创建 |
| 静态验证 | 已完成 |
| 页面实测 | 待执行 |
| 真实数据调拨验收 | 待执行 |
| 截图/PDF 验收材料 | 待补充 |
## 下一步建议
1. 使用测试账号进入库存盘点页面。
2. 查询一条库存大于 0 的物料库位记录。
3. 点击“调拨”。
4. 先调拨到已有库位,验证原库位扣减、目标库位增加。
5. 再新建库位并调拨,验证目标库存记录新增。
6. 查询 `库存盘点_调拨记录`,核对调拨前后库存。
7. 对上述步骤截图,补充到 `05-验收证据.md`

View File

@@ -0,0 +1,70 @@
# 04-任务矩阵
## 任务矩阵说明
本文用于记录库存调拨功能所有任务编号、状态和验收标准。后续继续推进时,先检查任务状态,避免重复开发或重复验证。
状态说明:
| 状态 | 含义 |
| --- | --- |
| 已完成 | 已开发或已验证完成 |
| 待执行 | 需要后续继续做 |
| 待补充 | 已有基础内容,但需要补充更完整证据 |
| 阻塞 | 当前缺少条件,无法推进 |
## 任务矩阵
| 任务编号 | 任务名称 | 状态 | 验收标准 |
| --- | --- | --- | --- |
| INV-TR-001 | 明确应用场景 | 已完成 | 方案明确为库存盘点组件内调拨,不做完整调拨单 |
| INV-TR-002 | 编写库存调拨设计方案 | 已完成 | `docs/库存调拨/库存调拨功能设计方案.md` 已存在 |
| INV-TR-003 | 梳理库存盘点现有字段和接口 | 已完成 | 明确 `库存``货位流水号``物料与货位流水号` 等字段 |
| INV-TR-004 | 增加表格调拨按钮 | 已完成 | `InventoryCheck/index.vue` 操作列出现“调拨”按钮 |
| INV-TR-005 | 增加调拨弹窗 | 已完成 | 弹窗展示物料、图号、原库位、原库存数、目标库位、新库位、调拨数量、备注 |
| INV-TR-006 | 增加调拨状态变量 | 已完成 | 存在 `transferDialogVisible``transferLocationAdding``transferSubmitting` |
| INV-TR-007 | 增加 `transferForm` | 已完成 | 表单包含原库存、目标库位、新库位、调拨数量、调拨备注 |
| INV-TR-008 | 打开调拨弹窗方法 | 已完成 | `openTransfer(row)` 可带出当前行库存信息 |
| INV-TR-009 | 目标库位选择联动 | 已完成 | `handleTransferLocationChange(value)` 可同步目标货位名称 |
| INV-TR-010 | 一键新建库位 | 已完成 | `addTransferLocation()` 可验证重复并新增库位 |
| INV-TR-011 | 新库位回填目标库位 | 已完成 | `selectTransferLocation(locationName)` 可按名称回填新增库位 |
| INV-TR-012 | 调拨提交前端校验 | 已完成 | 目标库位、调拨数量、原库存边界均有校验 |
| INV-TR-013 | 调拨提交接口调用 | 已完成 | 调用 `仓储管理_库存盘点_库存调拨` 并传 9 个参数 |
| INV-TR-014 | 前端传入 `类型` 参数 | 已完成 | 后端可按普通物料/通用件分支处理 |
| INV-TR-015 | 新增调拨 SQL 脚本 | 已完成 | `sql/仓储管理_库存盘点_库存调拨.sql` 已存在 |
| INV-TR-016 | 新增调拨记录表 | 已完成 | 数据库存在 `库存盘点_调拨记录` |
| INV-TR-017 | 新增调拨存储过程 | 已完成 | 数据库存在 `仓储管理_库存盘点_库存调拨` |
| INV-TR-018 | 普通物料调拨分支 | 已完成 | 使用 `库存管理_物料与货位对照表` 扣减和增加 |
| INV-TR-019 | 通用件调拨分支 | 已完成 | 使用 `库存管理_半成品与货位对照表` 扣减和增加 |
| INV-TR-020 | 原库位库存不足校验 | 已完成 | 后端当前库存不足时返回失败并回滚 |
| INV-TR-021 | 目标库位已有库存累加 | 已完成 | 目标库位存在同物料记录时累加库存 |
| INV-TR-022 | 目标库位无库存新增 | 已完成 | 目标库位不存在同物料记录时新增记录 |
| INV-TR-023 | 写入调拨记录 | 已完成 | 调拨记录包含原库位、目标库位、调拨前后库存 |
| INV-TR-024 | SQL 编译检查 | 已完成 | 编译输出 `sql compile ok` |
| INV-TR-025 | 数据库对象验证 | 已完成 | `sys.objects` 可查到表和过程 |
| INV-TR-026 | 存储过程参数验证 | 已完成 | `sys.parameters` 可查到 9 个参数 |
| INV-TR-027 | 调拨记录字段验证 | 已完成 | `INFORMATION_SCHEMA.COLUMNS` 可查到记录字段 |
| INV-TR-028 | 前端模板解析 | 已完成 | `vue-template-compiler` 输出 `template ok` |
| INV-TR-029 | 前端脚本解析 | 已完成 | Babel/脚本解析输出 `script ok` |
| INV-TR-030 | 实际页面调拨到已有库位 | 待执行 | 原库位库存减少,目标库位库存增加 |
| INV-TR-031 | 实际页面调拨到新库位 | 待执行 | 新库位创建成功,目标库存记录新增 |
| INV-TR-032 | 调拨记录业务核对 | 待执行 | `库存盘点_调拨记录` 中调拨前后库存正确 |
| INV-TR-033 | 页面截图留档 | 待补充 | 调拨前、弹窗、调拨后、数据库记录截图齐全 |
| INV-TR-034 | README 索引创建 | 已完成 | `docs/库存调拨/README.md` 指向 7 份文档 |
## 防重复规则
1. 凡状态为“已完成”的任务,后续不重复开发,只做回归验证。
2. 若发现已完成任务仍有缺陷,应新增缺陷任务编号,不直接覆盖原任务含义。
3. 页面实测类任务必须保留截图或数据库查询结果。
4. SQL 过程变更必须同步更新 `05-验收证据.md``06-决策记录.md`
## 当前优先级
| 优先级 | 任务编号 | 原因 |
| --- | --- | --- |
| P0 | INV-TR-030 | 需要真实页面验证核心调拨能力 |
| P0 | INV-TR-031 | 需要验证一键新建库位闭环 |
| P1 | INV-TR-032 | 需要确认追溯记录可用于审计 |
| P1 | INV-TR-033 | 需要补齐交付验收材料 |

View File

@@ -0,0 +1,209 @@
# 05-验收证据
## 验收证据说明
本文记录库存调拨功能已经产生的命令、页面、数据库对象、脚本、输出结果等验收证据。后续如果补充截图、PDF、页面录屏、job_id、report_id应继续追加到本文。
## 证据 1文件清单
已新增或修改的关键文件:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
sql/仓储管理_库存盘点_库存调拨.sql
docs/库存调拨/库存调拨功能设计方案.md
docs/库存调拨/库存调拨功能开发说明.md
docs/库存调拨/01-项目功能内容.md
docs/库存调拨/02-项目程序开发详细步骤.md
docs/库存调拨/03-推进台账.md
docs/库存调拨/04-任务矩阵.md
docs/库存调拨/05-验收证据.md
docs/库存调拨/06-决策记录.md
docs/库存调拨/README.md
```
## 证据 2数据库连接
数据库连接目标:
```text
SQL Server IP192.168.1.27
数据库ERPTOOL_JY_20250826Back
```
已验证连接结果:
```text
DatabaseName=ERPTOOL_JY_20250826Back
Version=Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)
```
## 证据 3SQL 编译检查
脚本:
```text
sql/仓储管理_库存盘点_库存调拨.sql
```
检查方式:
```sql
SET NOEXEC ON
-- 执行脚本文本做编译检查
SET NOEXEC OFF
```
输出结果:
```text
sql compile ok
```
## 证据 4数据库对象创建
执行调拨脚本后查询 `sys.objects`,确认对象存在:
```text
仓储管理_库存盘点_库存调拨 SQL_STORED_PROCEDURE
库存盘点_调拨记录 USER_TABLE
```
验收标准:
| 对象 | 标准 | 状态 |
| --- | --- | --- |
| `仓储管理_库存盘点_库存调拨` | 存储过程存在 | 已通过 |
| `库存盘点_调拨记录` | 用户表存在 | 已通过 |
## 证据 5存储过程参数
查询 `sys.parameters`,确认过程参数:
```text
1 @物料与货位流水号 int
2 @物料流水号 int
3 @原货位流水号 int
4 @目标货位流水号 int
5 @调拨数量 float
6 @原库存数 float
7 @调拨备注 nvarchar
8 @操作者 int
9 @类型 nvarchar
```
验收标准:
1. 参数包含原库存记录流水号。
2. 参数包含原货位和目标货位。
3. 参数包含调拨数量。
4. 参数包含操作者。
5. 参数包含类型,用于区分普通物料和通用件。
状态:已通过。
## 证据 6调拨记录表字段
查询 `INFORMATION_SCHEMA.COLUMNS`,确认调拨记录表字段:
```text
库存调拨流水号 int
类型 nvarchar
物料流水号 int
原物料与货位流水号 int
原货位流水号 int
目标物料与货位流水号 int
目标货位流水号 int
调拨数量 float
调拨前原库存 float
调拨后原库存 float
调拨前目标库存 float
调拨后目标库存 float
调拨备注 nvarchar
操作人 int
操作时间 datetime
```
验收标准:
| 字段组 | 标准 | 状态 |
| --- | --- | --- |
| 原库位信息 | 可记录原库存流水号和原货位 | 已通过 |
| 目标库位信息 | 可记录目标库存流水号和目标货位 | 已通过 |
| 库存变化 | 可记录调拨前后库存 | 已通过 |
| 操作信息 | 可记录备注、操作人、时间 | 已通过 |
## 证据 7前端静态检查
检查对象:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
```
检查内容:
1. Vue template 解析。
2. script 解析。
输出结果:
```text
template ok
script ok
```
说明:
命令因本机 Node 启动较慢触到超时边界,但在超时前已成功输出检查结果。
## 证据 8页面验收待补充
当前仍需补充实际页面证据:
| 证据编号 | 页面/动作 | 状态 | 需要补充 |
| --- | --- | --- | --- |
| PAGE-001 | 库存盘点列表出现“调拨”按钮 | 待补充 | 页面截图 |
| PAGE-002 | 打开库存调拨弹窗 | 待补充 | 弹窗截图 |
| PAGE-003 | 选择已有目标库位调拨 | 待补充 | 调拨前后库存截图 |
| PAGE-004 | 新建库位并调拨 | 待补充 | 新库位回填截图 |
| PAGE-005 | 调拨记录写入 | 待补充 | SQL 查询结果截图 |
## 证据 9建议补充的 SQL 核对语句
后续页面实测后,可用以下方向核对:
```sql
-- 查询调拨记录
SELECT TOP 20 *
FROM _调拨记录
ORDER BY DESC;
```
```sql
-- 查询普通物料库位库存
SELECT *
FROM _物料与货位对照表
WHERE = @
AND IN (@, @);
```
```sql
-- 查询通用件库位库存
SELECT *
FROM _半成品与货位对照表
WHERE = @
AND IN (@, @);
```
## 当前验收结论
| 验收项 | 结论 |
| --- | --- |
| 前端基础实现 | 通过 |
| SQL 编译 | 通过 |
| 数据库对象创建 | 通过 |
| 参数和字段结构 | 通过 |
| 页面实际业务调拨 | 待补充 |
| 截图/PDF/report_id/job_id | 暂无,待页面验收时补充 |

View File

@@ -0,0 +1,106 @@
# 06-决策记录
## 决策记录说明
本文记录库存调拨功能中的关键决策。后续变更时,优先查阅本文,避免重复争论已经确定的技术和业务选择。
## ADR-001不做完整调拨单流程
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 库存调拨只做库存盘点组件内轻量调拨 |
| 原因 | 用户明确场景是盘点时快速把库存从原库位调到目标库位,并支持一键新建库位 |
| 影响 | 不新增独立调拨单页面、不做审批、不做打印 |
| 后续变更条件 | 如果业务要求调拨审批、打印、跨仓库流转,再新增独立调拨单模块 |
## ADR-002使用后端原子存储过程完成调拨
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 新增 `仓储管理_库存盘点_库存调拨`,由一个事务完成扣减和增加 |
| 原因 | 前端拆成两次请求会出现只扣不加、只加不扣、并发负库存风险 |
| 影响 | 前端只提交一次调拨请求,库存一致性由数据库保证 |
| 后续变更条件 | 如果未来迁移到后端服务层,也必须保留事务边界 |
## ADR-003调拨数量使用 FLOAT
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | `@调拨数量`、库存记录字段按 `float` 处理 |
| 原因 | 现有库存表 `货位存量` 使用 `float`,库存可能存在小数 |
| 影响 | 调拨支持小数库存 |
| 后续变更条件 | 若未来统一库存数量精度,应迁移为 decimal 并同步所有库存过程 |
## ADR-004以后端当前库存为准
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 前端传 `原库存数` 只作参考,后端必须重新查询并锁定当前库存 |
| 原因 | 多人同时操作时,前端库存可能已过期 |
| 影响 | 可以避免并发调拨造成负库存 |
| 后续变更条件 | 无。库存扣减类业务都应遵守该规则 |
## ADR-005区分普通物料和通用件库存表
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 根据 `@类型 = N'通用件'` 选择库存表 |
| 原因 | 现有系统中通用件使用 `库存管理_半成品与货位对照表`,普通物料使用 `库存管理_物料与货位对照表` |
| 影响 | 前端必须传 `类型` 参数 |
| 后续变更条件 | 如果后续统一库存表,可移除分支 |
## ADR-006目标库位不存在同物料库存时新增记录
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 目标库位已有同物料库存则累加,没有则新增库存记录 |
| 原因 | 盘点调拨常见场景是将物料拆分到新库位 |
| 影响 | 调拨过程需要同时处理 update 和 insert |
| 后续变更条件 | 如果业务规定必须先建库存记录,再调拨,可改为无记录时报错 |
## ADR-007原库位库存为 0 时保留记录
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 调拨后原库位库存为 0不物理删除库存记录 |
| 原因 | 保留历史库位关系,便于追溯,也符合盘点页库存可编辑为 0 的现状 |
| 影响 | 查询页面是否显示 0 库存由查询条件控制 |
| 后续变更条件 | 如果业务要求隐藏 0 库存,优先改查询,不建议删除记录 |
## ADR-008一键新建库位复用现有接口
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 复用 `仓储管理_库位_验证是否存在``仓储管理_库位_增加数据` |
| 原因 | 系统已有库位校验和新增能力,不重复造接口 |
| 影响 | 新库位创建逻辑与现有库位维护规则保持一致 |
| 后续变更条件 | 如果库位维护规则变化,应统一改库位接口 |
## ADR-009新增轻量调拨记录表
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 新增 `库存盘点_调拨记录` |
| 原因 | 旧库存修改记录无法完整表达“从哪个库位调到哪个库位” |
| 影响 | 后续可以按记录追溯调拨数量、原库位、目标库位、操作人 |
| 后续变更条件 | 如需要调拨单,可在该记录基础上扩展主从表 |
## ADR-010暂不生成 PDF 和截图
| 项目 | 内容 |
| --- | --- |
| 状态 | 已采纳 |
| 决策 | 当前阶段只保留 Markdown 和命令/数据库证据 |
| 原因 | 功能尚需页面真实数据联调,截图/PDF 应在最终页面验收时生成 |
| 影响 | `05-验收证据.md` 中页面截图、PDF、report_id 暂为空 |
| 后续变更条件 | 页面实测完成后补充截图或 PDF 验收材料 |

View File

@@ -0,0 +1,64 @@
# 库存调拨文档索引
## 目录说明
本目录用于沉淀“库存盘点组件库存调拨功能”的设计、开发、推进、验收和决策资料。后续继续开发或验收时,优先从本 README 和任务矩阵开始,避免重复分析和重复开发。
## 标准文档
| 序号 | 文档 | 用途 |
| --- | --- | --- |
| 01 | [01-项目功能内容.md](./01-项目功能内容.md) | 说明功能范围、业务规则、数据对象和接口范围 |
| 02 | [02-项目程序开发详细步骤.md](./02-项目程序开发详细步骤.md) | 说明前端、后端、数据库的详细开发步骤 |
| 03 | [03-推进台账.md](./03-推进台账.md) | 记录每轮做了什么、改了什么、验证了什么、下一步是什么 |
| 04 | [04-任务矩阵.md](./04-任务矩阵.md) | 记录所有任务编号、状态和验收标准 |
| 05 | [05-验收证据.md](./05-验收证据.md) | 汇总命令、数据库对象、输出结果、待补截图等证据 |
| 06 | [06-决策记录.md](./06-决策记录.md) | 记录为什么这么做,后续变更时避免重复争论 |
## 历史文档
| 文档 | 用途 |
| --- | --- |
| [库存调拨功能设计方案.md](./库存调拨功能设计方案.md) | 初始设计方案,包含较完整的业务和技术说明 |
| [库存调拨功能开发说明.md](./库存调拨功能开发说明.md) | 已开发内容汇总,包含早期推进台账和验收证据 |
## 当前任务状态摘要
| 事项 | 状态 |
| --- | --- |
| 前端调拨入口 | 已完成 |
| 调拨弹窗 | 已完成 |
| 一键新建库位 | 已完成 |
| 调拨提交 | 已完成 |
| 调拨 SQL 脚本 | 已完成 |
| 数据库调拨记录表 | 已创建 |
| 数据库调拨存储过程 | 已创建 |
| 前端静态验证 | 已完成 |
| SQL 编译验证 | 已完成 |
| 页面真实数据联调 | 待执行 |
| 页面截图/PDF 验收资料 | 待补充 |
## 后续推进顺序
1. 打开 [04-任务矩阵.md](./04-任务矩阵.md),查看 `INV-TR-030` 之后的待执行任务。
2. 按 [05-验收证据.md](./05-验收证据.md) 中的待补页面证据进行实际页面验收。
3. 页面实测完成后将截图、SQL 查询结果、PDF 或 report_id 补充到 `05-验收证据.md`
4. 如果新增业务规则或改变调拨流程,先更新 [06-决策记录.md](./06-决策记录.md),再改代码。
5. 如果新增任务,追加到 [04-任务矩阵.md](./04-任务矩阵.md),不要复用已有任务编号。
## 快速入口
实际开发文件:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
sql/仓储管理_库存盘点_库存调拨.sql
```
核心数据库对象:
```text
库存盘点_调拨记录
仓储管理_库存盘点_库存调拨
```

View File

@@ -0,0 +1,202 @@
# 库存盘点组件库存调拨功能开发说明
## 01-功能内容
本次功能在库存盘点组件中增加轻量级“库存调拨”能力,应用页面为:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
```
功能目标:
- 在库存盘点列表每一行增加“调拨”操作。
- 点击“调拨”后弹出库存调拨窗口。
- 自动带出当前行物料名称、图号/型号、原库位、原库存数。
- 支持选择已有目标库位。
- 支持在弹窗中输入新库位名称,并一键新增库位。
- 新增库位成功后自动刷新库位下拉,并回填为目标库位。
- 输入调拨数量后,提交时从原库位库存数中扣减该数量。
- 目标库位已有同物料库存时累加库存。
- 目标库位没有同物料库存时新增物料货位库存记录。
- 调拨成功后关闭弹窗并刷新库存盘点列表。
- 后端保留调拨记录,记录调拨前后库存、原库位、目标库位、操作人和操作时间。
本次不做完整调拨单流程,不包含审批、打印、调出确认、调入确认、外协调拨和跨仓库复杂流转。
## 02-程序开发步骤
1. 梳理库存盘点页面现状:
- 查询页面现有字段:`库存``货位流水号``货位名称``物料与货位流水号`
- 确认现有接口:`仓储管理_库存盘点_查询``仓储管理_库存盘点_货位数量_编辑数据``仓储管理_库存盘点_物料货位数量_增加数据`
2. 梳理库位管理现有接口:
- 查询库位:`仓储管理_库位_查询`
- 验证库位是否存在:`仓储管理_库位_验证是否存在`
- 新增库位:`仓储管理_库位_增加数据`
3. 前端开发:
- 在库存盘点表格操作列增加“调拨”按钮。
- 新增 `transferDialogVisible``transferLocationAdding``transferSubmitting` 状态。
- 新增 `transferForm` 表单对象。
- 新增库存调拨弹窗。
- 新增 `openTransfer(row)` 打开弹窗方法。
- 新增 `handleTransferLocationChange(value)` 同步目标库位名称。
- 新增 `selectTransferLocation(locationName)` 新库位新增后回填目标库位。
- 新增 `addTransferLocation()` 一键新增库位。
- 新增 `submitTransfer()` 提交调拨。
4. 后端设计:
- 新增 SQL 脚本:`sql/仓储管理_库存盘点_库存调拨.sql`
- 新增调拨记录表:`库存盘点_调拨记录`
- 新增存储过程:`仓储管理_库存盘点_库存调拨`
- 存储过程使用事务,确保原库位扣减、目标库位增加、新增目标库存记录、累计库存更新、调拨记录写入同时成功或失败。
5. 数据库创建:
- 已连接 SQL Server`192.168.1.27`
- 已在数据库 `ERPTOOL_JY_20250826Back` 中执行脚本。
- 已确认 `库存盘点_调拨记录``仓储管理_库存盘点_库存调拨` 创建成功。
## 03-推进台账
| 轮次 | 做了什么 | 改了哪些文件 | 验证了什么 | 下一步 |
| --- | --- | --- | --- | --- |
| 1 | 生成初版库存调拨设计方案,偏完整调拨单流程 | `库存调拨功能设计方案.md` | 参考了仓储模块现有 `TransferQuery``InventoryQuery` | 根据实际应用场景收敛方案 |
| 2 | 按用户补充场景重写方案,聚焦库存盘点组件内调拨 | `库存调拨功能设计方案.md` | 确认 `InventoryCheck/index.vue` 已有库存、库位和新增物料货位接口 | 开始前端开发 |
| 3 | 开发前端调拨入口和弹窗 | `src/views/WarehouseManagement/InventoryCheck/index.vue` | Vue 模板解析输出 `template ok`,脚本解析输出 `script ok` | 设计后端原子调拨接口 |
| 4 | 连接 SQL Server读取相关存储过程和表结构 | 无代码文件变更 | 成功连接 `ERPTOOL_JY_20250826Back`,确认 SQL Server 2008读取现有盘点、库位相关过程 | 编写调拨存储过程 |
| 5 | 新增存储过程脚本,适配普通物料和通用件 | `sql/仓储管理_库存盘点_库存调拨.sql``src/views/WarehouseManagement/InventoryCheck/index.vue` | SQL `NOEXEC` 编译检查输出 `sql compile ok`;前端补传 `类型` 参数 | 创建数据库对象 |
| 6 | 在数据库中创建调拨记录表和调拨存储过程 | 数据库对象:`库存盘点_调拨记录``仓储管理_库存盘点_库存调拨` | 查询 `sys.objects` 确认对象存在;查询参数和表字段确认结构 | 做页面联调和实际数据调拨测试 |
| 7 | 按要求生成开发说明文档 | `库存调拨功能开发说明.md` | 汇总开发内容、验证证据、任务矩阵和决策记录 | 等待业务数据联调 |
## 04-任务矩阵
| 任务编号 | 任务名称 | 状态 | 验收标准 |
| --- | --- | --- | --- |
| INV-TR-001 | 明确应用场景 | 已完成 | 方案明确为库存盘点组件内调拨,不做完整调拨单 |
| INV-TR-002 | 编写设计方案 | 已完成 | `库存调拨功能设计方案.md` 已按盘点调拨场景重写 |
| INV-TR-003 | 增加表格调拨按钮 | 已完成 | `InventoryCheck/index.vue` 操作列出现“调拨”按钮 |
| INV-TR-004 | 增加调拨弹窗 | 已完成 | 弹窗展示物料、图号、原库位、原库存数、目标库位、新库位、调拨数量、备注 |
| INV-TR-005 | 支持选择目标库位 | 已完成 | 目标库位使用现有 `storageLocation` 下拉,变化时同步目标库位名称 |
| INV-TR-006 | 支持一键新建库位 | 已完成 | 调用 `仓储管理_库位_验证是否存在``仓储管理_库位_增加数据`,成功后刷新并回填 |
| INV-TR-007 | 调拨前端校验 | 已完成 | 校验库存流水号、库存大于 0、目标库位非空、目标库位不等于原库位、调拨数量合法 |
| INV-TR-008 | 提交调拨接口调用 | 已完成 | 前端调用 `仓储管理_库存盘点_库存调拨`,传入调拨数量、目标库位、操作者、类型等参数 |
| INV-TR-009 | 设计存储过程脚本 | 已完成 | `sql/仓储管理_库存盘点_库存调拨.sql` 已生成 |
| INV-TR-010 | 创建调拨记录表 | 已完成 | 数据库中存在 `库存盘点_调拨记录` |
| INV-TR-011 | 创建调拨存储过程 | 已完成 | 数据库中存在 `仓储管理_库存盘点_库存调拨` |
| INV-TR-012 | SQL 编译检查 | 已完成 | `NOEXEC` 检查输出 `sql compile ok` |
| INV-TR-013 | 前端模板和脚本基础检查 | 已完成 | 输出 `template ok``script ok` |
| INV-TR-014 | 页面实际联调 | 待执行 | 在系统页面选择真实库存行,完成调拨并刷新列表 |
| INV-TR-015 | 数据库调拨结果核对 | 待执行 | 原库位库存减少,目标库位库存增加或新增,累计库存保持正确,调拨记录写入 |
## 05-验收证据
### 5.1 数据库连接证据
连接 SQL Server 后返回:
```text
DatabaseName=ERPTOOL_JY_20250826Back
Version=Microsoft SQL Server 2008 (RTM) - 10.0.1600.22 (X64)
```
### 5.2 SQL 编译证据
`sql/仓储管理_库存盘点_库存调拨.sql` 使用 `SET NOEXEC ON` 编译检查:
```text
sql compile ok
```
### 5.3 数据库对象创建证据
执行创建脚本后查询 `sys.objects`
```text
仓储管理_库存盘点_库存调拨 SQL_STORED_PROCEDURE
库存盘点_调拨记录 USER_TABLE
```
### 5.4 存储过程参数证据
查询 `sys.parameters`
```text
1 @物料与货位流水号 int
2 @物料流水号 int
3 @原货位流水号 int
4 @目标货位流水号 int
5 @调拨数量 float
6 @原库存数 float
7 @调拨备注 nvarchar
8 @操作者 int
9 @类型 nvarchar
```
### 5.5 调拨记录表字段证据
查询 `INFORMATION_SCHEMA.COLUMNS`
```text
库存调拨流水号 int
类型 nvarchar
物料流水号 int
原物料与货位流水号 int
原货位流水号 int
目标物料与货位流水号 int
目标货位流水号 int
调拨数量 float
调拨前原库存 float
调拨后原库存 float
调拨前目标库存 float
调拨后目标库存 float
调拨备注 nvarchar
操作人 int
操作时间 datetime
```
### 5.6 前端静态检查证据
使用 `vue-template-compiler` 和 Babel 对 `InventoryCheck/index.vue` 做基础解析,输出:
```text
template ok
script ok
```
说明:命令因本机 Node 启动较慢触到超时边界,但成功输出了检查结果。
### 5.7 文件证据
新增/修改文件:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
sql/仓储管理_库存盘点_库存调拨.sql
库存调拨功能设计方案.md
库存调拨功能开发说明.md
```
## 06-决策记录
| 决策编号 | 决策 | 原因 | 后续影响 |
| --- | --- | --- | --- |
| ADR-001 | 不做完整调拨单流程 | 用户明确应用场景是库存盘点组件内快速调拨 | 页面内弹窗完成,不新增调拨单页面 |
| ADR-002 | 前端不拆成两次库存编辑请求 | 两次请求可能出现只扣不加或并发负库存 | 新增后端原子存储过程 |
| ADR-003 | 调拨数量使用 `FLOAT` | 库存表 `货位存量``float`,旧编辑过程用 `int` 有丢小数风险 | 新过程支持小数库存调拨 |
| ADR-004 | 通过 `物料与货位流水号` 反查物料/产品流水号 | `外购件库存_视图` 当前不返回 `物料流水号` | 前端传空也不影响后端执行 |
| ADR-005 | 支持普通物料和通用件两套表 | 现有盘点编辑过程按 `类型 = 通用件` 区分半成品表和物料表 | 存储过程内部按 `@类型` 分支处理 |
| ADR-006 | 调拨后原库位库存为 0 时保留记录 | 便于追溯,也符合盘点页库存可为 0 的现状 | 查询是否隐藏 0 库存由查询条件控制 |
| ADR-007 | 一键新建库位复用现有库位接口 | 项目已有 `仓储管理_库位_验证是否存在``仓储管理_库位_增加数据` | 不重复新增库位存储过程 |
| ADR-008 | 新增轻量调拨记录表 | 旧 `库存盘点_修改记录` 只能记录原库存更改,不记录目标库位和调拨前后目标库存 | 后续可扩展调拨记录查询 |
| ADR-009 | 前端传 `类型` 参数 | 避免普通物料和通用件流水号存在歧义 | 后端能明确走正确库存对照表 |
| ADR-010 | 暂不做页面截图/PDF | 当前任务聚焦开发和数据库对象创建,未启动本地页面联调 | 下一步实际页面验收时补截图证据 |
## 下一步建议
1. 在测试环境登录系统,进入库存盘点页面。
2. 选择一条库存大于 0 的记录点击“调拨”。
3. 选择已有库位进行调拨,验证原库位减少、目标库位增加。
4. 输入新库位名称点击“新建”,验证库位新增后自动回填。
5. 再执行一次调拨到新库位,验证目标库位新增库存记录。
6. 查询 `库存盘点_调拨记录`,确认调拨记录写入完整。

View File

@@ -0,0 +1,541 @@
# 库存盘点组件库存调拨功能设计方案
## 0. 需求背景
当前库存盘点页面 `src/views/WarehouseManagement/InventoryCheck/index.vue` 已支持查询物料库存、编辑库存数、选择库位,并已存在新增物料货位数量的相关接口。现场盘点时,经常会发现同一物料的实际库存需要从原库位拆分到另一个库位,例如:
- 盘点发现物料实际摆放到了新库位。
- 原库位库存数量过多,需要拆一部分到新库位。
- 系统中还没有目标库位,需要现场一键新建库位后立即调拨。
- 需要保留原库位库存,只把输入的调拨数量从原库位扣掉,并增加到目标库位。
因此本次功能不设计完整调拨单流程,而是在“库存盘点”组件内增加轻量级库存调拨能力:选择一行库存,输入调拨数量,选择或新建目标库位,提交后直接完成原库位库存扣减和目标库位库存增加。
## 1. 设计目标
本功能面向库存盘点页面,核心目标如下:
- 在库存盘点表格行上增加“调拨”操作。
- 调拨弹窗中自动带出当前物料、原库位、原库存数。
- 支持选择已有目标库位。
- 支持一键新建目标库位,并自动回填为调入库位。
- 输入调拨数量后,提交时从原库位库存数中减掉该调拨数量。
- 如果目标库位已有同物料库存,则目标库位库存数增加调拨数量。
- 如果目标库位没有同物料库存,则新增一条物料与货位数量记录。
- 调拨后刷新库存盘点列表,保持页面显示与数据库一致。
## 2. 功能范围
本次只处理库存盘点组件内的库位库存调整,不新增独立“库存调拨单”页面。
包含:
- 盘点列表行内调拨。
- 一键新增库位。
- 原库位扣减库存。
- 目标库位增加库存。
- 调拨操作记录。
不包含:
- 调拨单主表和明细表。
- 调出确认、调入确认两段式流程。
- 审批流程。
- 跨仓库复杂调拨。
- 打印调拨单。
- 外协调拨。
## 3. 页面改造位置
现有页面:
```text
src/views/WarehouseManagement/InventoryCheck/index.vue
```
当前页面已有相关字段和接口:
- 表格字段:`库存``货位流水号``货位名称``物料与货位流水号`
- 库位下拉查询:`仓储管理_库位_查询`
- 盘点查询:`仓储管理_库存盘点_查询`
- 库存编辑:`仓储管理_库存盘点_货位数量_编辑数据`
- 新增物料货位数量验证:`仓储管理_库存盘点_物料货位数量_增加数据_验证是否存在`
- 新增物料货位数量:`仓储管理_库存盘点_物料货位数量_增加数据`
## 4. 前端交互设计
### 4.1 表格增加操作按钮
在库存盘点表格操作列增加:
```text
调拨
```
按钮显示规则:
- 当前行 `物料与货位流水号` 存在时显示。
- 当前行 `库存 > 0` 时允许点击。
- 如果库存为 0按钮禁用或点击提示“当前库位库存为0不能调拨”。
建议按钮:
```html
<el-button type="text" size="mini" @click="openTransfer(scope.row)">调拨</el-button>
```
### 4.2 调拨弹窗
新增 `el-dialog`
```text
库存调拨
```
弹窗字段:
| 字段 | 控件 | 说明 |
| --- | --- | --- |
| 物料名称 | 文本 | 当前行带出,只读 |
| 图号或型号 | 文本 | 当前行带出,只读 |
| 原库位 | 文本 | 当前行 `货位名称`,只读 |
| 原库存数 | 文本 | 当前行 `库存`,只读 |
| 目标库位 | el-select | 选择已有库位 |
| 新库位名称 | el-input | 一键新建库位时填写 |
| 调拨数量 | el-input-number | 需要从原库位调出的数量 |
| 调拨备注 | el-input | 可选 |
弹窗按钮:
- 新建库位
- 确定调拨
- 取消
### 4.3 一键新建库位
在调拨弹窗中增加“新建库位”小区域:
```text
新库位名称 + 新建按钮
```
用户输入新库位名称后点击“新建库位”:
1. 校验库位名称不能为空。
2. 调用后端新增库位接口。
3. 新增成功后重新查询库位下拉。
4. 将新库位流水号自动赋值给 `transferForm.目标货位流水号`
5. 提示“库位新增成功”。
接口建议:
```js
var Data = this.CreateData('12', '仓储管理_库位_增加', param)
```
参数建议:
| 参数名 | 说明 |
| --- | --- |
| 货位名称 | 新库位名称 |
| UserID | 当前用户 |
| ModularID | 当前路由 |
如果后端已有通用库位新增接口,应优先复用现有接口,不重复新增存储过程。
## 5. 调拨业务规则
### 5.1 数量规则
调拨数量必须满足:
```text
0 < 调拨数量 <= 原库存数
```
前端校验:
```js
if (Number(this.transferForm.调拨数量) <= 0) {
this.$message.warning('调拨数量必须大于0')
return
}
if (Number(this.transferForm.调拨数量) > Number(this.transferForm.原库存数)) {
this.$message.warning('调拨数量不能大于原库存数')
return
}
```
后端也必须重复校验,避免多人同时操作导致库存被扣成负数。
### 5.2 库位规则
目标库位必须满足:
- 目标库位不能为空。
- 目标库位不能等于原库位。
- 新建库位名称不能与已有库位重复。
### 5.3 库存更新规则
提交调拨后,后端一次性完成两个动作:
```text
原库位库存 = 原库位库存 - 调拨数量
目标库位库存 = 目标库位库存 + 调拨数量
```
如果目标库位不存在该物料库存记录:
```text
新增 物料 + 目标库位 的库存记录,库存数 = 调拨数量
```
如果目标库位已存在该物料库存记录:
```text
更新目标库位库存数,库存数 = 原目标库位库存数 + 调拨数量
```
### 5.4 原库位库存为 0 的处理
调拨后如果原库位库存变为 0建议保留该物料货位记录并显示库存为 0。
原因:
- 便于追溯原库位曾经存在该物料。
- 避免删除记录影响历史盘点记录。
- 与当前盘点页面“库存数可为 0”的逻辑一致。
如果现场明确要求隐藏 0 库存,可以在查询接口中过滤,不建议物理删除。
## 6. 数据字段设计
### 6.1 前端弹窗对象
建议新增:
```js
transferForm: {
物料与货位流水号: '',
物料流水号: '',
物料名称: '',
图号或型号: '',
原货位流水号: '',
原货位名称: '',
原库存数: 0,
目标货位流水号: '',
目标货位名称: '',
新货位名称: '',
调拨数量: 1,
调拨备注: ''
}
```
### 6.2 后端调拨接口参数
建议新增一个原子接口,避免前端连续调用两个编辑接口导致只扣不加或只加不扣。
接口:
```js
var Data = this.CreateData('12', '仓储管理_库存盘点_库存调拨', param)
```
参数:
| 参数名 | 说明 |
| --- | --- |
| 物料与货位流水号 | 原库存记录流水号 |
| 物料流水号 | 当前物料流水号 |
| 原货位流水号 | 原库位流水号 |
| 目标货位流水号 | 目标库位流水号 |
| 调拨数量 | 本次调拨数量 |
| 原库存数 | 页面带出的原库存数,仅用于校验参考 |
| 调拨备注 | 调拨备注 |
| 操作人 | UserID |
后端处理必须放在同一个事务中:
1. 查询原库存记录,并锁定或重新校验当前库存。
2. 校验当前库存是否大于等于调拨数量。
3. 扣减原库位库存。
4. 查询目标库位是否已有同物料记录。
5. 有则累加目标库位库存。
6. 无则新增目标库位库存记录。
7. 写入库存调拨记录。
8. 返回成功。
## 7. 调拨记录设计
建议新增轻量级调拨记录表,便于盘点后追溯谁把多少库存从哪个库位调到哪个库位。
字段建议:
| 字段名 | 说明 |
| --- | --- |
| 库存调拨流水号 | 主键 |
| 物料流水号 | 物料流水号 |
| 物料名称 | 冗余名称,便于查询 |
| 图号或型号 | 冗余图号 |
| 原物料与货位流水号 | 原库存记录 |
| 原货位流水号 | 原库位 |
| 原货位名称 | 原库位名称 |
| 目标物料与货位流水号 | 目标库存记录 |
| 目标货位流水号 | 目标库位 |
| 目标货位名称 | 目标库位名称 |
| 调拨数量 | 调拨数量 |
| 调拨前原库存 | 扣减前原库位库存 |
| 调拨后原库存 | 扣减后原库位库存 |
| 调拨前目标库存 | 增加前目标库位库存 |
| 调拨后目标库存 | 增加后目标库位库存 |
| 调拨备注 | 备注 |
| 操作人 | UserID |
| 操作时间 | 调拨时间 |
查询接口建议:
```js
var Data = this.CreateData('11', '仓储管理_库存盘点_库存调拨记录_查询', param, this.pageSize, this.pageCurrent)
```
第一版可以不新增独立页面,只在库存盘点页面增加“调拨记录”按钮或弹窗。
## 8. API 设计
### 8.1 查询库位
沿用现有:
```js
var Data = this.CreateData('11', '仓储管理_库位_查询', param)
```
### 8.2 新增库位
建议新增或复用:
```js
var Data = this.CreateData('12', '仓储管理_库位_增加', param)
```
参数:
| 参数名 | 说明 |
| --- | --- |
| 货位名称 | 新库位名称 |
| 备注 | 可选 |
| UserID | 当前用户 |
返回:
| 字段 | 说明 |
| --- | --- |
| result | 是否成功 |
| 货位流水号 | 新增库位流水号 |
| 货位名称 | 新增库位名称 |
### 8.3 库存调拨
建议新增:
```js
var Data = this.CreateData('12', '仓储管理_库存盘点_库存调拨', param)
```
这是本功能最核心接口,必须由后端事务保证扣减和增加同时成功或同时失败。
### 8.4 调拨记录查询
建议新增:
```js
var Data = this.CreateData('11', '仓储管理_库存盘点_库存调拨记录_查询', param, this.pageSize, this.pageCurrent)
```
查询参数:
| 参数名 | 说明 |
| --- | --- |
| 物料名称_check | 是否按物料名称查询 |
| 物料名称 | 物料名称 |
| 图号或型号_check | 是否按图号查询 |
| 图号或型号 | 图号或型号 |
| 原货位流水号_check | 是否按原库位查询 |
| 原货位流水号 | 原库位 |
| 目标货位流水号_check | 是否按目标库位查询 |
| 目标货位流水号 | 目标库位 |
| 操作时间_check | 是否按时间查询 |
| 开始时间 | 开始时间 |
| 结束时间 | 结束时间 |
## 9. 前端方法设计
### 9.1 打开调拨弹窗
```js
openTransfer(row) {
if (Number(row.库存) <= 0) {
this.$message.warning('当前库位库存为0不能调拨')
return
}
this.transferForm.物料与货位流水号 = row.物料与货位流水号
this.transferForm.物料流水号 = row.物料流水号
this.transferForm.物料名称 = row.物料名称
this.transferForm.图号或型号 = row.图号或型号
this.transferForm.原货位流水号 = row.货位流水号
this.transferForm.原货位名称 = row.货位名称
this.transferForm.原库存数 = Number(row.库存)
this.transferForm.目标货位流水号 = ''
this.transferForm.目标货位名称 = ''
this.transferForm.新货位名称 = ''
this.transferForm.调拨数量 = 1
this.transferForm.调拨备注 = ''
this.transferDialogVisible = true
}
```
### 9.2 新建库位
```js
addTransferLocation() {
if (!this.transferForm.新货位名称) {
this.$message.warning('请输入新库位名称')
return
}
var param = []
param[0] = ['货位名称', this.transferForm.新货位名称]
var Data = this.CreateData('12', '仓储管理_库位_增加', param)
this.ExecDatabase(Data).then(response => {
if (response.data && response.data.length > 0) {
this.getStorageLocation()
this.transferForm.目标货位流水号 = response.data[0].货位流水号
this.$message.success('库位新增成功')
}
})
}
```
说明:具体返回结构以现有后端为准,若只返回成功标识,则新增后通过库位名称重新查询并回填。
### 9.3 提交调拨
```js
submitTransfer() {
if (!this.transferForm.目标货位流水号) {
this.$message.warning('请选择目标库位')
return
}
if (this.transferForm.目标货位流水号 === this.transferForm.原货位流水号) {
this.$message.warning('目标库位不能与原库位相同')
return
}
if (Number(this.transferForm.调拨数量) <= 0) {
this.$message.warning('调拨数量必须大于0')
return
}
if (Number(this.transferForm.调拨数量) > Number(this.transferForm.原库存数)) {
this.$message.warning('调拨数量不能大于原库存数')
return
}
var param = []
param[0] = ['物料与货位流水号', this.transferForm.物料与货位流水号]
param[1] = ['物料流水号', this.transferForm.物料流水号]
param[2] = ['原货位流水号', this.transferForm.原货位流水号]
param[3] = ['目标货位流水号', this.transferForm.目标货位流水号]
param[4] = ['调拨数量', this.transferForm.调拨数量]
param[5] = ['原库存数', this.transferForm.原库存数]
param[6] = ['调拨备注', this.transferForm.调拨备注]
var Data = this.CreateData('12', '仓储管理_库存盘点_库存调拨', param)
this.ExecDatabase(Data).then(response => {
this.$message.success('调拨成功')
this.transferDialogVisible = false
this.searchTable()
})
}
```
## 10. 后端事务逻辑
后端存储过程建议逻辑:
```text
开始事务
查询原物料货位库存记录
如果不存在,返回“原库存记录不存在”
如果当前库存 < 调拨数量,返回“库存不足”
如果原货位流水号 = 目标货位流水号,返回“目标库位不能与原库位相同”
更新原库位库存 = 当前库存 - 调拨数量
查询目标货位是否存在同物料库存记录
如果存在:
更新目标库位库存 = 当前目标库存 + 调拨数量
如果不存在:
新增目标货位库存记录,库存 = 调拨数量
写入库存调拨记录
提交事务
```
任何一步失败必须回滚,避免库存只扣不加。
## 11. 与现有编辑库存功能的关系
当前库存盘点页面已有“编辑库存数”和“编辑库位”的能力:
```js
var Data = this.CreateData('12', '仓储管理_库存盘点_货位数量_编辑数据', param)
```
新调拨功能不建议复用前端两次调用该接口来完成扣减和增加,因为:
- 两次请求中间失败会造成库存不一致。
- 多人并发时容易出现负库存。
- 目标库位不存在同物料记录时还需要新增记录。
因此建议新增一个后端原子接口:
```text
仓储管理_库存盘点_库存调拨
```
该接口内部统一完成扣减、增加、新增目标记录、写调拨记录。
## 12. 实施步骤
1. 后端新增或确认库位新增接口:`仓储管理_库位_增加`
2. 后端新增库存调拨接口:`仓储管理_库存盘点_库存调拨`
3. 后端新增库存调拨记录表。
4. 后端新增库存调拨记录查询接口。
5. 前端 `InventoryCheck/index.vue` 增加“调拨”按钮。
6. 前端增加调拨弹窗和 `transferForm`
7. 前端增加“一键新建库位”方法。
8. 前端增加“确定调拨”方法。
9. 调拨成功后调用 `searchTable()` 刷新盘点列表。
10. 联调库存扣减、目标库位增加、目标库位不存在时新增记录。
## 13. 风险点
### 13.1 并发扣减风险
盘点期间多人可能同时调拨同一库位库存。后端必须以数据库当前库存为准,不能只相信前端传入的 `原库存数`
### 13.2 目标库位重复风险
一键新建库位时需要校验 `货位名称` 是否已存在。若已存在,应直接提示或返回已有库位,不应重复新增同名库位。
### 13.3 只扣不加风险
调拨不能由前端拆成“编辑原库存”和“新增目标库存”两个独立请求。必须由一个后端事务接口完成。
### 13.4 数据追溯风险
虽然不做完整调拨单,也必须保留调拨记录,记录调拨前后库存、原库位、目标库位、操作人和时间。
## 14. 总结
本方案将库存调拨限定在库存盘点组件内,采用“行内调拨弹窗 + 一键新建库位 + 后端事务扣减/增加库存”的轻量设计。用户在盘点时选择一行库存,输入调拨数量和目标库位,系统直接将调拨数量从原库位库存中减掉,并增加到目标库位库存中。
关键点是新增一个原子后端接口 `仓储管理_库存盘点_库存调拨`,避免前端多次请求造成库存不一致。同时保留调拨记录,满足后续盘点追溯。