Record the agreed approach for hand-entered external QC object codes on temporary work orders. Co-authored-by: Cursor <cursoragent@cursor.com>
5.9 KiB
临时质检 · 外部质检对象编号(手写)设计
日期: 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 的手动写入:
- 系统产品:
cell_product_id必填且在本租户存在;external_target_code必须为空(写库时清空) - 外部编号:
external_target_code必填(trim 后非空且 ≤64);cell_product_id必须为空(写库时清空) - 二者不可同时有值;亦不可同时为空
入库/出库工单、生产派发临时质检:不应用上述外部编号写入路径(派发仍只写既有 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 新增/编辑弹窗。
- 来源类型:二选一(系统细胞产品 / 外部科研编号)
- 质检对象:
- 系统:现有远程搜索下拉(
fetchCellProductList) - 外部:单行输入,placeholder「请输入外部编号」
- 系统:现有远程搜索下拉(
- 备注:不变
行为:
- 新增默认「系统细胞产品」
- 编辑:有
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. 验收标准
- 系统产品路径:行为与现网一致(选产品、建单、列表/详情展示产品信息)
- 外部编号路径:可建单、可编辑;可切换来源;库中
cell_product_id为空且external_target_code有值 - 同一外部编号可创建多张临时工单
- 列表卡片标题与详情可见外部编号
- 生产派发临时质检回归无回归问题(链路代码未改或行为不变)
10. 风险与注意
- 历史临时工单均无
external_target_code,展示逻辑须兼容「仅有 cell_product_id」 - 编辑时从外部切到系统(或反向)须清空对侧字段,避免脏数据写入
_validate_cell_product_id不可再对「外部路径」强制必填;拆成按来源分支校验