8.6 KiB
8.6 KiB
质检物料库 · 编辑弹窗数量修正设计
日期: 2026-07-07
状态: 已实现
父模块: 质量检测 → 质检物料库(/#/quality-group/quality-base/qc-material)
关联文档:2026-06-11-qc-material-batch-inbound-design.md
1. 背景与目标
问题
编辑入库批次弹窗中,入库数量(in_qty)与剩余数量(remaining_qty)为只读,入库时若填错数量无法事后修正,导致批次余额与物资汇总库存(stock_qty)不准确。
目标(用户确认:场景 C — 两种都要支持)
| 场景 | 说明 | 典型操作 |
|---|---|---|
| A. 入库录入错误 | 初始入库量填错,出库/废弃/任务扣减记录本身正确 | 修正 in_qty,剩余按公式联动 |
| B. 账实不符 | 入库量无误,实物盘点或发现剩余与账面不一致 | 直接修正 remaining_qty,写库存调整流水 |
非目标
- 修改历史出库 / 废弃 / 任务扣减流水(审计记录不可篡改)
- 回溯修改已完成盘点单中的快照行
- 同步改造生产物料库、细胞存储物料库(本 spec 仅覆盖质检物料库;后续可复用模式)
2. 数据不变量
2.1 批次级
已出库总量(out_total) = Σ |change_qty|
WHERE batch_id = 当前批次
AND del_flag = 0
AND change_type IN ('use', 'discard')
理论剩余(theoretical_remaining) = in_qty − out_total
恒等式(正常状态下):
0 ≤ remaining_qty ≤ in_qtyremaining_qty = theoretical_remaining(无独立调整时)
2.2 物资汇总
material.stock_qty = Σ batch.remaining_qty(同 material_id、del_flag=0)
2.3 流水职责
| 类型 | change_type | source_type | 是否随编辑修改 |
|---|---|---|---|
| 入库 | in |
manual_in |
是 — 同步 change_qty、amount 快照 |
| 出库 | use |
manual_out 等 |
否 |
| 废弃 | discard |
manual_discard |
否 |
| 库存调整(新增) | adjust |
batch_qty_edit |
新增 — 仅当剩余与理论值不一致时 |
3. 业务规则
3.1 编辑弹窗字段
| 字段 | 可编辑 | 说明 |
|---|---|---|
入库数量 inQty |
✅ | el-input-number,min > 0,精度与入库一致(4 位小数) |
剩余数量 remainingQty |
✅ | 同上;可与理论值不同(场景 B) |
| 已出库总量 | 只读展示 | 打开弹窗时由后端返回或前端根据查看数据展示 |
| 理论剩余 | 只读展示 | inQty − outTotal;用户改 inQty 时前端实时重算 |
UI 提示(有出库时):
该批次已出库/废弃共 {outTotal} {unit}。修改入库数量后,若剩余数量未手工改动,将自动调整为 {theoreticalRemaining}。
UI 提示(剩余与理论值不一致时):
剩余数量与「入库数量 − 已出库」不一致,保存后将写入一条库存调整记录。
3.2 前端联动逻辑
- 打开编辑弹窗:请求批次详情(含
outTotal),或列表行扩展字段outTotal。 - 用户修改
inQty:- 若用户未手工改过
remainingQty(remainingQtyTouched = false)→remainingQty = inQty − outTotal - 若
remainingQtyTouched = true→ 不自动覆盖剩余(支持场景 B)
- 若用户未手工改过
- 用户修改
remainingQty→ 设remainingQtyTouched = true - 改
inQty且未锁定金额时 → 重算amount = unitPrice × inQty(与入库弹窗一致) - 提交前校验:
inQty > 0remainingQty ≥ 0remainingQty ≤ inQtyinQty ≥ outTotal(入库量不能小于已出库总量)
3.3 后端 update_batch 扩展(已实现:保留原入库 + adjust 流水)
- 原入库流水(
change_type=in):不修改change_qty、amount,仅同步编号/批号等元数据快照。 - 入库数量变化:写入
adjust流水,change_qty = 新入库量 − 旧入库量,备注编辑修正入库数量(旧 → 新)。 - 剩余数量在入库修正之外另有差异:再写入一条
adjust,change_qty = 新剩余 − (旧剩余 + 入库量差),备注编辑修正剩余数量。 - 出库/废弃/任务流水:仍不修改。
3.4 出库流水 — 明确不改
以下记录 只读、不 UPDATE:
change_type = use(含manual_out、task_complete、outbound_handover)change_type = discard
理由:反映真实领用/废弃/任务消耗,修正入库错误不应篡改历史操作。
3.5 边界情况
| 情况 | 处理 |
|---|---|
无出库记录(out_total = 0) |
改 in_qty 时默认 remaining = in_qty;两字段可联动 |
有出库,in_qty 从 100 改为 1000,剩余未手工改 |
remaining 自动 970(已出 30) |
有出库,仅改 remaining(in_qty 不变) |
写 adjust 流水,差值进 material.stock_qty |
in_qty 改小到小于 out_total |
拒绝,400:「入库数量不能小于已出库量 {out_total}」 |
remaining 改负或大于 in_qty |
拒绝,400 |
| 批次已删除 / 物资已停用 | 沿用现网校验 |
4. API 变更
4.1 批次详情(可选,推荐)
GET /api/admin/web/admin/qc-material-batches/{batchId}
Response 在现有字段上增加:
outTotal: number // 已出库+废弃总量
outCount: number // 出库/废弃流水条数(用于 UI 提示)
若暂不增详情接口,可在 list_batches 每行附带 outTotal(编辑时从列表行读取);有性能顾虑时优先详情接口。
4.2 更新批次
PUT /api/admin/web/admin/qc-material-batches/{batchId}
Body 新增可选字段:
inQty: number
remainingQty: number
QcMaterialBatchUpdateBody 增加上述两字段。
4.3 变动记录列表
change_type=adjust纳入筛选(变动类型下拉新增「库存调整」,value=adjust)_row_to_dict/ 前端展示:adjust→ Tagwarning,文案「库存调整」;source_type=batch_qty_edit→ 「批次数量修正」
5. 前端改造
5.1 文件
| 文件 | 改动 |
|---|---|
web-admin/src/views/quality-inspection/qc-material/index.vue |
编辑弹窗:inQty/remainingQty 可编辑;只读展示已出库/理论剩余;联动与校验;提交 payload |
web-admin/src/api/qc-material.ts |
类型与 update 入参增加字段;可选 fetchBatchDetail |
web-admin/src/views/quality-inspection/qc-material/QcMaterialUsageTab.vue |
变动类型筛选项 + 展示文案 |
5.2 编辑弹窗布局(在现有 form-grid-3 内)
入库数量 [input-number] 剩余数量 [input-number] 已出库总量 [只读]
理论剩余 [只读,inQty−outTotal] (有差异时 el-alert 提示将写调整流水)
- 数量控件样式与入库弹窗
input-number一致 form-label-tip:「已出库总量含手动出库、废弃及任务扣减(若启用)」
5.3 查看弹窗
- 批次基础信息仍展示修正后的
inQty/remainingQty - 出库明细列表不变;若存在 adjust 流水,可在「变动记录」Tab 中查看
6. 后端改造
| 文件 | 改动 |
|---|---|
backend/app/crud/qc_material_stock_batch.py |
update_batch 数量修正逻辑;_sum_batch_out_total() helper |
backend/app/api/qc.py |
QcMaterialBatchUpdateBody 增字段;可选 GET batch detail |
backend/app/crud/qc_material_usage.py |
list_usages 支持 change_type=adjust 筛选;_row_to_dict 展示 |
无需新增数据库表;change_type / source_type 为 varchar,新枚举值直接写入。
7. 测试要点
- 场景 A:入库 100,无出库 → 改 in 为 1000 → remaining=1000,stock_qty +900,入库流水 change_qty=1000,无 adjust 流水
- 场景 A+出库:入库 100,出库 30 → 改 in 为 1000 → remaining=970,stock_qty +900,出库 3 条不变
- 场景 B:in 保持 100,出库 30,remaining 从 70 改为 65 → stock_qty −5,新增 adjust 流水 change_qty=−5
- 校验:in 改为 20(已出 30)→ 失败
- 校验:remaining 改为 101(in=100)→ 失败
- 仅改厂家/批号:数量不变,无 adjust、无 stock_qty 变化
- 变动记录 Tab:adjust 类型可筛选、Tag 展示正确
8. 与盘点的关系
- 库存盘点 Tab 仍用于周期性盘点、登记未用完物料;本能力用于单批次事后纠错,二者互补。
- 已完成盘点单中的
remaining_qty快照不回溯修改。
9. 后续扩展(本 spec 不做)
- 生产物料库 / 细胞存储物料库复用同一模式
- 数量修正权限细分(如仅库管可改剩余量)