2026-06-16-production-work-order-tab-split-design.md 12 KB

生产工单 Tab 拆分与分型展示设计

日期:2026-06-16
状态:已确认方向(Tab 命名 + 拷贝再改策略 + 临床应用 hidden)
范围:web-admin 生产工单 + 我的生产任务;后端列表 / mine API 补充分型过滤
参照:docs/superpowers/specs/2026-06-16-qc-work-order-tab-split-design.md(质检侧已落地)


1. 背景与目标

1.1 问题

【生产工单】【我的生产任务】现为 3 Tab(入库 / 出库 / 临时),同一 Tab 内混用字段模板:

  • 出库卡片/弹窗出现入库字段(来源类型、协议状态等)
  • 基础实验与中试/临床共用 outbound 模板,课题/客户 vs 患者/输注错位
  • 入库 Tab 内细胞存储与科研捐赠协议语义混用

1.2 目标

拆为 6 个业务 Tab,每个 Tab 仅查、仅展示 对应子类型;列表卡片、查看弹窗与 Tab 一一对应。

1.3 已确认产品决策

项 决策
Tab 展示名 细胞存储生产 / 科研捐赠生产 / 中试服务生产 / 基础实验生产 / 临床应用生产(hidden)/ 临时生产
实施策略 拷贝再改(从现有 3 Tab 界面剪出/拷贝为 6 份,再按子类型删减字段)
临床应用 Tab hidden: true,Tab 栏不展示;保留 key 与弹窗文件供数据解析/后续开放
默认 Tab inbound_cell_storage
路由 ?tab=<tabKey>

1.4 非目标

  • 不在本期做「全部工单」汇总 Tab
  • 不改动任务执行、派发、完成、样本接收等 业务流程(仅调整展示与列表隔离)
  • 不改动质检工单模块

2. Tab 定义(权威)

Tab Key 展示标签 workOrderType receptionSource bizType hidden
inbound_cell_storage 细胞存储生产 inbound cell_storage —
inbound_research_donation 科研捐赠生产 inbound research_donation —
outbound_pilot_service 中试服务生产 outbound — pilot_service
outbound_basic_experiment 基础实验生产 outbound — basic_experiment
outbound_clinical_application 临床应用生产 outbound — clinical_application 是
temporary 临时生产 temporary — —

2.1 数据隔离(强约束)

每个 Tab 列表请求 必须 携带上表过滤参数,禁止 仅传 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. 实施策略:拷贝再改(已确认)

3.1 为什么采用拷贝再改

用户明确要求:从已稳定运行的 3 Tab 界面拷贝,再按子类型删减,以最大幅度保留现有业务逻辑(筛选、分页、工具栏、卡片事件、查看弹窗 sections),避免在单一文件内继续堆 activeTypeTab / bizType 分支。

这与质检改造 组件边界一致;质检在 Tab 子页上最终用 QcWorkOrderTabPanel 收敛,生产侧按产品要求 保留 6 份更独立的 Tab 文件(拷贝痕迹可见、 diff 清晰)。

3.2 拷贝来源映射

新 Tab 文件 拷贝自(现状) 改造要点
tabs/InboundCellStorageTab.vue 现 index.vue 在 activeTypeTab === 'inbound' 时的筛选+列表+查看逻辑 写死 receptionSource=cell_storage;卡片/弹窗保留协议、协议费用、样本接收
tabs/InboundResearchDonationTab.vue 拷贝上一行 写死 research_donation;去掉协议缴费;状态文案改为捐赠
tabs/OutboundPilotTab.vue 现 index.vue 在 activeTypeTab === 'outbound' 且中试字段逻辑 写死 bizType=pilot_service;保留患者/输注/诊断附件
tabs/OutboundBasicExperimentTab.vue 拷贝 outbound Tab 写死 basic_experiment;去掉患者/输注方案;保留课题/客户/交付
tabs/OutboundClinicalTab.vue 拷贝 outbound Tab 写死 clinical_application;hidden;保留临床+缴费
tabs/TemporaryTab.vue 现 activeTypeTab === 'temporary' 区块 写死 temporary;仅最小字段+任务

