docs: add lineage QC design/plan and pass project fields to material dialog
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
33c4408557
commit
56cee052d4
3 files changed
+1178
No files matched your search
@@ -0,0 +1,247 @@
|
||||
# 出库物料准备 — 细胞产品来源链质检查看设计
|
||||
|
||||
> 日期: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 响应骨架
|
||||
|
||||
```json
|
||||
{
|
||||
"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 查询规则
|
||||
|
||||
1. **链路**:`get_product_chain`;展平 nested ancestor `parent`;深度上限沿用 `_MAX_CHAIN_DEPTH`。
|
||||
2. **细胞产品工单**:`cell_product_id = node.id`,`del_flag=0`,租户过滤;**不限** `work_order_type`。
|
||||
3. **样本工单**:对齐 `list_work_orders_by_sample`;`reception_source` 缺失时该节点 `workOrders: []`,不 500。
|
||||
4. **任务**:复用 inspection batch → task → result / attachments 拼装;**不过滤**任务状态。
|
||||
5. **性能(一期)**:批量查工单与任务,避免 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 信息架构
|
||||
|
||||
自上而下:
|
||||
|
||||
1. 当前产品摘要条(编码 · 名称 · 代次)
|
||||
2. 按 `nodes` 分区(可折叠;默认均展开)
|
||||
- 样本:编码 + 来源标签
|
||||
- 产品:编码、名称、代次;当前节点 Tag「当前」+ 主色强调
|
||||
3. 工单卡片:工单号 · 类型 · 状态 Tag
|
||||
4. 任务卡片:对齐 `QcWorkOrderTaskResultPanel` 只读结构
|
||||
- 项目名、任务状态、结论 Tag
|
||||
- 检测参数
|
||||
- 备注(有则显示)
|
||||
- 附件(预览/下载,对齐现有附件卡片)
|
||||
5. 空态:节点无工单 →「暂无质检工单」;整单无数据 → 友好空状态
|
||||
|
||||
节点顺序:**上游 → 下游**(当前产品在最后)。
|
||||
|
||||
### 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 验收(产品语言)
|
||||
|
||||
1. 出库细胞行可打开「来源链质检」,列表保持简洁
|
||||
2. 可见该产品 + 全部上游样本/祖先产品的质检任务
|
||||
3. 每任务可见检测参数、结论、备注、附件;全部状态可见
|
||||
4. 再次打开为实时数据;不写入出库台账
|
||||
|
||||
## 7. 实现顺序建议
|
||||
|
||||
1. 后端:`get_product_lineage_qc` + 路由 + 单测(展平/样本键/批量)
|
||||
2. 前端 API + `CellProductLineageQcDialog`
|
||||
3. 接入 `OutboundReleaseMaterialDialog` 操作列
|
||||
4. 联调验收清单
|
||||
|
||||
## 8. 开放项(实现计划阶段闭合)
|
||||
|
||||
- 精确菜单权限码列表(对照 `docs/sql` 菜单)
|
||||
- 组件最终目录(`components/business` vs 业务目录)
|
||||
- 若 `outbound-material-form-sections` 与放行弹窗分叉,是否两边都接入口(默认:放行物料弹窗必做;共用组件则一并改)
|
||||
Reference in new issue
Block a user