2026-08-20-temporary-qc-external-target-code-design.md 5.9 KB

临时质检 · 外部质检对象编号(手写)设计

日期: 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 不可再对「外部路径」强制必填;拆成按来源分支校验