查看弹窗: 各 Tab 内 独立一份 view-dialogs/*ViewDialog.vue(从现 index.vue 内联 SystemViewDialog + useProductionWorkOrderViewDialog 拷贝再改),禁止继续用 ProductionWorkOrderViewDialogHost + 大 variant 分支。

3.3 仍共用(不拷贝 6 份)

模块 理由
WorkOrderTaskSubList 及任务执行/派发/完成/转发弹窗 与 Tab 子类型无关,逻辑复杂,拷贝 6 份维护成本过高
production-work-order/index.vue 壳层管理弹窗 新增临时工单、派发任务、派发质检、样本接收、批量完成等 与 Tab 无关或仅特定 Tab 触发
ProductionWorkOrderCardList 外壳(可选) 推荐 共用列表容器,各 Tab 传入不同 cardMetaConfig(与质检一致);若产品坚持卡片模板也拷贝,可在 Tab 文件内嵌独立 meta 区块,但默认方案为 cardMeta props
utils/production-work-order-tabs.ts Tab 常量、可见 Tab 列表、toListQuery()

原则: 拷贝 Tab 页 + 查看弹窗(展示差异大);共用 任务与生产管理动作(行为一致)。


4. 组件边界

模块 策略
WorkOrderTaskSubList + 任务相关弹窗 共用
ProductionWorkOrderCardList + 组/单卡 共用,props cardMetaConfig
查看详情弹窗 6 份独立 view-dialogs/*.vue
Tab 子页面 6 份独立 tabs/*.vue(拷贝再改)
生产工单壳 index.vue 6 Tab 按钮 + <component :is="..." /> + 共用管理向弹窗
我的生产任务 import 同一套 tabs/*,page-mode="mine"

5. 筛选区(按 Tab)

移除原出库 Tab 内「业务类型」下拉(my-production-task 现有 searchForm.bizType 一并删除)。

Tab 关键词 placeholder 时间标签 时间字段
细胞存储生产 工单号/样本编码/入库编码 创建时间 createTime
科研捐赠生产 同上 创建时间 createTime
中试服务生产 工单号/申请单号/申请单名称/患者 输注时间 infusionTime
基础实验生产 工单号/申请单号/课题名称/客户 交付时间 infusionTime
临床应用生产 同中试 输注时间 infusionTime
临时生产 工单号 创建时间 createTime

默认近 30 天。


6. 列表卡片展示矩阵(cardMetaConfig)

共用 ProductionWorkOrderCardList;各 Tab 传入 production-work-order-card-meta.ts 中对应配置。

6.1 入库 · 细胞存储

  • 组头:样本编码、样本类型、采集协议号、协议状态、接收时间
  • 组级费用条:paymentSummary 时展示协议缴费面板
  • 卡片 meta:检测/生产相关字段;无 outbound 申请单字段

6.2 入库 · 科研捐赠

  • 组头:捐赠状态(非协议状态)、样本编码、样本类型
  • 无 协议缴费条
  • 无 「来源类型」列(Tab 已固定)

6.3 出库 · 中试服务

  • 单列卡片;申请单、患者、输注次序/时间
  • 无 receptionSource、协议状态

6.4 出库 · 基础实验

  • 课题名称、客户名称、交付时间
  • 无 患者、输注方案、疗程

6.5 出库 · 临床应用(hidden)

  • 与中试类似 + 临床/缴费相关字段(弹窗完整;Tab 隐藏)

6.6 临时

  • 工单号、状态、备注;无 样本/协议/出库块

7. 查看弹窗(6 份独立)

Tab 弹窗文件 要点
细胞存储 InboundCellStorageProductionViewDialog.vue 协议缴费 + 运输 + 样本接收 + 生产任务
科研捐赠 InboundResearchDonationProductionViewDialog.vue 无协议缴费;捐赠状态
中试 OutboundPilotProductionViewDialog.vue 中试 context + 产品 + 任务
基础实验 OutboundBasicExperimentProductionViewDialog.vue 课题/客户/交付 + 缴费(若有)
临床应用 OutboundClinicalProductionViewDialog.vue 临床完整 + 缴费
临时 TemporaryProductionViewDialog.vue 最小信息 + 任务

可抽 useProductionWorkOrderTaskViewSections.ts 供 6 弹窗 import 任务/步骤区块,避免任务展示逻辑拷 6 份。

删除/替换: ProductionWorkOrderViewDialogHost.vue、useProductionWorkOrderViewDialog.ts(逻辑迁入 6 弹窗 + composable);index.vue 内联 SystemViewDialog 移除。


8. 我的生产任务

与生产工单 共用 6 个 Tab 子组件(tabs/*)。

差异:

  • pageMode='mine'
  • 卡片仅「查看」;无新增/派发/批量完成等
  • WorkOrderTaskSubList:listMode=mine,operateScope=mine
  • 数据:GET /production-tasks/mine + Tab 一致 receptionSource / bizType 过滤
  • 新建/扩展 production-mine-task-groups.ts(对标 qc-mine-task-groups.ts)

9. 后端 API

9.1 GET /production-work-orders

新增 Query:receptionSource、bizType;list_production_work_orders() 增加过滤。

9.2 GET /production-tasks/mine

新增 Query:receptionSource、bizType;join biz_production_work_order 过滤。

9.3 列表 enrich

出库列表确认/补充 projectTitle、customerName(基础实验卡片);关键词支持课题/客户(对标质检)。


10. 目录结构(目标)

web-admin/src/views/production/production-work-order/
  index.vue                          # 6 Tab 壳 + 管理向共用弹窗
  tabs/
    InboundCellStorageTab.vue          # 从现 inbound 拷贝改
    InboundResearchDonationTab.vue     # 拷贝 inbound 改
    OutboundPilotTab.vue               # 从现 outbound 拷贝改
    OutboundBasicExperimentTab.vue     # 拷贝 outbound 改
    OutboundClinicalTab.vue            # 拷贝 outbound 改(hidden)
    TemporaryTab.vue                   # 从现 temporary 拷贝改
  view-dialogs/                        # 6 独立查看弹窗
  composables/                         # 任务 sections、附件等可共用
web-admin/src/utils/
  production-work-order-tabs.ts
  production-work-order-card-meta.ts
web-admin/src/utils/
  production-mine-task-groups.ts       # mine 数据管道

11. 验收清单

11.1 数据隔离

  • 六类 Tab(含 hidden 临床应用)API 过滤正确
  • 可见 5 Tab 列表无串类型数据

11.2 展示

  • 出库卡片无 receptionSource
  • 基础实验无患者/输注字段,有中试/课题字段
  • 科研捐赠无协议缴费
  • 各 Tab 查看弹窗字段与 Spec §7 一致

11.3 行为保留

  • 派发任务、派发质检、完成工单、样本接收等管理操作与改造前一致
  • 我的生产任务仅操作收窄,卡片上下文与生产工单一致

12. 决策记录

日期 决策
2026-06-16 6 Tab 命名确认;临床应用 hidden
2026-06-16 拷贝再改:从现 3 Tab 剪出/拷贝为 6 Tab 页 + 6 查看弹窗;任务与管理弹窗共用
2026-06-16 卡片列表容器共用 + cardMetaConfig(避免 6 份卡片 markup 拷贝);若实现中发现 inbound 组头差异过大,允许 Inbound*Tab 内单独包一层组头组件

13. 下一步

  1. 用户审阅本 Spec
  2. 调用 writing-plans 生成 docs/superpowers/plans/2026-06-16-production-work-order-tab-split.md
  3. 按 Task 分期实施(先后端过滤 → cardMeta → 6 弹窗 → 6 Tab 拷贝 → 壳层 → mine)