15 KiB
质检工单 Tab 拆分与分型展示设计
日期:2026-06-16
状态:已确认(2026-06-16 组件边界已确认)
范围:web-admin质检工单 + 我的质检任务;后端列表 API 补充分型过滤
关联:2026-06-12-qc-work-order-fee-summary-design.md、outbound-qc-pilot-view-sections.ts、2026-06-10-basic-experiment-design.md
1. 背景与目标
1.1 问题
【质检工单】【我的质检任务】原有三 Tab(入库 / 出库 / 临时),同一 Tab 内混用字段模板,导致:
- 出库卡片出现入库字段(如「来源类型」
receptionSource) - 基础实验与中试/临床共用卡片 meta,关键业务字段缺失或错位
- 入库采集与捐赠在组头、查看弹窗混用「协议」语义
1.2 目标
将业务线拆为 6 个 Tab,每个 Tab 仅展示、仅查询 对应子类型的工单与任务;列表卡片、查看弹窗、筛选区与 Tab 一一对应。
1.3 非目标
- 不新增工单创建入口(捐赠入库仍由样本接收自动触发)
- 不改动质检任务执行、配置检测、物料使用逻辑
- 不在本期做「全部工单」汇总 Tab
- 不改动生产工单模块 Tab 结构
2. Tab 定义
2.1 Tab 配置表(权威)
| Tab Key | 展示标签 | workOrderType |
receptionSource |
bizType |
列表布局 |
|---|---|---|---|---|---|
inbound_cell_storage |
采集入库 | inbound |
cell_storage |
— | 样本分组 inbound-grouped |
inbound_research_donation |
捐赠入库 | inbound |
research_donation |
— | 样本分组 inbound-grouped |
outbound_pilot_service |
中试 | outbound |
— | pilot_service |
单列 standalone |
outbound_basic_experiment |
基础实验 | outbound |
— | basic_experiment |
单列 standalone |
outbound_clinical_application |
临床应用 | outbound |
— | clinical_application |
单列 standalone |
temporary |
临时 | temporary |
— | — | 单列 standalone |
Tab 栏视觉分组(可选 CSS): 入库 2 | 出库 3 | 临时 1,标签使用短文案。
默认 Tab: inbound_cell_storage(替换原 inbound)。
路由记忆: ?tab=<tabKey>,刷新/分享链接保持当前 Tab。
2.2 数据隔离规则(强约束)
每个 Tab 的列表 API 请求 必须同时携带 上表中的过滤参数,禁止仅传 workOrderType 后在客户端再筛:
采集入库 → workOrderType=inbound AND receptionSource=cell_storage
捐赠入库 → workOrderType=inbound AND receptionSource=research_donation
中试 → workOrderType=outbound AND bizType=pilot_service
基础实验 → workOrderType=outbound AND bizType=basic_experiment
临床应用 → workOrderType=outbound AND bizType=clinical_application
临时 → workOrderType=temporary
验收: 在任一 Tab 下,列表中不得出现其它子类型的工单;切换 Tab 后分页重置为第 1 页。
3. 筛选区(按 Tab)
移除原「业务类型」「来源类型」下拉(已由 Tab 固定)。
| Tab | 关键词 placeholder | 时间筛选标签 | 时间字段 | 额外筛选 |
|---|---|---|---|---|
| 采集入库 | 工单号/样本编码/入库编码 | 创建时间 | createTime |
触发来源(样本接收 / 生产过程) |
| 捐赠入库 | 工单号/样本编码/入库编码 | 创建时间 | createTime |
触发来源 |
| 中试 | 工单号/申请单号/申请单名称/患者 | 输注时间 | infusionTime |
— |
| 基础实验 | 工单号/申请单号/课题名称/客户 | 交付时间 | infusionTime(schedule 提货时间) |
— |
| 临床应用 | 工单号/申请单号/申请单名称/患者 | 输注时间 | infusionTime |
— |
| 临时 | 工单号 | 创建时间 | createTime |
— |
默认时间范围:近 30 天(出库类按输注/交付时间,入库/临时按创建时间)。
4. 组件边界(已确认)
| 模块 | 策略 | 说明 |
|---|---|---|
QcWorkOrderTaskSubList |
共用 | 任务执行、填结果、物料与 Tab 无关 |
| 配置检测 / 调整检测弹窗 | 共用 | 三种工单类型逻辑相同 |
QcWorkOrderCardList + QcWorkOrderSampleGroup + QcWorkOrderSingleCard |
共用 | 各 Tab 通过 props 传入卡片 meta 字段模板(组头文案、meta 列、费用条开关) |
| 查看详情弹窗 | 不共用 | 六 Tab 各一份独立查看界面;信息区块差异大,禁止再用 Host + variant 分支 |
| Tab 页内容(筛选 + 工具栏 + 列表) | 拷贝再改 | 从现有入库/出库/临时 Tab 剪出/拷贝为 6 个子页面;index.vue 仅 Tab 壳 |
我的质检任务: 与质检工单 共用同一套 6 个 Tab 子组件(tabs/*),已确认。差异仅:
- prop
pageMode='mine' - 卡片操作:仅「查看」,无配置检测 / 新增 / 删除等
- 任务区
taskListMode='mine' - 数据:
GET /qc-tasks/mine+ 与 Tab 一致的receptionSource/bizType过滤
维护成本: 6 个 Tab 文件 + 2 个壳页面(qc-work-order/index.vue、my-qc-task/index.vue),不是 12 份拷贝。
5. 列表卡片展示矩阵
共用 QcWorkOrderCardList / QcWorkOrderSampleGroup / QcWorkOrderSingleCard;各 Tab 子页面传入不同的 cardMetaConfig(字段 label、取值、Tag、费用条),禁止在卡片内用 activeTypeTab === 'outbound' 大包大揽。
5.1 入库 · 采集(inbound_cell_storage)
样本组头(QcWorkOrderSampleGroup)
- 样本编码、样本类型、采集协议号、协议状态、接收时间、经手人
组内费用条(组级,已有逻辑扩展)
- 组内存在
cell_storage工单且paymentSummary时展示QcWorkOrderProtocolPaymentPanel
卡片 meta
- 质检对象、触发来源 Tag、关联生产工单(仅
triggerSource=production)、实验室入库编码、检测方式、创建时间、备注
卡片费用条
paymentSummary(QcWorkOrderProtocolPaymentPanelcompact)
工具栏
- 「新增入库质检工单」(仅本 Tab;
receptionSource固定cell_storage)
5.2 入库 · 捐赠(inbound_research_donation)
样本组头
- 样本编码、样本类型、捐赠单号(
protocolNo字段存捐赠编号)、捐赠状态、接收时间、经手人
卡片 meta
- 同采集入库卡片结构;不展示协议状态、费用相关字段
工具栏
- 无新增按钮
5.3 出库 · 中试(outbound_pilot_service)
卡片 meta
- 申请单号、申请单名称、渠道名称、患者姓名、第 N 次 / 共 M 次、输注时间、检测方式、创建时间、备注
禁止展示
receptionSource、业务类型 Tag(Tab 已表达)、基础实验专属字段
费用条
- 不展示
5.4 出库 · 基础实验(outbound_basic_experiment)
卡片 meta
- 申请单号、课题名称、客户名称、交付时间、售卖金额(可选,来自
feeSummary.saleAmount)、检测方式、创建时间、备注
费用条
QcWorkOrderFeeSummaryBar(feeSummary)
5.5 出库 · 临床应用(outbound_clinical_application)
卡片 meta
- 申请单号、申请单名称、渠道名称、患者姓名、第 N 次 / 共 M 次、输注时间、检测方式、创建时间、备注
费用条
QcWorkOrderFeeSummaryBar(与2026-06-13-production-work-order-fee-summary-design.mdD1=B 一致)
5.6 临时(temporary)
保持现状:产品编码/名称/类型、检测方式、创建时间;工具栏「新增临时工单」。
6. 查看弹窗(六份独立界面)
不共用 QcWorkOrderViewDialogHost、OutboundQcViewDialog 及其中 variant 分支。自现有弹窗拷贝后按 Tab 删减字段;检测任务区块(实验室/第三方/参数/附件/物料)可抽 useQcWorkOrderTaskViewSections.ts 供六弹窗 import,避免任务展示逻辑拷六份。
6.1 Tab → 弹窗组件(一一对应)
| Tab Key | 新建组件 | 拷贝来源 | 主要差异 |
|---|---|---|---|
inbound_cell_storage |
InboundCellStorageViewDialog.vue |
现 QcWorkOrderViewDialogHost + useQcWorkOrderViewDialog |
协议状态、协议缴费、运输、样本接收 |
inbound_research_donation |
InboundResearchDonationViewDialog.vue |
上者拷贝 | 无协议缴费;捐赠状态;组头/基本信息用捐赠文案 |
outbound_pilot_service |
OutboundPilotViewDialog.vue |
现 OutboundQcViewDialog |
仅中试:申请单、患者、输注方案/计划、产品、检测任务;无缴费区块 |
outbound_basic_experiment |
OutboundBasicExperimentViewDialog.vue |
出库弹窗拷贝 | 课题/客户/交付计划/产品/缴费;无患者、输注方案 |
outbound_clinical_application |
OutboundClinicalViewDialog.vue |
出库弹窗拷贝 | 同中试结构 + 临床应用缴费信息(如有) |
temporary |
TemporaryQcViewDialog.vue |
入库弹窗拷贝 | 仅产品信息 + 检测任务;无接收/运输/协议 |
6.2 挂载方式
- 各 Tab 子页面 内直接
import对应弹窗,:visible+@view打开;不再使用统一openView(row)按类型分流。 - 旧文件
QcWorkOrderViewDialogHost.vue、OutboundQcViewDialog.vue在六弹窗落地并切换引用后删除(或首版标记@deprecated再删)。
6.3 可共用的底层(非 UI 壳)
| 共用项 | 说明 |
|---|---|
SystemViewDialog |
布局壳 |
ProtocolAttachmentReadonly |
附件只读 |
QcWorkOrderProtocolPaymentPanel |
仅采集入库弹窗使用 |
fetchQcWorkOrderDetail / fetchOutboundQcDetail |
API |
useQcWorkOrderTaskViewSections(新建) |
检测任务 sections + 附件 slot + 物料 slot |
7. Tab 子页面结构(拷贝再改)
web-admin/src/views/quality-inspection/qc-work-order/
index.vue # 6 Tab 壳 + ?tab= 路由
tabs/
InboundCellStorageTab.vue # 从原 index 入库区块剪出
InboundResearchDonationTab.vue # 拷贝 InboundCellStorageTab 再改
OutboundPilotTab.vue # 从原出库区块剪出
OutboundBasicExperimentTab.vue # 拷贝 OutboundPilotTab 再改
OutboundClinicalTab.vue # 拷贝 OutboundPilotTab 再改
TemporaryTab.vue # 从原临时区块剪出
view-dialogs/
InboundCellStorageViewDialog.vue
InboundResearchDonationViewDialog.vue
OutboundPilotViewDialog.vue
OutboundBasicExperimentViewDialog.vue
OutboundClinicalViewDialog.vue
TemporaryQcViewDialog.vue
my-qc-task/index.vue 同样 6 Tab 壳,import 上述 tabs/* 组件,传 page-mode="mine"。
8. 我的质检任务
与质检工单 共用 tabs/* 子组件与 cardMetaConfig;差异:
pageMode='mine':卡片仅「查看」- 任务列表
taskListMode='mine' - 数据流:先按 Tab 参数请求
GET /qc-tasks/mine,再聚合为卡片
后端扩展 list_mine_tasks: 增加 receptionSource、bizType 过滤,与工单列表对齐,避免客户端从全量任务中筛类型。
qc-mine-task-groups.ts:
QcWorkOrderTypeTab替换为QcWorkOrderTabKeyresolveWorkOrderTabKey(task)由workOrderType+receptionSource/bizType解析filterMineEntriesByWorkOrderSearch按tabKey固定过滤,移除bizType/receptionSource筛选项
9. 后端 API 变更
7.1 GET /qc-work-orders(列表)
新增 Query 参数:
| 参数 | 类型 | 说明 |
|---|---|---|
receptionSource |
string | 入库分型:cell_storage / research_donation |
list_work_orders() 在 work_order_type=inbound 且 reception_source 有值时:
q0 = q0.filter(BizQcWorkOrder.reception_source == rs)
出库 Tab 继续传 bizType(已有)。
7.2 GET /qc-tasks/mine
新增 Query 参数:receptionSource、bizType,在 join BizQcWorkOrder 后过滤。
7.3 列表 enrich
确认基础实验列表项含 projectTitle(课题名称)、customerName;缺则于 _enrich_outbound_list_fields 补充 join。
10. 前端模块结构(摘要)
web-admin/src/utils/qc-work-order-tabs.ts # Tab 常量 + toListQueryParams
web-admin/src/utils/qc-work-order-card-meta.ts # 六 Tab 的 cardMetaConfig 导出(供 CardList props)
web-admin/src/views/.../qc-work-order/tabs/ # 6 Tab 子页面(拷贝再改)
web-admin/src/views/.../qc-work-order/view-dialogs/ # 6 独立查看弹窗
web-admin/src/views/.../qc-work-order/composables/useQcWorkOrderTaskViewSections.ts # 检测任务区块共用
共用不改业务: QcWorkOrderTaskSubList、配置检测弹窗(仍在 index.vue 或 composable)。
删除/替换: QcWorkOrderViewDialogHost.vue、OutboundQcViewDialog.vue、useQcWorkOrderViewDialog.ts(逻辑拆入六弹窗 + task composable)。
11. 验收清单
11.1 数据隔离
- 采集入库 Tab 仅
receptionSource=cell_storage的 inbound 工单 - 捐赠入库 Tab 仅
research_donation的 inbound 工单 - 中试 / 基础实验 / 临床 Tab 各自仅对应
bizType的 outbound 工单 - 临时 Tab 仅
workOrderType=temporary - 我的质检任务六 Tab 与上相同(任务所属工单类型一致)
11.2 展示
- 出库卡片无
receptionSource字段 - 基础实验卡片无患者/输注疗程字段,有课题/客户/交付时间
- 捐赠组头为捐赠单号/捐赠状态,非协议文案
- 采集入库查看弹窗有协议缴费;捐赠无
- 六 Tab 各打开对应独立查看弹窗,无交叉引用 Host/variant
- 基础实验查看弹窗无患者/输注方案;中试/临床无课题专属区块
11.3 操作
- 仅采集入库 Tab 有「新增入库质检工单」
- 仅临时 Tab 有「新增临时工单」
- 配置检测 / 调整检测 / 编辑备注行为与改版前一致
11.4 回归
- Tab 切换重置分页与筛选(保留 Tab 专属默认时间范围)
- URL
?tab=可深链到指定 Tab - 费用摘要条规则与
2026-06-12-qc-work-order-fee-summary-design.md一致
12. 决策记录
| 项 | 决策 |
|---|---|
| Tab 数量 | 6(入库 2 + 出库 3 + 临时 1) |
| Tab 标签 | 短标签:采集入库 / 捐赠入库 / 中试 / 基础实验 / 临床应用 / 临时 |
| 实现策略 | Tab 子页面拷贝再改;index.vue 仅 Tab 壳 |
| 数据过滤 | 服务端 强制分型,禁止仅靠前端过滤 |
| TaskSubList | 共用 |
| 配置检测弹窗 | 共用 |
| CardList + SampleGroup | 共用,props 传 cardMetaConfig |
| 查看弹窗 | 六份独立界面,不共用 Host / OutboundQcViewDialog |
| 检测任务展示 | composable 共用,避免六份弹窗重复任务 UI 逻辑 |
| 我的质检任务 | 已确认 共用 6 个 tabs/*,pageMode='mine' |