Record the agreed approach for hand-entered external QC object codes on temporary work orders. Co-authored-by: Cursor <cursoragent@cursor.com>
131 lines
5.9 KiB
Markdown
131 lines
5.9 KiB
Markdown
# 临时质检 · 外部质检对象编号(手写)设计
|
||
|
||
**日期:** 2026-08-20
|
||
**状态:** 已评审待实现
|
||
**范围:** web-admin 质检工单「临时质检」手动新增/编辑 + 列表/详情展示;backend `biz_qc_work_order` 字段与校验
|
||
|
||
## 1. 背景与问题
|
||
|
||
当前「新增临时质检工单」弹窗中「质检对象」仅能从系统细胞产品主数据(`GET /web/admin/cell-products` → `biz_cell_product`)选择;创建/更新时后端强制校验 `cell_product_id` 必须存在。
|
||
|
||
客户场景:部分样品来自外部科研机构,**不在系统细胞产品库中**,希望能手写一个编号作为质检对象标识。
|
||
|
||
## 2. 需求结论(已确认)
|
||
|
||
| 项 | 结论 |
|
||
|---|---|
|
||
| 交互 | 方案 A:来源切换(系统细胞产品 / 外部科研编号) |
|
||
| 外部信息 | 只要一个编号 |
|
||
| 唯一性 | 不强制;同一编号可多次建单(复检/多批次) |
|
||
| 格式 | 无特殊格式;trim 后非空,最长 64 |
|
||
| 与细胞产品关联 | 不需要;全程不绑细胞产品,纯展示标识 |
|
||
| 范围 | 手动新增/编辑 + 列表/详情展示;**生产派发临时质检链路不动** |
|
||
|
||
## 3. 方案选择
|
||
|
||
采用 **方案 1:工单表增加外部编号字段**。
|
||
|
||
- 不借用 `sample_code` / `remark`(语义污染)
|
||
- 不为外部编号自动创建伪细胞产品(污染主数据,且与「不绑定」冲突)
|
||
- 不新增独立 `qc_target_source` 列:由 `cell_product_id` 与 `external_target_code` 互斥存在推导来源
|
||
|
||
## 4. 数据模型
|
||
|
||
### 4.1 表字段
|
||
|
||
表:`biz_qc_work_order`
|
||
|
||
| 字段 | 类型 | 可空 | 说明 |
|
||
|---|---|---|---|
|
||
| `external_target_code` | `VARCHAR(64)` | YES | 外部质检对象编号(手写) |
|
||
|
||
放置位置:业务字段区,建议紧挨 `cell_product_id` 之后。同步更新 SQLAlchemy `BizQcWorkOrder`、`docs/sql/` 增量脚本。
|
||
|
||
### 4.2 互斥不变量(仅临时工单手动创建/编辑)
|
||
|
||
对 `work_order_type = temporary` 的手动写入:
|
||
|
||
1. **系统产品**:`cell_product_id` 必填且在本租户存在;`external_target_code` 必须为空(写库时清空)
|
||
2. **外部编号**:`external_target_code` 必填(trim 后非空且 ≤64);`cell_product_id` 必须为空(写库时清空)
|
||
3. 二者不可同时有值;亦不可同时为空
|
||
|
||
入库/出库工单、生产派发临时质检:**不应用上述外部编号写入路径**(派发仍只写既有 `cell_product_id` 逻辑)。
|
||
|
||
### 4.3 API 契约
|
||
|
||
**创建/更新请求(临时):**
|
||
|
||
- 保留 `cellProductId`(可选)
|
||
- 新增 `externalTargetCode`(可选)
|
||
- 服务端按互斥规则校验并归一化(另一侧置空)
|
||
|
||
**列表/详情响应:**
|
||
|
||
- 继续返回 `cellProductId` / `cellProductCode` / `cellProductName` / 类型等(有关联时 enrich)
|
||
- 新增 `externalTargetCode`
|
||
- 不强制返回 `qcTargetSource`;前端可用字段有无推导
|
||
|
||
**列表 keyword:** 临时质检列表现有 keyword 仅匹配工单号;本期在临时工单(及通用列表在 `work_order_type=temporary` 或未限定类型时)keyword 条件中增加 `external_target_code` 模糊匹配。
|
||
|
||
## 5. 前端交互(方案 A)
|
||
|
||
文件焦点:`web-admin/src/views/quality-inspection/qc-work-order/index.vue` 新增/编辑弹窗。
|
||
|
||
1. **来源类型**:二选一(系统细胞产品 / 外部科研编号)
|
||
2. **质检对象**:
|
||
- 系统:现有远程搜索下拉(`fetchCellProductList`)
|
||
- 外部:单行输入,placeholder「请输入外部编号」
|
||
3. **备注**:不变
|
||
|
||
行为:
|
||
|
||
- 新增默认「系统细胞产品」
|
||
- 编辑:有 `cellProductId` → 系统并回填;有 `externalTargetCode` → 外部并回填
|
||
- 切换来源时清空另一侧已填值
|
||
- 提交只带当前来源字段;另一侧传空
|
||
|
||
前端校验与后端错误文案对齐:「请选择质检对象」「请填写外部编号」。
|
||
|
||
## 6. 列表 / 详情展示
|
||
|
||
| 场景 | 系统产品 | 外部编号 |
|
||
|---|---|---|
|
||
| 卡片主标题 `resolveTemporaryWorkOrderCardTitle` | `cellProductCode` | `externalTargetCode` |
|
||
| 卡片 meta(产品名称/类型等) | 照旧 | 增加「质检对象」展示外部编号;产品名称/类型显示 `—` |
|
||
| 详情 `buildTemporaryViewSections` | 产品编码/名称/类型等 | 「质检对象」= 外部编号 + Tag「外部」;产品字段 `—` |
|
||
| 任务子列表等同类「质检对象」展示 | 同步兜底外部编号 | 同上 |
|
||
|
||
列表卡片**不强制**加「外部」Tag(避免多色);详情用 Tag 区分。
|
||
|
||
## 7. 改动面清单
|
||
|
||
| 层 | 内容 |
|
||
|---|---|
|
||
| SQL | `docs/sql/` 增加 `external_target_code` |
|
||
| Backend | `models` / `schemas` / `crud`:`create_temp_qc_work_order`、`update_qc_work_order`、列表 `_row_to_dict` / enrich、keyword |
|
||
| Frontend API | `QcWorkOrder` 类型增加 `externalTargetCode` |
|
||
| 弹窗 | `qc-work-order/index.vue` |
|
||
| 卡片 | `qc-work-order-card-meta.ts`(标题 + temporaryFields) |
|
||
| 详情 | `inbound-view-sections.ts` 中 `buildTemporaryViewSections`;相关任务子列表展示若有则一并 |
|
||
|
||
## 8. 明确不做
|
||
|
||
- 生产派发临时质检链路改造
|
||
- 外部编号唯一性、格式正则
|
||
- 自动创建细胞产品或事后关联回产品
|
||
- 入库/出库工单的质检对象模型变更
|
||
|
||
## 9. 验收标准
|
||
|
||
1. 系统产品路径:行为与现网一致(选产品、建单、列表/详情展示产品信息)
|
||
2. 外部编号路径:可建单、可编辑;可切换来源;库中 `cell_product_id` 为空且 `external_target_code` 有值
|
||
3. 同一外部编号可创建多张临时工单
|
||
4. 列表卡片标题与详情可见外部编号
|
||
5. 生产派发临时质检回归无回归问题(链路代码未改或行为不变)
|
||
|
||
## 10. 风险与注意
|
||
|
||
- 历史临时工单均无 `external_target_code`,展示逻辑须兼容「仅有 cell_product_id」
|
||
- 编辑时从外部切到系统(或反向)须清空对侧字段,避免脏数据写入
|
||
- `_validate_cell_product_id` 不可再对「外部路径」强制必填;拆成按来源分支校验
|