提交
This commit is contained in:
1 parent
e1d6de45a3
commit
5ad07c8cac
616 files changed
+181132
-35125
No files matched your search
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-06-13
|
||||
@@ -0,0 +1,110 @@
|
||||
## Context
|
||||
|
||||
生产物料库(`biz_production_material*`)已对齐质检物料库:试剂/耗材统一目录、批次、领用(`manual_out`)、工单 `step_save`(`parent_usage_id`)、盘点。用户确认 **方案 A**:配置试剂配制完成后 **先入库存**,工单使用前 **再领用**,步骤登记 **不二次扣库**。
|
||||
|
||||
已废弃的 `biz_consumable_pack` 仅为耗材模板,无配制实例与子物料领用追溯,不可复用。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 第三类物料 `material_type=configured_reagent`,目录 + BOM(试剂+耗材子项)
|
||||
- 配制单:记录每次配制实际消耗的子物料领用行;产出配置试剂批次
|
||||
- 配置试剂走完整 **批次 → 领用 → 工单 step_save** 链路
|
||||
- UI 落在【生产物料库】与【生产工单】执行态,风格对齐 Fresh Mint / QC 物料库
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不合并质检物料库
|
||||
- 不恢复耗材包
|
||||
- 工艺库/工艺路线步骤引用配置试剂 BOM(二期)
|
||||
- 配制现场「直用不入库」模式(方案 B/C)
|
||||
- 盘点首版对配置试剂做特殊调账逻辑(沿用现有 Part A/B,不调账)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: 扩展 material_type,不另建独立库存域
|
||||
|
||||
**选择**:`configured_reagent` 作为 `biz_production_material.material_type` 第三值;批次/领用/盘点 **复用** 现有表与 CRUD 模式。
|
||||
|
||||
**理由**:与用户已接受的试剂/耗材统一库一致;避免第二套 batch/usage API。
|
||||
|
||||
**替代**:独立 `biz_configured_reagent*` 表系 — 拒绝,重复建设。
|
||||
|
||||
### Decision 2: 配方与配制分离
|
||||
|
||||
| 实体 | 表 | 含义 |
|
||||
|------|-----|------|
|
||||
| 配方 BOM | `biz_production_material_formula` | 主数据:标准子物料与标准用量 |
|
||||
| 配制单 | `biz_production_material_prep` + `_prep_line` | 业务单据:某次实际配制 |
|
||||
|
||||
**理由**:BOM 可版本化维护;配制单保留历史追溯(哪次用了哪些领用记录)。
|
||||
|
||||
配制单头关键字段:`configured_material_id`、`prep_no`、`prep_time`、`output_qty`、`output_unit`、`batch_no`、`expire_date`、`stock_in_no`(产出批次)、`status`(draft/completed/cancelled)。
|
||||
|
||||
配制行关键字段:`component_material_id`、`component_material_type`、`component_material_code`、`requisition_usage_id`(parent 领用记录)、`actual_qty`、`usage_unit`。
|
||||
|
||||
### Decision 3: 库存流水 source_type
|
||||
|
||||
| 环节 | change_type | source_type | 库存影响 |
|
||||
|------|-------------|-------------|----------|
|
||||
| 子物料配制消耗 | use | `prep_consume` | 子物料 **不扣** batch;`stock_before==stock_after`;`parent_usage_id` 指向领用记录 |
|
||||
| 配置试剂配制入库 | in | `prep_in` | 配置试剂 catalog `stock_qty` ↑;新建/更新 batch `remaining_qty` |
|
||||
| 配置试剂领用 | use | `manual_out` | 按 batch 扣减(与现网一致) |
|
||||
| 工单步骤登记 | use | `step_save` | 不扣库存;`parent_usage_id` 指向领用记录 |
|
||||
|
||||
**理由**:与 `production-material-requisition` Decision 5 一致;子物料已在领用时扣过 batch。
|
||||
|
||||
### Decision 4: 配制完成事务边界
|
||||
|
||||
单次「确认配制」在一个 DB 事务内:
|
||||
|
||||
1. 校验每行 `requisition_usage_id` 有效、未重复、领用人为当前用户或允许范围
|
||||
2. 写入 `prep` + `prep_line`
|
||||
3. 对每个 prep_line 写 `prep_consume` usage
|
||||
4. 创建配置试剂 `stock_batch` + `prep_in` usage
|
||||
5. 更新配置试剂 `stock_qty`
|
||||
|
||||
失败则整体回滚。
|
||||
|
||||
### Decision 5: 生产工单步骤 UI
|
||||
|
||||
**选择**:新增 **`biz_production_task_step_configured_reagent`** 子表(或等价命名),工单执行态增加 **「配置试剂」Tab**;领用下拉 `GET /production-material-requisition-options?materialType=configured_reagent`。
|
||||
|
||||
**理由**:与保留「试剂」「耗材」分列一致;避免塞入 reagent Tab 造成类型混淆。
|
||||
|
||||
保存仍调用统一 `register_step_usage_from_requisition`;目录内配置试剂 **有实际用量时必须选领用记录**。
|
||||
|
||||
### Decision 6: 编码唯一性
|
||||
|
||||
沿用 **租户 + material_type + material_code**;允许配置试剂编码与试剂/耗材编码相同(类型不同)。
|
||||
|
||||
### Decision 7: 偏离 BOM
|
||||
|
||||
配制时允许调整 **实际用量**;子物料行 **必须** 选领用记录。标准用量自 BOM 带出,仅作参考。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| 领用余量与子物料配制量不一致 | 首版仅记录 `prep_consume` 关联领用,不强制核销领用余额字段;二期可加「领用已配制量」汇总 |
|
||||
| 配置试剂批次过期日规则不清 | 配制单必填 `expire_date` |
|
||||
| 成本单价 | 首版 `unit_price`/`amount` 可按子物料 `prep_consume` 金额汇总写入产出 batch |
|
||||
| 步骤子表增多 | 配置试剂 Tab 独立;工艺模板引用二期再做 |
|
||||
| 与未完成 production-material-requisition 依赖 | tasks 注明前置:统一物料库迁移已执行 |
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. DDL:formula、prep、prep_line;字典项 `configured_reagent`;step 子表(若新建)
|
||||
2. 部署后端 API + 前端
|
||||
3. 无历史数据迁移(新能力);旧耗材包保持废弃
|
||||
|
||||
回滚:隐藏菜单与 API;新表保留不删(软兼容)。
|
||||
|
||||
## Open Questions
|
||||
|
||||
| # | 问题 | 默认 |
|
||||
|---|------|------|
|
||||
| Q1 | 配制单是否独立菜单 vs 物料库 Tab | **物料库第四 Tab「配制单」** |
|
||||
| Q2 | prep_no 生成规则 | 租户内按日序号,如 `PZ-YYYYMMDD-NNN` |
|
||||
| Q3 | 取消配制单是否回滚库存 | 首版仅 draft 可删;completed 不可撤销 |
|
||||
@@ -0,0 +1,52 @@
|
||||
## Why
|
||||
|
||||
生产侧已统一为【生产物料库】(试剂 + 耗材 + 批次 + 领用 + 工单登记)。业务上还存在 **「配置试剂」**:由多个原试剂与耗材按配方配制而成,需 **追溯每次配制用了哪些子物料**,且配制产物 **先入库存、再领用、再在生产工单步骤中登记消耗**(方案 A,用户已确认)。这与已废弃的「耗材包」(仅模板、无配制实例与库存)不同,需在统一物料库上扩展第三类物料,而非恢复耗材包。
|
||||
|
||||
## What Changes
|
||||
|
||||
### 配置试剂主数据与配方(BOM)
|
||||
|
||||
- `biz_production_material.material_type` 新增 **`configured_reagent`**(配置试剂)
|
||||
- 数据字典 `production_material_type` 新增「配置试剂」
|
||||
- 新建 **`biz_production_material_formula`**:配置试剂 → 子物料(`reagent` / `consumable`)+ 标准用量 + 单位
|
||||
- 生产物料库支持按类型筛选、维护配置试剂目录及配方子表
|
||||
|
||||
### 配制单与批次入库(方案 A)
|
||||
|
||||
- 新建 **`biz_production_material_prep`**(配制单头)+ **`biz_production_material_prep_line`**(子物料实际消耗行)
|
||||
- 配制时:每行子物料 **必须** 关联已有 **领用记录**(`parent_usage_id`),记 `prep_consume` 流水(**不二次扣** 子物料 batch 库存)
|
||||
- 配制完成:配置试剂 **批次入库**(`biz_production_material_stock_batch` + `prep_in` 流水),`stock_qty` / `remaining_qty` 增加
|
||||
- 支持查看配制单详情及子物料追溯
|
||||
|
||||
### 领用与生产工单
|
||||
|
||||
- 配置试剂与试剂/耗材相同:**manual_out 领用** → 工单步骤选领用记录 → **step_save**(`parent_usage_id`,不二次扣库)
|
||||
- 生产工单步骤新增 **「配置试剂」Tab**(或等价独立子表),领用选项 API 增加 `materialType=configured_reagent`
|
||||
- 【我的物料领用记录】支持配置试剂类型筛选与展示
|
||||
|
||||
### 与现网关系
|
||||
|
||||
- **复用** `biz_production_material*` 批次、领用、盘点、usage 流水体系
|
||||
- **不恢复** 耗材包;工艺库引用配置试剂 BOM 为 **二期**(本期 Non-Goal)
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `configured-reagent-catalog`: 配置试剂目录、material_type、字典、配方 BOM CRUD
|
||||
- `configured-reagent-prep`: 配制单、子物料领用关联、prep_consume / prep_in 库存流水
|
||||
- `configured-reagent-work-order-usage`: 配置试剂领用、工单步骤登记、我的领用记录扩展
|
||||
- `configured-reagent-ui`: 生产物料库配方编辑、配制单 UI、工单配置试剂 Tab
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `production-material-library`: material_type 扩展 `configured_reagent`;筛选与 Tag 展示
|
||||
- `production-requisition-stock-log`: 领用选项与流水 source_type 扩展 `prep_consume` / `prep_in`
|
||||
- `production-step-requisition-usage`: 步骤子表与 API 支持配置试剂领用登记
|
||||
|
||||
## Impact
|
||||
|
||||
- **数据库**:2 张新表(formula、prep + prep_line);字典项;`production_material_usage.source_type` 语义扩展;可选 step 子表 `biz_production_task_step_configured_reagent` 或扩展现有结构
|
||||
- **后端**:`models/crud/api` 扩展 `production_material*`;新 prep 路由;`register_step_usage_from_requisition` 支持 configured_reagent
|
||||
- **前端**:`production-material` 页扩展类型与配方弹窗;新配制单 Tab/页;`StepDetailPanel` 配置试剂 Tab;`status-tag-registry` 新类型
|
||||
- **依赖**:`production-material-requisition` 变更应已落地(统一物料库 + 领用 + step_save)
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Configured reagent material type
|
||||
系统 SHALL 在 `biz_production_material.material_type` 支持第三值 **`configured_reagent`**(配置试剂)。
|
||||
|
||||
数据字典 `production_material_type` SHALL 新增字典项:标签「配置试剂」,值 `configured_reagent`。
|
||||
|
||||
唯一约束不变:**租户 + material_type + material_code**(del_flag=0)。
|
||||
|
||||
#### Scenario: Create configured reagent catalog
|
||||
- **WHEN** 用户新增物料,material_type=configured_reagent,material_code=CR001
|
||||
- **THEN** 写入 biz_production_material,stock_qty 初始为 0
|
||||
|
||||
#### Scenario: Same code different type
|
||||
- **WHEN** 已存在 reagent 编码 R001,再新增 configured_reagent 编码 R001
|
||||
- **THEN** 允许创建(material_type 不同)
|
||||
|
||||
### Requirement: Configured reagent catalog fields
|
||||
配置试剂目录行 SHALL 含:`material_code`、`material_name`、`spec_model`(可选)、`unit`(产出单位,如 mL)、`warning_qty`、`status` 及公共字段。
|
||||
|
||||
配置试剂 **无** 直接入库操作(不经由普通 manual_in 录入原子物料批次);其批次 **仅** 通过配制单 `prep_in` 产生(见 configured-reagent-prep)。
|
||||
|
||||
#### Scenario: No direct batch in for configured reagent via generic stock-in
|
||||
- **WHEN** 用户对 material_type=configured_reagent 的物料执行普通批次入库(非配制单)
|
||||
- **THEN** API 返回 400 并提示须通过「配制单」入库
|
||||
|
||||
### Requirement: Material type tag on library UI
|
||||
生产物料库列表与详情 SHALL 对 `configured_reagent` 展示 Tag「配置试剂」(`status-tag-registry` 或等价注册)。
|
||||
|
||||
#### Scenario: Library filter configured reagent
|
||||
- **WHEN** 用户在生产物料库筛选物料类型为「配置试剂」
|
||||
- **THEN** 仅展示 material_type=configured_reagent 的目录行
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Formula BOM table
|
||||
系统 SHALL 新建 `biz_production_material_formula`(配方行),关联 `configured_material_id` → `biz_production_material.id`(material_type 必须为 configured_reagent)。
|
||||
|
||||
每行 SHALL 含:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `component_material_id` | 子物料目录 ID |
|
||||
| `component_material_type` | `reagent` 或 `consumable` 快照 |
|
||||
| `component_material_code` | 子物料编码快照 |
|
||||
| `component_material_name` | 子物料名称快照 |
|
||||
| `standard_qty` | 标准用量(数值) |
|
||||
| `usage_unit` | 单位 |
|
||||
| `order_num` | 排序 |
|
||||
| 公共字段 | id、tenant_no、del_flag 等 |
|
||||
|
||||
子物料 **不得** 为 `configured_reagent`(禁止嵌套配方,首版)。
|
||||
|
||||
#### Scenario: Add formula line with reagent and consumable
|
||||
- **WHEN** 用户为配置试剂 CR-培养基 添加配方:试剂 A 10mL + 耗材 B 2 个
|
||||
- **THEN** 写入两行 formula,component_material_type 分别为 reagent、consumable
|
||||
|
||||
#### Scenario: Reject nested configured reagent in formula
|
||||
- **WHEN** 用户尝试将另一配置试剂加入配方
|
||||
- **THEN** API 返回 400,提示子物料仅允许试剂或耗材
|
||||
|
||||
### Requirement: Formula CRUD API
|
||||
系统 SHALL 提供:
|
||||
|
||||
- `GET /production-materials/{id}/formula` — 查询配方列表
|
||||
- `PUT /production-materials/{id}/formula` — 全量替换配方行(软删旧行 + 插入新行,与工艺子表策略一致)
|
||||
|
||||
创建/更新配置试剂目录时 **可** 携带 formula 列表一并保存。
|
||||
|
||||
#### Scenario: Replace formula on edit
|
||||
- **WHEN** 用户编辑配置试剂并修改配方行数量
|
||||
- **THEN** 旧 formula 行 del_flag=1,新行写入且 order_num 连续
|
||||
@@ -0,0 +1,65 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Prep order tables
|
||||
系统 SHALL 新建:
|
||||
|
||||
- `biz_production_material_prep` — 配制单头
|
||||
- `biz_production_material_prep_line` — 配制明细(子物料实际消耗)
|
||||
|
||||
配制单头 SHALL 含:`prep_no`、`configured_material_id`、`prep_time`、`output_qty`、`output_unit`、`batch_no`、`expire_date`、`stock_in_no`(产出入库编号)、`status`(draft/completed/cancelled)、`remark` 及公共字段。
|
||||
|
||||
配制行 SHALL 含:`prep_id`、`component_material_id`、`component_material_type`、`requisition_usage_id`(关联 biz_production_material_usage 领用记录 id)、`actual_qty`、`usage_unit`、`remark` 及公共字段。
|
||||
|
||||
#### Scenario: Create draft prep from BOM
|
||||
- **WHEN** 用户基于配置试剂 CR001 创建配制单,系统带出 BOM 子行
|
||||
- **THEN** prep 状态为 draft,prep_line 含 component 信息与标准用量参考
|
||||
|
||||
### Requirement: Prep line must link requisition
|
||||
配制确认(completed)时,每个 prep_line SHALL 提供非空 `requisition_usage_id`,且该记录须为对应子物料的 **manual_out** 领用、同一 tenant、del_flag=0。
|
||||
|
||||
同一配制单内 `requisition_usage_id` **不得** 重复。
|
||||
|
||||
#### Scenario: Reject prep without requisition
|
||||
- **WHEN** 用户确认配制但某子物料行未选领用记录
|
||||
- **THEN** API 返回 400,提示须选择领用记录
|
||||
|
||||
#### Scenario: Reject duplicate requisition in one prep
|
||||
- **WHEN** 同一配制单两行选用相同 requisition_usage_id
|
||||
- **THEN** API 返回 400
|
||||
|
||||
### Requirement: Prep complete stock transaction
|
||||
确认配制 SHALL 在单事务内:
|
||||
|
||||
1. 对每个 prep_line 写入 `biz_production_material_usage`:`change_type=use`,`source_type=prep_consume`,`parent_usage_id=requisition_usage_id`,**不减少**子物料 batch/catalog 库存(stock_before 等于 stock_after)
|
||||
2. 创建配置试剂 `biz_production_material_stock_batch`(in_qty=remaining_qty=output_qty)
|
||||
3. 写入配置试剂 `prep_in` usage(change_type=in,增加 catalog stock_qty 与 batch remaining_qty)
|
||||
4. 将 prep.status 置为 completed
|
||||
|
||||
#### Scenario: Prep consume does not deduct component batch again
|
||||
- **WHEN** 用户确认配制,子物料领用记录关联 batch 剩余 50
|
||||
- **THEN** 子物料 batch remaining_qty 仍为 50,但新增 prep_consume 流水关联 parent_usage_id
|
||||
|
||||
#### Scenario: Prep in increases configured reagent stock
|
||||
- **WHEN** 用户确认配制产出 100mL 配置试剂
|
||||
- **THEN** 配置试剂 stock_qty 增加 100,且存在对应 stock_batch 与 prep_in 流水
|
||||
|
||||
### Requirement: Prep list and detail API
|
||||
系统 SHALL 提供:
|
||||
|
||||
- `GET /production-material-preps` — 分页列表(可按 configured_material_id、status、时间筛选)
|
||||
- `GET /production-material-preps/{id}` — 详情含 prep_line 及子物料/领用快照
|
||||
- `POST /production-material-preps` — 创建(draft)
|
||||
- `PUT /production-material-preps/{id}` — 更新 draft
|
||||
- `POST /production-material-preps/{id}/complete` — 确认配制
|
||||
- `POST /production-material-preps/{id}/cancel` — 取消 draft
|
||||
|
||||
#### Scenario: Cannot complete twice
|
||||
- **WHEN** 配制单已 completed,再次调用 complete
|
||||
- **THEN** API 返回 400
|
||||
|
||||
### Requirement: Prep traceability in usage log
|
||||
变动记录 Tab SHALL 展示 `source_type` 为 `prep_consume`、`prep_in` 的流水;`prep_consume` 行 SHALL 可下钻到 parent 领用记录与配制单号。
|
||||
|
||||
#### Scenario: View prep consume in usage tab
|
||||
- **WHEN** 用户在生产物料库变动记录筛选来源类型 prep_consume
|
||||
- **THEN** 展示子物料消耗行,含配制单号与关联领用批号
|
||||
@@ -0,0 +1,54 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Production material library type filter extension
|
||||
【生产物料库】筛选区 SHALL 物料类型含:**全部 / 试剂 / 耗材 / 配置试剂**。
|
||||
|
||||
批次列表、变动记录、库存盘点 Tab 的 material_type 筛选 SHALL 同步支持 `configured_reagent`。
|
||||
|
||||
#### Scenario: Stock check filter configured reagent
|
||||
- **WHEN** 用户在库存盘点 Tab 筛选配置试剂
|
||||
- **THEN** Part A 快照仅含 material_type=configured_reagent 的批次行
|
||||
|
||||
### Requirement: Configured reagent edit dialog with formula
|
||||
新增/编辑配置试剂弹窗 SHALL 含目录字段 + **配方子表**(可增删子行:选择子物料 reagent/consumable、标准用量、单位)。
|
||||
|
||||
布局 SHALL 对齐现有 CRUD 弹窗(`dialog-form-layout`、`form-grid-2`、内嵌 `inner-table`)。
|
||||
|
||||
#### Scenario: Edit configured reagent with formula
|
||||
- **WHEN** 用户编辑配置试剂并添加一行配方耗材
|
||||
- **THEN** 保存后 formula API 持久化,列表可查看子物料数量摘要
|
||||
|
||||
### Requirement: Prep order UI tab
|
||||
【生产物料库】SHALL 新增第四 Tab **「配制单」**(或同级入口),含:
|
||||
|
||||
- 筛选:配置试剂、状态、时间
|
||||
- 列表:配制单号、配置试剂名称、产出数量、状态、配制时间
|
||||
- 操作:新建、编辑(draft)、确认配制、查看
|
||||
|
||||
配制单编辑弹窗 SHALL 含:配置试剂选择、产出数量/单位、批号、过期日、子物料表(领用记录下拉 + 实际用量)。
|
||||
|
||||
领用下拉 SHALL 调用 `fetchProductionMaterialRequisitionOptions`,按子行 component_material_type 过滤。
|
||||
|
||||
#### Scenario: Complete prep from UI
|
||||
- **WHEN** 用户填写所有子行领用记录并点击确认配制
|
||||
- **THEN** 调用 complete API,列表状态变为已完成,配置试剂库存增加
|
||||
|
||||
### Requirement: Work order step configured reagent tab
|
||||
`StepDetailPanel` 执行态 SHALL 新增 **「配置试剂」** Tab,交互对齐试剂 Tab:
|
||||
|
||||
- 列:编码、名称、规格、标准用量、**领用记录**(执行态)、实际用量、单位、备注
|
||||
- 领用下拉:`materialType=configured_reagent`
|
||||
- 保存携带 `requisition_usage_id`
|
||||
|
||||
按钮 SHALL 含 leading `el-icon`(项目 UI 规范)。
|
||||
|
||||
#### Scenario: Execution mode shows requisition column
|
||||
- **WHEN** 用户在生产工单执行态打开步骤配置试剂 Tab
|
||||
- **THEN** 展示领用记录下拉,选项仅含配置试剂领用
|
||||
|
||||
### Requirement: Pattern and reference pages
|
||||
新页面/Tab SHALL 引用界面模式 **P01**(列表)及生产物料库 / 质检物料库为参考;PR 须注明 pattern 与参考路径。
|
||||
|
||||
#### Scenario: New prep tab follows list pattern
|
||||
- **WHEN** 开发配制单 Tab
|
||||
- **THEN** 结构含 filter-block、list-toolbar、list-body、分页,与 `qc-material` 变动记录 Tab 同级规范
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Configured reagent manual requisition
|
||||
配置试剂批次 SHALL 支持与普通试剂相同的 **manual_out** 领用:按 batch 扣减 `remaining_qty` 与 catalog `stock_qty`,写入 `biz_production_material_usage`(source_type=manual_out)。
|
||||
|
||||
领用选项 API `GET /production-material-requisition-options` SHALL 支持 `materialType=configured_reagent`。
|
||||
|
||||
#### Scenario: Requisition options for configured reagent
|
||||
- **WHEN** 前端请求 materialType=configured_reagent
|
||||
- **THEN** 仅返回配置试剂的 manual_out 领用记录
|
||||
|
||||
### Requirement: Production task step configured reagent sub-table
|
||||
系统 SHALL 新建 `biz_production_task_step_configured_reagent`(或等价命名),字段对齐步骤试剂子表语义:
|
||||
|
||||
- `configured_reagent_code`、`configured_reagent_name`、`spec`、`standard_usage`、`actual_usage`、`unit`
|
||||
- **`requisition_usage_id`** — 执行态必填(有 actual_usage 且目录存在时)
|
||||
|
||||
工艺/步骤模板 **可** 预置配置试剂标准用量(二期工艺库扩展前,允许步骤内手工维护行)。
|
||||
|
||||
#### Scenario: Step save with requisition
|
||||
- **WHEN** 用户在工单步骤配置试剂 Tab 填写 actual_usage 并选择领用记录后保存
|
||||
- **THEN** 写入 step 子表行与 step_save usage(parent_usage_id),不二次扣库存
|
||||
|
||||
### Requirement: Step replace API
|
||||
系统 SHALL 提供:
|
||||
|
||||
- `PUT /production-tasks/{task_id}/steps/{step_id}/configured-reagents` — 全量替换步骤配置试剂行
|
||||
|
||||
请求体 SHALL 支持 `requisitionUsageId`(alias);服务端调用 `register_step_usage_from_requisition`。
|
||||
|
||||
目录内配置试剂有 actual_usage 时 **必须** 选领用记录(与试剂/耗材规则一致)。
|
||||
|
||||
#### Scenario: Reject step usage without requisition for catalog item
|
||||
- **WHEN** 步骤行 configured_reagent_code 对应目录存在且填写了 actual_usage 但未选领用
|
||||
- **THEN** API 返回 400
|
||||
|
||||
### Requirement: My material usage includes configured reagent
|
||||
【我的物料领用记录】SHALL 包含 material_type=configured_reagent 的 manual_out 与 step_save 行,Tag 展示「配置试剂」。
|
||||
|
||||
#### Scenario: Filter my usage by configured reagent
|
||||
- **WHEN** 用户筛选物料类型为配置试剂
|
||||
- **THEN** 仅展示 configured_reagent 相关流水
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Unified production material catalog
|
||||
系统 SHALL 新建 `biz_production_material` 作为生产侧 **唯一** 物资目录,字段对齐 `biz_qc_material`,并 **新增**:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `material_type` | 物料类型,**必填**;`reagent`(试剂)、`consumable`(耗材)或 **`configured_reagent`(配置试剂)** |
|
||||
|
||||
其他字段:`material_code`、`material_name`、`spec_model`、`unit`、`stock_qty`、`warning_qty`、`status` 及公共字段。
|
||||
|
||||
唯一约束:**租户 + material_type + material_code**(del_flag=0 维度)。
|
||||
|
||||
#### Scenario: Create reagent catalog entry
|
||||
- **WHEN** 用户新增物料,material_type=reagent,material_code=R001
|
||||
- **THEN** 写入 biz_production_material,stock_qty 初始 0
|
||||
|
||||
#### Scenario: Same code different type allowed
|
||||
- **WHEN** 已存在 consumable 编码 C001,再新增 reagent 编码 C001
|
||||
- **THEN** 允许创建(类型不同)
|
||||
|
||||
#### Scenario: Create configured reagent catalog entry
|
||||
- **WHEN** 用户新增物料,material_type=configured_reagent,material_code=CR001
|
||||
- **THEN** 写入 biz_production_material,stock_qty 初始 0
|
||||
|
||||
### Requirement: Material type dictionary
|
||||
`material_type` SHALL 注册数据字典 `production_material_type`(或等价 dict_type),前端 Tag 展示「试剂」「耗材」**及「配置试剂」**。
|
||||
|
||||
#### Scenario: List shows type tag
|
||||
- **WHEN** 用户查看生产物料库批次列表
|
||||
- **THEN** 每行展示 material_type 对应 Tag
|
||||
|
||||
### Requirement: Production material library menu and page
|
||||
系统 SHALL 提供 **单一** 管理入口:
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| 菜单名 | **生产物料库** |
|
||||
| 父菜单 | **【生产基础信息】**(`PRB00000000000000000000000000001`,**已确认**) |
|
||||
| 路由 | `production-material` → `/production/production-material/index` |
|
||||
| menuCode | `production:material:list` |
|
||||
|
||||
页面 SHALL 含 Tab:**批次列表 | 变动记录 | 库存盘点 | 配制单**(配制单见 configured-reagent-ui);前三个 Tab 布局参照 `qc-material/index.vue`。
|
||||
|
||||
筛选区 SHALL 含 **物料类型**(全部 / 试剂 / 耗材 / **配置试剂**)。
|
||||
|
||||
菜单注册 SHALL 同步 `sys_menu` 迁移脚本、`backend/app/api/menu.py`、`sqxp.ts`(挂在 `ProductionBase` 的 `children` 下,替代原耗材/试剂管理项)。
|
||||
|
||||
#### Scenario: Single library replaces dual menus
|
||||
- **WHEN** 用户打开生产物料库
|
||||
- **THEN** 可同时管理试剂、耗材与配置试剂,无需分别进入耗材管理、试剂管理
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Requisition options API
|
||||
系统 SHALL 提供:
|
||||
|
||||
```
|
||||
GET /api/admin/web/admin/production-material-requisition-options
|
||||
Query: materialType? (reagent|consumable|configured_reagent), keyword?, limit?
|
||||
```
|
||||
|
||||
返回 `source_type=manual_out` 记录,label 含批号/入库编号/领用人;**materialType** 过滤试剂、耗材或配置试剂。
|
||||
|
||||
#### Scenario: Reagent tab loads reagent requisitions only
|
||||
- **WHEN** 生产工单步骤试剂 Tab 请求 materialType=reagent
|
||||
- **THEN** 仅返回 material_type=reagent 的领用记录
|
||||
|
||||
#### Scenario: Consumable tab loads consumable requisitions only
|
||||
- **WHEN** 耗材 Tab 请求 materialType=consumable
|
||||
- **THEN** 仅返回耗材领用记录
|
||||
|
||||
#### Scenario: Configured reagent tab loads configured reagent requisitions only
|
||||
- **WHEN** 配置试剂 Tab 请求 materialType=configured_reagent
|
||||
- **THEN** 仅返回 material_type=configured_reagent 的领用记录
|
||||
|
||||
### Requirement: My production material requisition list API
|
||||
系统 SHALL 提供:
|
||||
|
||||
```
|
||||
GET /api/admin/web/admin/my-production-material-usages
|
||||
Query: materialType?, changeType?, keyword?, startTime?, endTime?, page, pageSize
|
||||
```
|
||||
|
||||
可见范围(与 QC 一致):
|
||||
|
||||
- manual_out:当前用户为 receiver
|
||||
- step_save、**prep_consume**(登记人 create_by):当前用户为 create_by
|
||||
|
||||
materialType 筛选 SHALL 支持 `configured_reagent`。
|
||||
|
||||
#### Scenario: Single my menu with type filter
|
||||
- **WHEN** 用户打开【我的物料领用记录】并筛选 materialType=consumable
|
||||
- **THEN** 仅展示耗材相关领用与步骤登记
|
||||
|
||||
#### Scenario: Filter configured reagent in my list
|
||||
- **WHEN** 用户筛选 materialType=configured_reagent
|
||||
- **THEN** 展示配置试剂领用与步骤登记流水
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Prep-related source types in usage log
|
||||
`biz_production_material_usage.source_type` SHALL 扩展支持:
|
||||
|
||||
- `prep_consume` — 配制消耗子物料(关联 parent_usage_id,不扣子物料库存)
|
||||
- `prep_in` — 配置试剂配制入库(change_type=in)
|
||||
|
||||
变动记录列表 SHALL 可筛选上述来源类型,并以 Tag 展示语义化标签。
|
||||
|
||||
#### Scenario: Usage tab shows prep_in
|
||||
- **WHEN** 用户完成配制单确认
|
||||
- **THEN** 变动记录出现 source_type=prep_in 的配置试剂入库行
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Step save registers consumption via requisition not direct deduction
|
||||
对于 **编码存在于** `biz_production_material` 目录中的步骤行(material_type 为 **reagent、consumable 或 configured_reagent**),系统 SHALL 要求提供有效 `requisitionUsageId`(指向 `source_type=manual_out` 的 usage 记录)。步骤保存时:
|
||||
|
||||
1. 写 `source_type=step_save` 变动记录
|
||||
2. 设置 `parent_usage_id = requisitionUsageId`
|
||||
3. **不修改** 对应物资 `stock_qty`(`stock_before` SHALL 等于 `stock_after`)
|
||||
4. `change_qty` SHALL 为负数,绝对值等于 `actual_usage` 解析后的有效用量
|
||||
|
||||
#### Scenario: First save with requisition linked
|
||||
- **WHEN** 用户保存步骤,耗材 A(目录内)关联领用记录 R(曾出库 10),actual_usage=2
|
||||
- **THEN** 耗材 A 的 stock_qty 不变,生成 1 条 step_save 记录(change_qty=-2,parent_usage_id=R)
|
||||
|
||||
#### Scenario: Configured reagent step save
|
||||
- **WHEN** 用户保存步骤,配置试剂 CR001 关联领用记录 R,actual_usage=5
|
||||
- **THEN** 配置试剂 stock_qty 不变,生成 step_save 记录(parent_usage_id=R)
|
||||
|
||||
#### Scenario: Save without requisition for catalog material
|
||||
- **WHEN** 用户保存步骤,试剂 B 编码存在于目录,但未选 requisitionUsageId
|
||||
- **THEN** 整个步骤保存回滚,提示「请选择领用记录」
|
||||
|
||||
### Requirement: Requisition record validation on step save
|
||||
保存步骤时,对每个需关联领用的行,系统 SHALL 校验:
|
||||
|
||||
1. `requisitionUsageId` 对应记录存在、未删除、`source_type=manual_out`
|
||||
2. 领用记录的 `material_id` 与步骤行所选物料(按 **material_type + 编码** 匹配 `biz_production_material`)一致
|
||||
3. 领用记录 **SHALL** 含有效 `batch_id`;步骤登记继承 parent 的批号/入库编号快照
|
||||
4. 同一步骤列表内 `requisitionUsageId` 不可重复(**同一 Tab 内**;试剂/耗材/配置试剂各 Tab 独立校验,跨 Tab 可不重复同一领用)
|
||||
|
||||
#### Scenario: Configured reagent requisition material mismatch
|
||||
- **WHEN** 配置试剂步骤行选择 CR001,但 requisitionUsageId 指向另一配置试剂的领用
|
||||
- **THEN** 步骤保存回滚,提示物料与领用记录不匹配
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Step configured reagent replace endpoint
|
||||
`replace_step_configured_reagents()` SHALL 与 `replace_step_reagents()` 采用相同 revert + `register_step_usage_from_requisition()` 模式。
|
||||
|
||||
步骤子表 `biz_production_task_step_configured_reagent` SHALL 含 `requisition_usage_id` 字段。
|
||||
|
||||
#### Scenario: Replace configured reagent rows
|
||||
- **WHEN** 用户保存步骤配置试剂 Tab 两行且均选领用
|
||||
- **THEN** 子表全量替换,生成对应 step_save 流水,不扣配置试剂总库
|
||||
@@ -0,0 +1,48 @@
|
||||
## 1. 前置与 DDL
|
||||
|
||||
- [ ] 1.1 确认 `production-material-requisition` 迁移已执行(统一物料库 + 领用 + step_save)
|
||||
- [ ] 1.2 DDL:`biz_production_material_formula`、`biz_production_material_prep`、`biz_production_material_prep_line`
|
||||
- [ ] 1.3 DDL:`biz_production_task_step_configured_reagent` + `requisition_usage_id`
|
||||
- [ ] 1.4 字典 `production_material_type` 新增 `configured_reagent`;菜单无需新增顶级项(物料库 Tab 扩展)
|
||||
- [ ] 1.5 SQL 迁移脚本写入 `docs/sql/migrations/`(含 utf8mb4_unicode_ci)
|
||||
|
||||
## 2. 后端 — 目录与配方
|
||||
|
||||
- [ ] 2.1 Models:`formula` / `prep` / `prep_line` / `step_configured_reagent`
|
||||
- [ ] 2.2 CRUD:配置试剂目录 CRUD(material_type=configured_reagent);禁止普通 manual_in
|
||||
- [ ] 2.3 CRUD:formula 全量替换;校验子物料仅 reagent/consumable
|
||||
- [ ] 2.4 API:`GET/PUT /production-materials/{id}/formula`
|
||||
|
||||
## 3. 后端 — 配制单
|
||||
|
||||
- [ ] 3.1 CRUD:prep 创建/更新 draft、complete、cancel
|
||||
- [ ] 3.2 事务:complete 写 prep_consume + stock_batch + prep_in + 更新 stock_qty
|
||||
- [ ] 3.3 API:prep 列表/详情/complete;prep_no 生成规则
|
||||
- [ ] 3.4 usage 流水:扩展 source_type prep_consume、prep_in 展示与筛选
|
||||
|
||||
## 4. 后端 — 领用与工单
|
||||
|
||||
- [ ] 4.1 扩展 `production-material-requisition-options` 支持 materialType=configured_reagent
|
||||
- [ ] 4.2 `replace_step_configured_reagents` + API 路由
|
||||
- [ ] 4.3 `register_step_usage_from_requisition` 支持 configured_reagent 校验
|
||||
- [ ] 4.4 `my-production-material-usages` 含 configured_reagent 筛选
|
||||
|
||||
## 5. 前端 — 生产物料库
|
||||
|
||||
- [ ] 5.1 类型筛选/Tag 扩展「配置试剂」;`status-tag-registry`
|
||||
- [ ] 5.2 配置试剂新增/编辑弹窗 + 配方 inner-table
|
||||
- [ ] 5.3 第四 Tab「配制单」:列表、新建/编辑、确认配制
|
||||
- [ ] 5.4 API 模块 `production-material.ts` 扩展 formula/prep 接口
|
||||
|
||||
## 6. 前端 — 生产工单
|
||||
|
||||
- [ ] 6.1 `useTaskStepEditor`:配置试剂领用选项、保存 payload
|
||||
- [ ] 6.2 `StepDetailPanel`:配置试剂 Tab(执行态领用列)
|
||||
- [ ] 6.3 任务详情 API 返回 `configuredReagents` 子表
|
||||
|
||||
## 7. 验证与收尾
|
||||
|
||||
- [ ] 7.1 联调:BOM → 子物料领用 → 配制入库 → 配置试剂领用 → 工单 step_save
|
||||
- [ ] 7.2 `python scripts/check_field_consistency.py`(若新增 CRUD 行映射)
|
||||
- [ ] 7.3 `./scripts/update-graph.sh backend frontend`
|
||||
- [ ] 7.4 更新本变更 `tasks.md` 勾选状态
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-06-13
|
||||
@@ -0,0 +1,119 @@
|
||||
## Context
|
||||
|
||||
### 目标模型(与质检物料库对称)
|
||||
|
||||
```
|
||||
质检域 生产域(本期目标)
|
||||
──────── ────────────────
|
||||
【质检物料库】 【生产物料库】
|
||||
biz_qc_material biz_production_material (+ material_type)
|
||||
└ stock_batch └ stock_batch
|
||||
└ usage (流水) └ usage (流水)
|
||||
└ stock_check └ stock_check
|
||||
【我的物料领用记录】 【我的物料领用记录】
|
||||
```
|
||||
|
||||
**material_type** 枚举(租户内字典或固定码表):
|
||||
|
||||
| 值 | 含义 | 原表 |
|
||||
|----|------|------|
|
||||
| `reagent` | 试剂 | biz_reagent |
|
||||
| `consumable` | 耗材 | biz_consumable |
|
||||
|
||||
### 为何融合
|
||||
|
||||
- 批次、领用、盘点、变动记录 **同一套 CRUD/API/UI**,仅多一个类型维度
|
||||
- 与 QC「一个物料库」思路一致,降低培训与维护成本
|
||||
- 试剂/耗材分表导致重复实现(两套 batch、两套 check、两个「我的」菜单)
|
||||
|
||||
### 仍与质检分离
|
||||
|
||||
- 质检物料用于检测流程;生产物料用于培养/生产步骤 — **权限与菜单不同**
|
||||
- **禁止**合并 `biz_qc_material` 与 `biz_production_material` 为一张表
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 一个【生产物料库】页面 + 一个【我的物料领用记录】菜单
|
||||
- material_type 区分试剂/耗材;列表/变动/盘点均可按类型筛选
|
||||
- 批次 + 领用 + 工单登记 + 月末盘点(同 QC)
|
||||
- 迁移 consumable/reagent 历史数据;废弃耗材包
|
||||
- 生产工单步骤保留试剂/耗材 Tab,共用领用 API
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不合并质检物料库
|
||||
- 不合并生产步骤子表为单行(`step_reagent` / `step_consumable` 可保留,仅目录统一)
|
||||
- 盘点首版不调账
|
||||
- 不物理删除 biz_consumable / biz_reagent 表(迁移后只读)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: 统一表命名 `biz_production_material*`
|
||||
|
||||
**选择**:新建 `production_material` 系列表,结构 **拷贝 QC 表设计** + `material_type` 字段。
|
||||
|
||||
**理由**:与 `qc_material.py` 一一对应,后端可复用 CRUD 模式;避免继续维护 consumable/reagent 双份 batch/check。
|
||||
|
||||
### Decision 2: material_type 落点
|
||||
|
||||
| 层级 | material_type |
|
||||
|------|----------------|
|
||||
| 物资目录 `biz_production_material` | **必填** |
|
||||
| 批次 / 流水 / 盘点快照 | 冗余快照 `material_type`(便于列表筛选,与 material_code 一并复制) |
|
||||
|
||||
编码唯一性:**租户 + material_type + material_code**(允许试剂与耗材编码相同但类型不同)。
|
||||
|
||||
### Decision 3: 菜单与页面
|
||||
|
||||
| 旧 | 新 |
|
||||
|----|-----|
|
||||
| 耗材管理、试剂管理 | **【生产物料库】** → 挂在 **【生产基础信息】**(**已确认**;替换原耗材/试剂管理入口,`parent_id=PRB00000000000000000000000000001`) |
|
||||
| 我的耗材领用 + 我的试剂领用 | **【我的物料领用记录】** → 挂在 **【生产管理】**(与「我的生产任务」同级,执行侧查阅) |
|
||||
|
||||
页面三 Tab:**批次列表 | 变动记录 | 库存盘点**(复制 `qc-material/index.vue` 结构)。
|
||||
|
||||
### Decision 4: 生产工单步骤 UI
|
||||
|
||||
**选择**:保留 **试剂 Tab / 耗材 Tab**(工艺步骤已有分列习惯),但:
|
||||
|
||||
- 领用下拉调用 `GET /production-material-requisition-options?materialType=reagent|consumable`
|
||||
- 保存仍写各自 step 子表 + 统一 `biz_production_material_usage`(step_save)
|
||||
|
||||
**替代方案**:合并为单「物料」Tab — 放弃,改动工艺对照成本高。
|
||||
|
||||
### Decision 5: 领用与 step_save(同前)
|
||||
|
||||
库存仅在 manual_out(按 batch)扣减;step_save 关联 parent_usage_id,不扣 stock_qty。
|
||||
|
||||
### Decision 6: 数据迁移
|
||||
|
||||
1. INSERT `biz_production_material` FROM consumable(type=consumable)+ reagent(type=reagent)
|
||||
2. 期初 batch:对 migrated 且 stock_qty>0 生成 INIT 批次
|
||||
3. 旧 stock_log 可迁移到 `production_material_usage` 或保留旧表只读(实现时 **新流水只写新表**)
|
||||
4. 步骤/工艺快照:`reagent_code` / `consumable_code` 通过 **material_type + code** 关联新目录
|
||||
|
||||
### Decision 7: 旧 API 策略
|
||||
|
||||
`GET /consumables`、`GET /reagents`:**只读兼容** 1 个版本(内部转查 production_material + type 过滤),POST/PUT/DELETE 返回 410 并提示使用生产物料库。
|
||||
|
||||
### Decision 8: 耗材包
|
||||
|
||||
同前:UI/API 下线;原因同批次管理。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| 风险 | 缓解 |
|
||||
|------|------|
|
||||
| 迁移编码冲突(同码异型) | 唯一键含 material_type;冲突则迁移脚本加前缀 |
|
||||
| 范围大(融合+批次+盘点+领用) | tasks 分 Phase;先 library+migration,再 batch,再 requisition,再 check |
|
||||
| 步骤双 Tab 与统一库认知 | UI 文案说明「类型由 Tab 决定,领用记录已过滤」 |
|
||||
|
||||
## Open Questions
|
||||
|
||||
| # | 问题 | 建议 |
|
||||
|---|------|------|
|
||||
| Q1 | 【生产物料库】挂「生产管理」还是「生产基础信息」 | **已确认:生产基础信息** |
|
||||
| Q2 | material_type 是否走数据字典 | **是**,dict_type=`production_material_type` |
|
||||
| Q3 | 旧 consumable/reagent 菜单是否保留隐藏入口 | **否**,直接隐藏,仅保留路由 redirect 可选 |
|
||||
@@ -0,0 +1,63 @@
|
||||
## Why
|
||||
|
||||
客户希望生产侧物料管理与【质检物料库】采用 **同一套思路**:一个物料库、入库批次、领用→工单登记、月末盘点;批号/厂家不同须靠批次区分,耗材包不再适用。同时,生产侧现有 **试剂、耗材分表分菜单** 造成与质检不一致;客户要求 **融合为统一「生产物料库」**,通过 **物料类型**(试剂 / 耗材)区分,使生产与质检的管理模型对称、思路清晰。
|
||||
|
||||
## What Changes
|
||||
|
||||
### 统一生产物料库(本期核心架构变更)
|
||||
|
||||
- 新建 **`biz_production_material`** 物资目录,字段对齐 `biz_qc_material`,新增 **`material_type`**(`reagent` 试剂 / `consumable` 耗材)
|
||||
- 新建统一子表(对齐 QC 命名):
|
||||
- `biz_production_material_stock_batch`
|
||||
- `biz_production_material_usage`(变动流水,含 manual_in / manual_out / step_save)
|
||||
- `biz_production_material_stock_check` + `_batch_line` + `_unused_line`
|
||||
- **一个** 管理页面 **【生产物料库】**(菜单挂在 **【生产基础信息】**,三 Tab:批次列表 / 变动记录 / 库存盘点),筛选器支持按物料类型
|
||||
- **一个** 菜单 **【我的物料领用记录】**(参照质检「我的物料领用记录」,可按类型筛选)
|
||||
- 迁移 `biz_consumable`、`biz_reagent` 历史数据 → `biz_production_material`;原表只读保留或废弃写 API
|
||||
- **下线** 独立菜单「耗材管理」「试剂管理」(合并进生产物料库)
|
||||
|
||||
### 领用与生产工单(保留,数据源改为统一库)
|
||||
|
||||
- 步骤保存:从 **领用记录** 登记消耗(`parent_usage_id`),不二次扣库
|
||||
- 【生产工单】步骤可 **保留「试剂」「耗材」两个 Tab**(与工艺步骤结构一致),但均从 **同一领用 API** 拉取,按 `material_type` 过滤
|
||||
- 登记记录可在 **【我的物料领用记录】** 查看(含类型 Tag、批号)
|
||||
|
||||
### 耗材包废弃(保留)
|
||||
|
||||
- 移除耗材包 Tab/菜单、工艺库「从耗材包导入」
|
||||
|
||||
### 与质检的关系
|
||||
|
||||
- **融合范围**:仅生产侧 **试剂 + 耗材** → **生产物料库**
|
||||
- **仍不合并**:`biz_qc_material`(质检物料库)与 `biz_production_material` **独立**(业务域、权限、菜单分离);**结构对称**,非表合并
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `production-material-library`: 统一物资目录 + material_type、菜单/页面【生产物料库】、旧表迁移与菜单下线
|
||||
- `production-material-batch-inventory`: 统一批次表、入出库、变动流水(对齐 QC)
|
||||
- `production-material-stock-check`: 统一库存盘点(Part A + Part B)
|
||||
- `production-material-unification`: consumable/reagent → production_material 数据迁移、编码映射、下游快照兼容
|
||||
- `consumable-pack-deprecation`: 耗材包下线
|
||||
- `production-requisition-stock-log`: 领用关联、领用选项/我的领用/下钻 API
|
||||
- `production-step-requisition-usage`: 步骤领用登记、step_save 替换规则
|
||||
- `production-material-requisition-ui`: 生产物料库 UI、我的物料领用、生产工单步骤 UI
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `production-step-stock-deduction`: supersede 直接扣库
|
||||
- `material-stock-log-ui`: supersede 为 production-material 统一变动记录 UI 要求
|
||||
|
||||
### Superseded(本变更内不再单独实施)
|
||||
|
||||
- 原 `consumable-batch-inventory` / `reagent-batch-inventory` 双轨方案
|
||||
- 原 `consumable-stock-check` / `reagent-stock-check` 双轨方案
|
||||
- 原「我的耗材领用记录」「我的试剂领用记录」两个菜单 → 合并为「我的物料领用记录」
|
||||
|
||||
## Impact
|
||||
|
||||
- **数据库**:新建 production_material 系列 6 表;迁移脚本;step 子表 `requisition_usage_id`;隐藏旧菜单
|
||||
- **后端**:新建 `models/production_material.py`、`crud/production_material*.py`;统一 API 前缀 `/production-materials`;consumable/reagent API 只读或 410
|
||||
- **前端**:新建 `production-material/index.vue`(参照 `qc-material/index.vue`);`my-production-material-usage`;改造 `StepDetailPanel`;隐藏 consumable/reagent 菜单
|
||||
- **下游**:工艺/步骤子表仍可按试剂行、耗材行维护标准用量(快照);目录引用逐步改为 material_id 或编码映射
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Consumable pack UI removed
|
||||
系统 SHALL **移除**以下入口:
|
||||
|
||||
- 耗材管理页 `consumable/index.vue` 的 **「耗材包」** Tab 及 `ConsumablePackTab.vue` 引用
|
||||
- 侧栏/路由「耗材包管理」(`consumable-pack`)设为不可见(`visible=0` 或 `isHide: true`)
|
||||
|
||||
#### Scenario: Consumable page has no pack tab
|
||||
- **WHEN** 用户打开耗材管理
|
||||
- **THEN** 不存在「耗材包」Tab
|
||||
|
||||
#### Scenario: Pack menu hidden
|
||||
- **WHEN** 用户浏览生产基础信息菜单
|
||||
- **THEN** 不展示「耗材包管理」菜单项
|
||||
|
||||
### Requirement: Process library pack import removed
|
||||
工艺库 `process/index.vue` SHALL **移除**「从耗材包导入」按钮、弹窗及相关 API 调用(`fetchAllConsumablePacks`、`fetchConsumablePackDetail`)。
|
||||
|
||||
工艺步骤耗材区仍支持手工「添加耗材」行(编码、名称、标准用量等快照),**实际批次领用与消耗**在生产工单步骤完成。
|
||||
|
||||
#### Scenario: Process editor no pack import
|
||||
- **WHEN** 用户在工艺库编辑步骤耗材
|
||||
- **THEN** 无「从耗材包导入」操作,仅可手工添加行
|
||||
|
||||
### Requirement: Consumable pack write API disabled
|
||||
后端 `/consumable-packs` 的 POST、PUT、DELETE SHALL 拒绝新操作(HTTP 410 或 403,消息说明已废弃)。GET 可保留只读供历史审计(可选实现)。
|
||||
|
||||
#### Scenario: Create pack rejected
|
||||
- **WHEN** 客户端调用 POST /consumable-packs
|
||||
- **THEN** 请求失败,提示耗材包功能已废弃
|
||||
|
||||
### Requirement: Rationale documented in spec
|
||||
废弃原因:同名耗材 **批号、厂家不同** 时,耗材包无法唯一标识实际库存批次;批次管理 + 领用记录可精确追溯。
|
||||
|
||||
#### Scenario: New workflow uses batch not pack
|
||||
- **WHEN** 生产人员需领用某批号耗材
|
||||
- **THEN** 在耗材管理按批次领用出库,而非从耗材包导入到工艺再使用
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Consumable pack as standard workflow
|
||||
**Reason**: 由入库批次 + 领用记录替代。
|
||||
|
||||
**Migration**: 历史 pack 数据只读;工艺改用人工维护步骤耗材清单;实际消耗走生产工单领用登记。
|
||||
@@ -0,0 +1,38 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Stock log display fields
|
||||
【生产物料库】变动记录 Tab 及行内弹窗 SHALL 展示:
|
||||
|
||||
- 物料类型(material_type Tag:试剂/耗材)
|
||||
- 物料编码、物料名称
|
||||
- 入库编号、货号、批号、厂家、过期日期(批次快照)
|
||||
- 变动类型、变动数量、变动前/后汇总库存
|
||||
- 来源 Tag:手动入库 / 手动出库(领用)/ 步骤登记 / 步骤扣减(历史)
|
||||
- 关联任务、步骤、领用人、用途、用量单位、操作人、时间
|
||||
|
||||
数据源为 **`biz_production_material_usage`**(非旧 consumable/reagent stock_log)。
|
||||
|
||||
#### Scenario: Unified usage log shows material type
|
||||
- **WHEN** 用户查看变动记录
|
||||
- **THEN** 试剂与耗材流水在同一 Tab,可按类型筛选
|
||||
|
||||
#### Scenario: Manual out log display
|
||||
- **WHEN** 变动记录为手动出库类型
|
||||
- **THEN** 展示领用人、用途、操作人、时间,来源显示「手动出库(领用)」
|
||||
|
||||
#### Scenario: Step registration log display
|
||||
- **WHEN** 变动记录为 step_save 且含 parentUsageId
|
||||
- **THEN** 展示关联任务编号、步骤名称、parent 领用人、操作人、时间,来源显示「步骤登记」;stock_before 与 stock_after 相同
|
||||
|
||||
#### Scenario: Legacy step save log display
|
||||
- **WHEN** 变动记录为历史 step_save(无 parentUsageId)
|
||||
- **THEN** 来源显示「步骤扣减(历史)」以区别于新流程;展示 task_no 与当时 stock 变动
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Requisition drill-down action in stock log
|
||||
变动记录列表中,`source_type=manual_out` 的行 SHALL 提供「查看步骤消耗」操作,打开子明细(step-usages API 数据)。
|
||||
|
||||
#### Scenario: Open step usages from stock log
|
||||
- **WHEN** 用户点击领用记录行的「查看步骤消耗」
|
||||
- **THEN** 弹窗或展开区展示该领用下所有 step_save 明细
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Unified production material stock batch
|
||||
系统 SHALL 新建 `biz_production_material_stock_batch`,结构对齐 `biz_qc_material_stock_batch`,含 `material_id` → `biz_production_material.id`,快照含 **material_type**。
|
||||
|
||||
批次必填:stock_in_no(租户唯一)、stock_in_date、**expire_date**、catalog_no、batch_no、manufacturer、unit_price、amount、in_qty、remaining_qty。
|
||||
|
||||
`biz_production_material.stock_qty` = Σ 下属批次 remaining_qty。
|
||||
|
||||
#### Scenario: Batch inbound updates typed material stock
|
||||
- **WHEN** 对 material_type=consumable 的物料入库一批
|
||||
- **THEN** 批次行与汇总 stock_qty 增加,usage 写 manual_in
|
||||
|
||||
### Requirement: Unified production material usage log
|
||||
系统 SHALL 新建 `biz_production_material_usage` 作为 **唯一** 变动流水表,对齐 QC usage 字段,并扩展生产域溯源:
|
||||
|
||||
| source_type | 说明 |
|
||||
|-------------|------|
|
||||
| manual_in | 入库 |
|
||||
| manual_out | 领用出库 |
|
||||
| step_save | 生产工单步骤登记 |
|
||||
|
||||
生产步骤字段:`step_id`、`step_name`、`task_id`、`task_no`;领用关联:`parent_usage_id`、`receiver`、`purpose`;批次快照字段同 QC。
|
||||
|
||||
**SHALL NOT** 继续使用 `biz_consumable_stock_log` / `biz_reagent_stock_log` 写入新流水。
|
||||
|
||||
#### Scenario: Manual out writes to unified usage table
|
||||
- **WHEN** 用户对某批次领用出库
|
||||
- **THEN** INSERT biz_production_material_usage,source_type=manual_out
|
||||
|
||||
### Requirement: Batch list tab data source
|
||||
【生产物料库】批次列表 Tab SHALL 调用 `GET /production-material-batches`,支持 keyword、materialId、**materialType**、status 筛选;一行 = 一条批次。
|
||||
|
||||
#### Scenario: Filter batches by reagent only
|
||||
- **WHEN** 用户筛选 materialType=reagent
|
||||
- **THEN** 列表仅展示试剂批次
|
||||
|
||||
### Requirement: Inbound and outbound by batch
|
||||
入库/批量入库、领用出库/批量出库 SHALL 按 batchId 操作,逻辑对齐 QC `qc_material_stock_batch` CRUD。
|
||||
|
||||
#### Scenario: Outbound requires batch selection
|
||||
- **WHEN** 领用出库未选 batchId
|
||||
- **THEN** 拒绝并提示选择入库批次
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Unified production material catalog
|
||||
系统 SHALL 新建 `biz_production_material` 作为生产侧 **唯一** 物资目录,字段对齐 `biz_qc_material`,并 **新增**:
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `material_type` | 物料类型,**必填**;`reagent`(试剂)或 `consumable`(耗材) |
|
||||
|
||||
其他字段:`material_code`、`material_name`、`spec_model`、`unit`、`stock_qty`、`warning_qty`、`status` 及公共字段。
|
||||
|
||||
唯一约束:**租户 + material_type + material_code**(del_flag=0 维度)。
|
||||
|
||||
#### Scenario: Create reagent catalog entry
|
||||
- **WHEN** 用户新增物料,material_type=reagent,material_code=R001
|
||||
- **THEN** 写入 biz_production_material,stock_qty 初始 0
|
||||
|
||||
#### Scenario: Same code different type allowed
|
||||
- **WHEN** 已存在 consumable 编码 C001,再新增 reagent 编码 C001
|
||||
- **THEN** 允许创建(类型不同)
|
||||
|
||||
### Requirement: Material type dictionary
|
||||
`material_type` SHALL 注册数据字典 `production_material_type`(或等价 dict_type),前端 Tag 展示「试剂」「耗材」。
|
||||
|
||||
#### Scenario: List shows type tag
|
||||
- **WHEN** 用户查看生产物料库批次列表
|
||||
- **THEN** 每行展示 material_type 对应 Tag
|
||||
|
||||
### Requirement: Production material library menu and page
|
||||
系统 SHALL 提供 **单一** 管理入口:
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| 菜单名 | **生产物料库** |
|
||||
| 父菜单 | **【生产基础信息】**(`PRB00000000000000000000000000001`,**已确认**) |
|
||||
| 路由 | `production-material` → `/production/production-material/index` |
|
||||
| menuCode | `production:material:list` |
|
||||
|
||||
页面 SHALL 含三 Tab:**批次列表 | 变动记录 | 库存盘点**(布局参照 `qc-material/index.vue`)。
|
||||
|
||||
筛选区 SHALL 含 **物料类型**(全部 / 试剂 / 耗材)。
|
||||
|
||||
菜单注册 SHALL 同步 `sys_menu` 迁移脚本、`backend/app/api/menu.py`、`sqxp.ts`(挂在 `ProductionBase` 的 `children` 下,替代原耗材/试剂管理项)。
|
||||
|
||||
#### Scenario: Single library replaces dual menus
|
||||
- **WHEN** 用户打开生产物料库
|
||||
- **THEN** 可同时管理试剂与耗材,无需分别进入耗材管理、试剂管理
|
||||
|
||||
### Requirement: Legacy consumable and reagent menus hidden
|
||||
菜单 SQL SHALL 将「耗材管理」「试剂管理」设为不可见(`visible=0` 或删除菜单项);**不得**再作为物料维护入口。
|
||||
|
||||
可选:旧路由 redirect 至生产物料库并带 `materialType` query。
|
||||
|
||||
#### Scenario: Old menus not shown
|
||||
- **WHEN** 用户浏览生产基础信息
|
||||
- **THEN** 不展示独立的耗材管理、试剂管理菜单
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Production material library page
|
||||
新建 `production/production-material/index.vue`,**一个** 页面管理试剂+耗材,三 Tab + 物料类型筛选,**参照** `quality-inspection/qc-material/index.vue`。
|
||||
|
||||
**SHALL NOT** 再维护独立的 `consumable/index.vue`、`reagent/index.vue` 作为主入口(可保留文件仅 redirect 或废弃)。
|
||||
|
||||
#### Scenario: User manages all production materials in one place
|
||||
- **WHEN** 用户维护批号不同的同名耗材与试剂
|
||||
- **THEN** 在同一生产物料库批次列表中通过类型列与批号列区分
|
||||
|
||||
### Requirement: My production material usage single menu
|
||||
【生产管理】下 SHALL 仅 **一个** 菜单 **【我的物料领用记录】**(对齐质检命名习惯):
|
||||
|
||||
| 项 | 值 |
|
||||
|----|-----|
|
||||
| 路由 | `my-production-material-usage` |
|
||||
| menuCode | `production:my-material-usage:list` |
|
||||
| 参照 | `my-qc-material-usage/index.vue` |
|
||||
|
||||
页面含 **物料类型** 筛选;展示领用 + 生产工单 step_save 登记。
|
||||
|
||||
**SHALL NOT** 再实施「我的耗材领用记录」「我的试剂领用记录」两个独立菜单。
|
||||
|
||||
#### Scenario: One my menu replaces two
|
||||
- **WHEN** 用户查看自己的领用与消耗
|
||||
- **THEN** 在一个列表中通过类型 Tag 区分试剂/耗材
|
||||
|
||||
### Requirement: Production work order step tabs use filtered requisition API
|
||||
【生产工单】步骤执行界面 **保留** 试剂 Tab、耗材 Tab;各自调用 `production-material-requisition-options?materialType=reagent|consumable`。
|
||||
|
||||
列:领用记录(含批号/入库编号)、物料名称、批号、厂家、领用人、标准用量、实际用量、单位、备注。
|
||||
|
||||
#### Scenario: Reagent tab only shows reagent requisitions
|
||||
- **WHEN** 用户在试剂 Tab 打开领用下拉
|
||||
- **THEN** 不出现 consumable 类型的领用记录
|
||||
|
||||
### Requirement: Usage and stock check tabs show material type
|
||||
变动记录 Tab、库存盘点 Tab 列表 SHALL 含 **物料类型** 列/筛选项。
|
||||
|
||||
#### Scenario: Usage log filter by type
|
||||
- **WHEN** 用户在变动记录 Tab 筛选「试剂」
|
||||
- **THEN** 仅展示 material_type=reagent 的流水
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: My consumable requisition menu page
|
||||
**Reason**: 合并为【我的物料领用记录】+ materialType 筛选。
|
||||
|
||||
**Migration**: 若已创建双菜单 SQL,改为单菜单。
|
||||
|
||||
### Requirement: My reagent requisition menu page
|
||||
**Reason**: 同上。
|
||||
|
||||
**Migration**: 同上。
|
||||
|
||||
### Requirement: Consumable and reagent management three-tab layout
|
||||
**Reason**: 合并为【生产物料库】单页三 Tab。
|
||||
|
||||
**Migration**: 隐藏旧双菜单。
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Unified production material stock check
|
||||
系统 SHALL 新建:
|
||||
|
||||
- `biz_production_material_stock_check`
|
||||
- `biz_production_material_stock_check_batch_line`(Part A)
|
||||
- `biz_production_material_stock_check_unused_line`(Part B)
|
||||
|
||||
规则对齐质检盘点:Part A 仅 remaining_qty>0 批次;Part B 自由登记;完成不调账;unused_line 含 material_type 快照。
|
||||
|
||||
#### Scenario: Create check snapshots all positive batches
|
||||
- **WHEN** 创建盘点单
|
||||
- **THEN** Part A 含所有类型(试剂+耗材)remaining_qty>0 批次快照
|
||||
|
||||
### Requirement: Stock check tab on production material library
|
||||
【生产物料库】第三 Tab **库存盘点** SHALL 参照 `QcMaterialStockCheckTab.vue`;列表可按 **material_type** 筛选 Part A/B 明细。
|
||||
|
||||
#### Scenario: Stock check tab after usage tab
|
||||
- **WHEN** 用户在生产物料库切换 Tab
|
||||
- **THEN** 顺序为:批次列表 → 变动记录 → 库存盘点
|
||||
|
||||
### Requirement: Monthly inventory use case
|
||||
系统 SHALL 支持按标题/时间创建盘点单(如「2026年6月生产物料盘点」),供月末盘存归档。
|
||||
|
||||
#### Scenario: Complete monthly check
|
||||
- **WHEN** 用户完成盘点单
|
||||
- **THEN** status=completed,库存数量不因盘点而改变
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Migrate consumable and reagent to production material
|
||||
系统 SHALL 提供迁移脚本,将:
|
||||
|
||||
- `biz_consumable` → `biz_production_material`(material_type=consumable,字段映射 consumable_code→material_code 等)
|
||||
- `biz_reagent` → `biz_production_material`(material_type=reagent,reagent_code→material_code 等)
|
||||
|
||||
保留原表 **id 映射表** 或在新表 `remark`/扩展字段存 `legacy_id` 以便追溯。
|
||||
|
||||
对 stock_qty>0 的迁移行生成 **期初批次**(stock_in_no=`INIT-{type}-{code}`)。
|
||||
|
||||
#### Scenario: Consumable row migrated with type
|
||||
- **WHEN** 迁移执行
|
||||
- **THEN** 原 consumable 编码 X 成为 production_material 一行,material_type=consumable
|
||||
|
||||
### Requirement: Step and process snapshot compatibility
|
||||
工艺/步骤子表仍使用 `reagent_code`、`consumable_code` 快照时,解析目录 SHALL 使用 **material_type + code** 查询 `biz_production_material`。
|
||||
|
||||
#### Scenario: Resolve reagent code on step load
|
||||
- **WHEN** 步骤含 reagent_code=R001
|
||||
- **THEN** 关联 material_type=reagent 且 material_code=R001 的目录行(若存在)
|
||||
|
||||
### Requirement: Legacy API read-only bridge
|
||||
`GET /consumables`、`GET /reagents` MAY 只读代理到 production_material 对应 type,**不得** 新建/更新旧表。
|
||||
|
||||
POST/PUT/DELETE 旧 consumable/reagent API SHALL 返回 410,提示使用 `/production-materials`。
|
||||
|
||||
#### Scenario: Legacy create consumable rejected
|
||||
- **WHEN** POST /consumables
|
||||
- **THEN** 410,消息指向生产物料库
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Usage log requisition link fields
|
||||
`biz_production_material_usage` SHALL 包含:
|
||||
|
||||
- `parent_usage_id` — step_save 指向 manual_out
|
||||
- `usage_unit`
|
||||
- `material_type` 快照
|
||||
|
||||
步骤子表 `biz_production_task_step_reagent` / `_consumable` 保留 `requisition_usage_id`(指向 usage.id)。
|
||||
|
||||
#### Scenario: Step save links to manual out in unified usage table
|
||||
- **WHEN** 步骤保存登记消耗
|
||||
- **THEN** 写入 production_material_usage,parent_usage_id 指向同表 manual_out 行
|
||||
|
||||
### Requirement: Requisition options API
|
||||
系统 SHALL 提供:
|
||||
|
||||
```
|
||||
GET /api/admin/web/admin/production-material-requisition-options
|
||||
Query: materialType? (reagent|consumable), keyword?, limit?
|
||||
```
|
||||
|
||||
返回 `source_type=manual_out` 记录,label 含批号/入库编号/领用人;**materialType** 过滤试剂或耗材。
|
||||
|
||||
#### Scenario: Reagent tab loads reagent requisitions only
|
||||
- **WHEN** 生产工单步骤试剂 Tab 请求 materialType=reagent
|
||||
- **THEN** 仅返回 material_type=reagent 的领用记录
|
||||
|
||||
#### Scenario: Consumable tab loads consumable requisitions only
|
||||
- **WHEN** 耗材 Tab 请求 materialType=consumable
|
||||
- **THEN** 仅返回耗材领用记录
|
||||
|
||||
### Requirement: My production material requisition list API
|
||||
系统 SHALL 提供:
|
||||
|
||||
```
|
||||
GET /api/admin/web/admin/my-production-material-usages
|
||||
Query: materialType?, changeType?, keyword?, startTime?, endTime?, page, pageSize
|
||||
```
|
||||
|
||||
可见范围(与 QC 一致):
|
||||
|
||||
- manual_out:当前用户为 receiver
|
||||
- step_save:当前用户为 create_by
|
||||
|
||||
#### Scenario: Single my menu with type filter
|
||||
- **WHEN** 用户打开【我的物料领用记录】并筛选 materialType=consumable
|
||||
- **THEN** 仅展示耗材相关领用与步骤登记
|
||||
|
||||
#### Scenario: Step registration visible in my list
|
||||
- **WHEN** 用户在生产工单登记试剂消耗
|
||||
- **THEN** my-production-material-usages 含该 step_save 行(material_type=reagent)
|
||||
|
||||
### Requirement: Requisition child step usages API
|
||||
```
|
||||
GET /api/admin/web/admin/production-material-requisitions/{parentUsageId}/step-usages
|
||||
```
|
||||
|
||||
返回 parent_usage_id 下所有 step_save 明细。
|
||||
|
||||
#### Scenario: Drill down step usages from requisition
|
||||
- **WHEN** 查询某领用记录下钻
|
||||
- **THEN** 返回关联生产步骤消耗列表
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Step save registers consumption via requisition not direct deduction
|
||||
对于 **编码存在于** `biz_consumable` / `biz_reagent` 目录中的步骤行,系统 SHALL 要求提供有效 `requisitionUsageId`(指向 `source_type=manual_out` 的 stock_log 记录)。步骤保存时:
|
||||
|
||||
1. 写 `source_type=step_save` 变动记录
|
||||
2. 设置 `parent_usage_id = requisitionUsageId`
|
||||
3. **不修改** 对应物资 `stock_qty`(`stock_before` SHALL 等于 `stock_after`)
|
||||
4. `change_qty` SHALL 为负数,绝对值等于 `actual_usage` 解析后的有效用量
|
||||
|
||||
#### Scenario: First save with requisition linked
|
||||
- **WHEN** 用户保存步骤,耗材 A(目录内)关联领用记录 R(曾出库 10),actual_usage=2
|
||||
- **THEN** 耗材 A 的 stock_qty 不变,生成 1 条 step_save 记录(change_qty=-2,parent_usage_id=R)
|
||||
|
||||
#### Scenario: Save without requisition for catalog material
|
||||
- **WHEN** 用户保存步骤,试剂 B 编码存在于 biz_reagent,但未选 requisitionUsageId
|
||||
- **THEN** 整个步骤保存回滚,提示「请选择领用记录」
|
||||
|
||||
#### Scenario: Save with empty actual usage
|
||||
- **WHEN** 用户保存步骤,已选领用记录但 actual_usage 为空或为 0
|
||||
- **THEN** 该步骤行不生成 step_save 记录(与现网跳过空用量一致)
|
||||
|
||||
### Requirement: Custom catalog-absent materials remain record-only
|
||||
若步骤行 `consumable_code` / `reagent_code` **不存在于** 对应目录表(自定义/legacy 编码),系统 SHALL:
|
||||
|
||||
- 允许保存步骤子表(编码、名称、standard_usage、actual_usage 等)
|
||||
- **不要求** requisitionUsageId
|
||||
- **不写入** stock_log,**不修改** stock_qty
|
||||
|
||||
#### Scenario: Custom code without catalog match
|
||||
- **WHEN** 步骤保存包含 consumable_code=`CUSTOM-001` 且 biz_consumable 中无此编码
|
||||
- **THEN** 子表保存成功,无 stock_log 变动
|
||||
|
||||
### Requirement: Requisition record validation on step save
|
||||
保存步骤时,对每个需关联领用的行,系统 SHALL 校验:
|
||||
|
||||
1. `requisitionUsageId` 对应记录存在、未删除、`source_type=manual_out`
|
||||
2. 领用记录的 `material_id` 与步骤行所选物料(按编码匹配目录)一致
|
||||
3. 领用记录 **SHALL** 含有效 `batch_id`(批次领用出库产生);步骤登记继承 parent 的批号/入库编号快照
|
||||
4. 同一步骤列表内 `requisitionUsageId` 不可重复
|
||||
|
||||
#### Scenario: Invalid requisition id rejected
|
||||
- **WHEN** 用户提交不存在的 requisitionUsageId
|
||||
- **THEN** 步骤保存回滚,提示「领用记录不存在或已失效」
|
||||
|
||||
#### Scenario: Duplicate requisition in same step
|
||||
- **WHEN** 同一步骤两行均选择同一 requisitionUsageId
|
||||
- **THEN** 步骤保存回滚,提示「物料列表中存在重复领用记录,请检查」
|
||||
|
||||
#### Scenario: Requisition material mismatch
|
||||
- **WHEN** 步骤行选择耗材 A,但 requisitionUsageId 指向耗材 B 的领用记录
|
||||
- **THEN** 步骤保存回滚,提示物料与领用记录不匹配
|
||||
|
||||
### Requirement: Step save diff settlement replaces legacy deduct_for_step
|
||||
`replace_step_reagents()` / `replace_step_consumables()` SHALL 继续采用全量回退 + 重算,但替换 `deduct_for_step()` 的直接扣库逻辑为 `register_step_usage_from_requisition()`(新函数,耗材/试剂各一)。
|
||||
|
||||
**回退阶段**(revert step 的全部 step_save 记录):
|
||||
|
||||
| 旧记录类型 | 库存处理 |
|
||||
|-----------|----------|
|
||||
| `parent_usage_id` 为空(历史直接扣库) | 回加 `\|change_qty\|` 至 stock_qty |
|
||||
| `parent_usage_id` 有值(新流程登记) | **不回加** stock_qty,仅软删记录 |
|
||||
|
||||
**重算阶段**:按本 spec「Step save registers consumption via requisition」写入新 step_save 记录。
|
||||
|
||||
#### Scenario: Re-save step with new requisition flow
|
||||
- **WHEN** 步骤首次保存登记领用 R 用量 2(新流程),第二次改为用量 3
|
||||
- **THEN** 回退时 stock_qty 不变;重算后仅 1 条 step_save(change_qty=-3);stock_qty 全程不变
|
||||
|
||||
#### Scenario: Re-save legacy direct deduction step
|
||||
- **WHEN** 步骤含历史 step_save(无 parent_usage_id,曾扣库 5),用户编辑为领用模式用量 2
|
||||
- **THEN** 回退时 stock_qty +5;新 step_save 不扣库;净效果 stock_qty +5
|
||||
|
||||
#### Scenario: Remove all reagent rows from step
|
||||
- **WHEN** 步骤曾登记 2 条 step_save(新流程),第二次保存清空试剂列表
|
||||
- **THEN** 回退软删 2 条 step_save,stock_qty 不变
|
||||
|
||||
### Requirement: Step save transaction atomicity
|
||||
领用登记、步骤子表替换、stock_log 回退/写入 SHALL 在同一数据库事务内完成。任一校验失败 SHALL 整单回滚。
|
||||
|
||||
#### Scenario: Invalid requisition rolls back step sub-table
|
||||
- **WHEN** 领用校验失败
|
||||
- **THEN** 步骤试剂/耗材子表不发生部分更新
|
||||
|
||||
### Requirement: Step save traceability fields
|
||||
每条新流程 `step_save` 记录 SHALL 包含:
|
||||
|
||||
- `step_id`、`step_name`(快照)
|
||||
- `task_id`、`task_no`(快照)
|
||||
- `parent_usage_id`
|
||||
- `material_id`、`material_code`、`material_name`(快照)
|
||||
- `usage_unit`(来自步骤行 unit 或领用记录)
|
||||
|
||||
#### Scenario: Stock log traceability
|
||||
- **WHEN** 步骤保存成功
|
||||
- **THEN** step_save 记录可通过 task_no、step_name 追溯至【生产工单】任务与步骤;登记人可在【我的耗材领用记录】或【我的试剂领用记录】中查看
|
||||
|
||||
### Requirement: Step usage visible in my requisition menus
|
||||
【生产工单】步骤保存产生的 `step_save` 记录 SHALL 在对应物料类型的「我的领用记录」菜单中可见:`create_by` 为登记人;`manual_out` 领用记录可通过下钻查看关联的全部 step_save。
|
||||
|
||||
#### Scenario: Operator finds own registration in my menu
|
||||
- **WHEN** 用户完成生产工单步骤耗材登记
|
||||
- **THEN** 无需进入耗材管理页,在【我的耗材领用记录】即可看到该次登记
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Step save auto stock deduction
|
||||
**Reason**: 库存扣减前移至 manual_out 领用;步骤保存改为领用关联登记,避免双重扣减。
|
||||
|
||||
**Migration**: 新保存步骤 MUST 选领用记录;历史无 parent_usage_id 的 step_save 仍按 Decision 3 回退规则处理。实现上删除 `deduct_for_step()` 中对目录物料的直接扣库分支,替换为 `register_step_usage_from_requisition()`。
|
||||
|
||||
### Requirement: Skip deduction for materials not in catalog
|
||||
**Reason**: 合并入「Custom catalog-absent materials remain record-only」;目录内物料改为 MUST 选领用,不再存在「目录内跳过扣减」语义。
|
||||
|
||||
**Migration**: 自定义编码行为不变(仅记录);目录内物料从无领用扣库变为必须领用。
|
||||
|
||||
### Requirement: Step save diff settlement via full revert and re-deduct
|
||||
**Reason**: 「re-deduct」语义变更:重算阶段不再扣总库,仅写关联流水。
|
||||
|
||||
**Migration**: 保留 revert + 重算框架;重算函数替换;回退区分历史/新记录(见 ADDED「Step save diff settlement replaces legacy deduct_for_step」)。
|
||||
|
||||
#### Scenario: Stock insufficient during step save
|
||||
- **WHEN** 用户保存步骤且某目录内行未选领用
|
||||
- **THEN** 回滚并提示「请选择领用记录」(**不再**出现「库存不足」类 step_save 扣库错误)
|
||||
|
||||
> **注**:「库存不足」仍仅发生在 **manual_out 批量出库** 时,不在步骤保存阶段校验总库。
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: Step save auto stock deduction
|
||||
**Reason**: Superseded by `production-step-requisition-usage` — 步骤保存改为领用关联登记,不再按 actual_usage 直接扣减 stock_qty。
|
||||
|
||||
**Migration**: 见 `openspec/changes/production-material-requisition/specs/production-step-requisition-usage/spec.md`。
|
||||
|
||||
### Requirement: Step save diff settlement via full revert and re-deduct
|
||||
**Reason**: 「re-deduct」语义移除;重算阶段仅写 parent_usage_id 关联流水,不扣总库。
|
||||
|
||||
**Migration**: 保留 revert 框架;回退规则区分历史/新记录。
|
||||
|
||||
### Requirement: Step save stock deduction uses row-level locking
|
||||
**Reason**: 新流程 step_save 不改 stock_qty,无需对物资主表加锁;manual_out 仍保留行锁。
|
||||
|
||||
**Migration**: 行锁保留在 manual_out 与历史 step_save 回退路径。
|
||||
|
||||
### Requirement: Step save stock deduction in same transaction
|
||||
**Reason**: 合并入 `production-step-requisition-usage` 的事务原子性要求;错误类型从「库存不足」变为「请选择领用记录」。
|
||||
|
||||
**Migration**: 无数据迁移。
|
||||
|
||||
### Requirement: Skip deduction for materials not in catalog
|
||||
**Reason**: 合并入自定义物料 record-only 规则;目录内物料必须选领用。
|
||||
|
||||
**Migration**: 自定义编码行为不变。
|
||||
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Stock deduction traceability
|
||||
每条 `step_save` 类型的变动记录 SHALL 包含以下溯源字段:
|
||||
|
||||
- `step_id` — 生产任务步骤 ID
|
||||
- `step_name` — 步骤名称快照
|
||||
- `task_id` — 生产任务 ID
|
||||
- `task_no` — 生产任务编号快照
|
||||
- `parent_usage_id` — 关联领用记录 ID(新流程必填;历史直接扣库为空)
|
||||
|
||||
#### Scenario: Stock log shows task and requisition info
|
||||
- **WHEN** 步骤保存触发 step_save 变动记录(新流程)
|
||||
- **THEN** 变动记录包含 step_id、task_id、task_no、parent_usage_id,且 stock_before 等于 stock_after
|
||||
|
||||
#### Scenario: Legacy stock log without parent
|
||||
- **WHEN** 查询历史 step_save(无 parent_usage_id)
|
||||
- **THEN** 仍展示 task_no/step 溯源;stock_before/stock_after 反映当时直接扣库结果
|
||||
|
||||
### Requirement: Deduction hooks in replace_step_reagents and replace_step_consumables
|
||||
步骤试剂/耗材替换函数 SHALL 调用 `revert_step_stock_changes()` + `register_step_usage_from_requisition()`(取代原 `deduct_for_step()` 直接扣库),调用时机不变:软删旧子记录前回退 stock_log,插入新子记录后登记新消耗。
|
||||
|
||||
#### Scenario: replace_step_consumables triggers requisition registration
|
||||
- **WHEN** API `PUT /production-tasks/{task_id}/steps/{step_id}/consumables` 被调用且含有效 requisitionUsageId
|
||||
- **THEN** 系统登记 step_save 关联流水,不扣减 consumable.stock_qty
|
||||
@@ -0,0 +1,52 @@
|
||||
# 生产物料库(统一)— Implementation Tasks
|
||||
|
||||
> Phase 0 融合 → A 批次/流水 → B 领用/工单 → C 盘点 → D 废弃 pack/旧菜单
|
||||
|
||||
## Phase 0 — 统一物料库 + 迁移
|
||||
|
||||
- [ ] 0.1 DDL:`biz_production_material`(含 material_type)+ 字典 `production_material_type`
|
||||
- [ ] 0.2 迁移脚本:consumable/reagent → production_material + id 映射 + INIT 批次
|
||||
- [ ] 0.3 Model `production_material.py`;CRUD 目录 list/get/create/update
|
||||
- [ ] 0.4 API `/production-materials`;旧 consumable/reagent 写接口 410
|
||||
- [ ] 0.5 菜单:【生产基础信息】下新增【生产物料库】;隐藏耗材管理、试剂管理
|
||||
- [ ] 0.6 前端:`production-material/index.vue` 骨架(三 Tab 占位 + 类型筛选)
|
||||
|
||||
## Phase A — 批次与变动流水
|
||||
|
||||
- [ ] A1 DDL:`production_material_stock_batch`、`production_material_usage`(含 step 溯源字段)
|
||||
- [ ] A2 CRUD batch + usage(参照 qc_material_stock_batch / qc_material_usage)
|
||||
- [ ] A3 入库/批量入库、领用/批量领用 API + 前端弹窗(对齐 QC)
|
||||
- [ ] A4 批次列表 Tab 完整实现
|
||||
- [ ] A5 变动记录 Tab(含 material_type、批次列)
|
||||
|
||||
## Phase B — 领用登记 + 生产工单 + 我的领用
|
||||
|
||||
- [ ] B1 step 子表 `requisition_usage_id`;usage `parent_usage_id`
|
||||
- [ ] B2 `register_step_usage_from_requisition()`;替换 step_save 直接扣库
|
||||
- [ ] B3 API:`production-material-requisition-options?materialType=`、`my-production-material-usages`
|
||||
- [ ] B4 菜单【我的物料领用记录】+ `my-production-material-usage/index.vue`
|
||||
- [ ] B5 `StepDetailPanel`:试剂/耗材 Tab 共用领用 API + 类型过滤
|
||||
|
||||
## Phase C — 库存盘点
|
||||
|
||||
- [ ] C1 DDL:stock_check + batch_line + unused_line(统一三表)
|
||||
- [ ] C2 CRUD + API(参照 qc_material_stock_check)
|
||||
- [ ] C3 `ProductionMaterialStockCheckTab.vue`(参照 QC)
|
||||
|
||||
## Phase D — 清理
|
||||
|
||||
- [ ] D1 耗材包 Tab/菜单/工艺导入下线
|
||||
- [ ] D2 删除或 redirect 旧 consumable/reagent 路由
|
||||
- [ ] D3 更新 `production-material-unification` 文档与 field consistency 脚本
|
||||
|
||||
## 验证
|
||||
|
||||
- [ ] V1 同一页面管理试剂+耗材;类型筛选正确
|
||||
- [ ] V2 批次领用 → 工单登记 → 【我的物料领用记录】可见
|
||||
- [ ] V3 月末盘点 Part A+B 完成不调账
|
||||
- [ ] V4 迁移后旧编码在步骤/工艺中仍可解析
|
||||
|
||||
## 评审
|
||||
|
||||
- [ ] Q1 生产物料库菜单挂载位置 — **已确认:生产基础信息**
|
||||
- [ ] Q2 material_type 字典项文案
|
||||
Reference in new issue
Block a user