9.4 KiB
9.4 KiB
出库物料准备 — 细胞产品来源链质检查看设计
日期:2026-07-29
状态:已确认(brainstorming)
方案:A(后端聚合接口 + 独立只读弹窗)
入口:出库放行审核 → 出库物料准备 → 出库细胞列表
1. 需求概述
在「出库物料准备」弹窗的「出库细胞」列表中,用户可通过行操作查看所选细胞产品相关的质检信息,用于放行前核对。
必须展示:
- 质检任务的检测参数、结论、备注、附件(业务所称「检测材料」= 质检任务附件)
- 整条来源链上的质检:祖先细胞产品 + 上游样本相关质检(不仅当前产品)
- 全部任务状态(待配置 / 进行中 / 已完成等,含未完成)
数据策略:实时查询,不写入出库台账快照;质检事后变更后再次打开可见最新结果。
交互:主列表保持简洁;行上「查看质检」打开独立弹窗(非行内展开)。
1.1 已确认决策
| 项 | 选择 |
|---|---|
| 父级范围 | B:整条来源链(祖先细胞产品 + 上游样本) |
| 任务状态 | B:全部状态 |
| 检测材料 | 质检任务附件(非出库 qcMaterials 库存扣减,非实验室物料使用明细) |
| 交互 | B:行按钮 → 独立弹窗 |
| 数据 | A:实时查询 |
| 实现路径 | A:后端聚合 API + 只读弹窗 |
1.2 非目标(本期不做)
- 出库保存时落质检快照
- 行内展开 / 添加细胞时自动弹出质检
- 改造细胞库来源链图谱(
/chain可视化) - 展示实验室任务「物料使用」库存明细
- 同步改造出库审核弹窗 / 查看出库详情(若需要另开需求)
- 前端拼装多次现有接口作为主方案
2. 背景与现有能力
2.1 传代 / 来源链
biz_cell_product 无 parent_id。父子关系来自生产任务投入/产出:
- 祖先:
get_product_chain→_build_ancestor_chain(backend/app/crud/cell_product.py) - 前端已有:
fetchCellProductChain→GET /web/admin/cell-products/{id}/chain - 设计参考:
docs/superpowers/specs/2026-05-24-cell-product-source-chain-design.md
本需求只消费 current + ancestors,不取 descendants。
2.2 质检关联
- 细胞产品:
BizQcWorkOrder.cell_product_id - 样本入库质检:
list_work_orders_by_sample(sample_code+reception_source,work_order_type=inbound) - 任务详情字段:
results(参数)、conclusion/remark、attachmentFiles(由附件 URL 解析) - 只读 UI 参考:
web-admin/.../QcWorkOrderTaskResultPanel.vue
2.3 出库物料弹窗现状
- 组件:
OutboundReleaseMaterialDialog.vue - 出库细胞仅存
cellProductId等台账字段;保存逻辑不因本需求变更
3. 架构与数据流
出库细胞行 [查看质检]
│
▼
GET /web/admin/cell-products/{id}/lineage-qc
│
├─ get_product_chain(复用)→ current + ancestors
├─ 展平节点(根→叶,当前最后;按 nodeType+id 去重)
├─ cell_product 节点:按 cell_product_id 查工单(不限 work_order_type)
├─ sample 节点:按 sampleCode + receptionSource 查入库质检
└─ 工单批量拉任务详情(参数/结论/备注/附件;不过滤状态)
│
▼
el-dialog「来源链质检」只读展示
4. 后端设计
4.1 接口
- 方法/路径:
GET /web/admin/cell-products/{product_id}/lineage-qc - 注册:与
/chain同域(backend/app/api/production.py) - 编排:
get_product_lineage_qc(建议在cell_product.py,内部复用 qc CRUD,禁止复制序列化逻辑)
4.2 响应骨架
{
"productId": "...",
"productCode": "...",
"productName": "...",
"nodes": [
{
"nodeType": "sample | cell_product",
"id": "...",
"label": "样本编码或产品编码",
"productName": "...",
"passage": "P1",
"receptionSource": "cell_storage | research_donation | null",
"isCurrent": false,
"workOrders": [
{
"id": "...",
"workOrderNo": "...",
"workOrderType": "...",
"workOrderStatus": "...",
"workOrderStatusLabel": "...",
"tasks": [
{
"id": "...",
"taskNo": "...",
"itemName": "...",
"itemCode": "...",
"taskType": "...",
"taskStatus": "...",
"conclusion": "...",
"conclusionLabel": "...",
"remark": "...",
"completedTime": "...",
"results": [
{ "paramName": "", "paramValue": "", "paramUnit": "" }
],
"attachmentFiles": [
{ "fileName": "", "fileUrl": "", "fileType": "" }
]
}
]
}
]
}
]
}
字段命名与现有质检详情 camelCase 对齐,便于前端复用 Tag/附件组件。
4.3 查询规则
- 链路:
get_product_chain;展平 nested ancestorparent;深度上限沿用_MAX_CHAIN_DEPTH。 - 细胞产品工单:
cell_product_id = node.id,del_flag=0,租户过滤;不限work_order_type。 - 样本工单:对齐
list_work_orders_by_sample;reception_source缺失时该节点workOrders: [],不 500。 - 任务:复用 inspection batch → task → result / attachments 拼装;不过滤任务状态。
- 性能(一期):批量查工单与任务,避免 N 次串行
get_work_order_detail;全量一次返回。二期可按节点懒加载。
4.4 错误与边界
| 情况 | 行为 |
|---|---|
| 产品不存在 / 跨租户 | 业务 400/404,文案明确 |
| 无祖先(如手动录入) | nodes 仅含 current |
| 节点无工单 | 仍返回节点,workOrders: [] |
| 单节点加载异常 | 该节点空列表 + 可选 loadError,不拖垮整响应 |
| 附件 URL 坏项 | 跳过该项 |
4.5 权限
- 能进入「出库物料准备」的用户应能调用本只读接口。
- 实现时使用
require_any_menu_code:任一匹配即可——出库放行相关菜单码,或质检工单列表码,或细胞产品查看码(具体码表在实现计划中对照菜单 SQL 写死)。 - 租户隔离强制。数据范围:优先按工单
tenant_no过滤;若套用质检 data scope 会导致「能准备出库物料却看不到质检」则本期对放行入口放宽为租户内只读(实现计划写明最终策略)。
5. 前端设计
5.1 入口
- 文件:
OutboundReleaseMaterialDialog.vue(及若共用的outbound-material-form-sections,以实现时是否共用为准;至少出库放行物料弹窗落地) - 出库细胞操作列增加「查看质检」(
View图标 + 文案);保留「删除」 - 操作列
min-width约 ≥ 180px - 仅存在
cellProductId时可点
5.2 弹窗组件
- 新建
CellProductLineageQcDialog.vue(建议components/business/或outbound-release-review/) el-dialog+dialog-form-layout,宽约 960–1120px,append-to-body,无 backdrop blur- 标题:
来源链质检;副信息:当前产品编码 / 名称 - 打开时请求
lineage-qc;v-loading;失败ElMessage.error - 底栏仅「关闭」(Close 图标)
5.3 信息架构
自上而下:
- 当前产品摘要条(编码 · 名称 · 代次)
- 按
nodes分区(可折叠;默认均展开)- 样本:编码 + 来源标签
- 产品:编码、名称、代次;当前节点 Tag「当前」+ 主色强调
- 工单卡片:工单号 · 类型 · 状态 Tag
- 任务卡片:对齐
QcWorkOrderTaskResultPanel只读结构- 项目名、任务状态、结论 Tag
- 检测参数
- 备注(有则显示)
- 附件(预览/下载,对齐现有附件卡片)
- 空态:节点无工单 →「暂无质检工单」;整单无数据 → 友好空状态
节点顺序:上游 → 下游(当前产品在最后)。
5.4 API 封装
web-admin/src/api/cell-product.ts增加fetchCellProductLineageQc(productId)
5.5 UI 规范
- Fresh Mint;状态/结论用
el-tag+status-tag-registry - 按钮带图标;遮罩无模糊
6. 测试与验收
6.1 后端
- 仅 current、无祖先
- P1→P2→当前,顺序与挂载正确
- 链上样本节点挂入库质检
- 多状态任务与参数/结论/备注/附件齐全
- 产品不存在、租户隔离、深度截断
6.2 前端
- 独立弹窗不打断主弹窗编辑
- loading / 错误 / 空态
- 附件可预览下载
- 操作列不被裁切
6.3 验收(产品语言)
- 出库细胞行可打开「来源链质检」,列表保持简洁
- 可见该产品 + 全部上游样本/祖先产品的质检任务
- 每任务可见检测参数、结论、备注、附件;全部状态可见
- 再次打开为实时数据;不写入出库台账
7. 实现顺序建议
- 后端:
get_product_lineage_qc+ 路由 + 单测(展平/样本键/批量) - 前端 API +
CellProductLineageQcDialog - 接入
OutboundReleaseMaterialDialog操作列 - 联调验收清单
8. 开放项(实现计划阶段闭合)
- 精确菜单权限码列表(对照
docs/sql菜单) - 组件最终目录(
components/businessvs 业务目录) - 若
outbound-material-form-sections与放行弹窗分叉,是否两边都接入口(默认:放行物料弹窗必做;共用组件则一并改)