2026-10-05-unified-sample-info-design.md 10 KB

统一样本信息管理 — 实现设计(方案 1)

日期:2026-10-05
状态:已确认(2026-10-05)
关联:细胞存储 / 科研捐赠「样本信息管理」;采集协议单「储存证 / 满月待办」收口


1. 背景

现状把样本进度拆在多处:

  • 细胞存储「样本信息管理」四个 Tab(采集 / 接收 / 质检 / 入库),后三 Tab 还承担短信提取与通知标记。
  • 科研捐赠「样本信息管理」只有采集列表。
  • 储存证、满月保险在「采集协议单」另外两个 Tab;保险还绑定保险公司、险种、保单号、投保单、发票。

市场侧无法在同一张样本列表上看完整进度。保险公司 / 险种菜单已隐藏,产品要求证与保险先做轻量办理。


2. 目标与非目标

2.1 目标

  • 一个「样本信息管理」界面、两个来源 Tab(细胞存储 / 科研捐赠)。
  • 一条样本一行;一份协议多个样本即多行。
  • 列表展示采集、接收、质检、入库进度标识(只读,由现有业务数据派生)。
  • 细胞存储额外展示储存证、保险「已办理 / 未办理」(协议级,同协议多行相同)。
  • 详情展示对应进度明细;细胞存储详情可办理储存证、保险(办理时间、办理人员、附件、备注)。
  • 采集协议单移除「储存证管理」「满月待办管理」Tab;旧路由跳转到样本信息。

2.2 非目标

  • 不在本页改采集 / 接收 / 质检 / 入库状态(仍在质检、生产等菜单办理)。
  • 不在本页提取短信、标记已通知。
  • 不采集保险公司、险种、保单号、费用、投保单、发票;不恢复已隐藏的保险公司 / 体检机构菜单。
  • 不新建「样本进度总表」,不把两套协议样本合成一张混排物理表。
  • 不删除短信相关 API / 表;本页不再入口即可。
  • 不删除证 / 保险表上的旧保险字段;界面不展示、新保存不写入这些字段。

3. 菜单与页面

3.1 入口

菜单 路由 默认 Tab
细胞存储 → 样本信息管理 /market/cell-storage/sample-info cell_storage
科研捐赠 → 样本信息管理 /market/research-donation/sample-info research_donation

两路由共用同一页面组件。query.tab 为 cell_storage | research_donation,与菜单默认一致,切换 Tab 时写入 query。

权限码保持现有:cell-storage:sample-info:list、research-donation:sample-info:list。用户只能看到有权限的 Tab;从无权限的菜单进入时不展示对应 Tab。

3.2 采集协议单

protocol-audit 仅保留「协议单管理」(审核、状态变更、增删改)。移除储存证、满月待办 Tab。

已隐藏路由:

  • /market/cell-storage/storage-cert → 跳转 CellStorageSampleInfo?tab=cell_storage
  • /market/cell-storage/fullmoon-todo → 同上
  • 旧样本接收 / 入库 / protocol-audit?tab=storage-cert|fullmoon-todo → 同样落到统一样本信息页

3.3 UI

  • 列表对齐标准列表(筛选 → 表格 → 分页);进度与办理状态用 el-tag。
  • 操作列 fixed="right",min-width ≥ 260px;本页主操作仅为「查看」。
  • 详情弹窗沿用 ProtocolViewDialog / DonationViewDialog,label-position="top",无遮罩模糊。
  • 附件上传卡片化,对齐协议附件(ProtocolFormDialog)。

4. 列表

4.1 粒度与排序

  • 数据源:biz_protocol_sample(细胞存储)/ biz_research_donation_sample(科研捐赠),del_flag = 0,当前租户 + 数据权限。
  • 默认排序与现采集列表一致:预产期空值靠后,其余预产期倒序,再主单 create_time DESC,再样本 id 倒序。

4.2 公共列

协议/捐赠状态、预产期、母亲姓名、新生儿姓名、样本编码(含特殊样本展示)、实验室入库编码、样本类型、采集标识、接收标识、质检标识、入库标识、操作。

细胞存储 Tab 在入库标识后增加:储存证办理、保险办理。

4.3 进度标识(只读,按租户 + 样本编码关联下游)

采集(sample_status)

展示 条件
未采集 空
已采集 ycj / jcz / yrk
已作废 yzf

接收(该编码、对应来源下 del_flag=0 的接收单;多条时取接收时间最晚一条)

展示 条件
未接收 无接收单,或结论为空 / dqr
已接收 js
拒收 bj

质检(该编码细胞存储或科研捐赠来源的入库质检)

展示 条件
未完成 无工单,或待质检 / 质检中
已完成 已有结论:tg 或 btg(通过、不通过都算完成)
已作废 工单作废 yzf

入库

展示 条件
未入库 无入库结果,或待确认 drk
已入库 yrk
拒绝入库 btg

本页 不得 提供改这四类状态的控件。

4.4 储存证 / 保险办理标识(仅细胞存储,协议级)

同一 collection_protocol_id 下所有样本行标识相同。

已办理 当且仅当以下任一成立:

  • 新字段 handle_time 非空;或
  • 兼容旧数据:储存证 make_status = 1 或 make_date 非空;保险 todo_status = 1 或旧 handle_date 非空。

否则 未办理。

不使用保险公司、险种、保单号、insurance_subscribed 判断。

4.5 筛选

  • 关键词:姓名 / 样本编码 / 实验室入库编码(与现采集列表一致)。
  • 采集、接收、质检、入库:与上表展示枚举一致。
  • 细胞存储:储存证办理、保险办理(已办理 / 未办理)。

5. 详情

5.1 打开方式

查看 / 双击:细胞存储打开协议详情,科研捐赠打开捐赠详情。仍为整单。打开后滚动到「样本及运输」,高亮当前行样本。

5.2 样本进度(只读)

每条样本卡片补充四段:采集(状态与采集/母血时间、地区医院医护)、接收(结论、时间、备注)、质检(状态/结论、完成时间)、入库(状态、时间)。无数据展示「—」。

科研捐赠无缴费、储存证、保险区块。

5.3 储存证 / 保险办理(仅细胞存储,可编辑)

协议级两块,各含:

字段 规则
办理时间 日期时间;非空则已办理
办理人员 用户选择;打开空表单时默认当前登录用户。填写了办理时间则办理人员必填
附件 可选;多文件逗号分隔 URL(证:cert_image_urls;保险:insurance_attachments)
备注 可选(证:remark;保险:handle_remark)

每块独立「保存」。不校验协议必须为生效中。

保存时:

  • 有办理时间:写入 handle_time、handler_user_id、附件、备注;同步 make_status/todo_status = 1;同步 make_date / 旧 handle_date 为该日 YYYYMMDD。
  • 办理时间为空:视为撤销办理——清空 handle_time、handler_user_id,status = 0,日期字段清空;附件与备注按本次提交写入(允许一并清空)。
  • 不更新 insurance_company_id、险种、保单号、费用、生效失效、insurance_subscribed。

从样本信息打开的协议详情不再使用旧的只读储存证拼盘 / 满月保险只读区作为办理入口;办理只在上述两块。


6. 数据与接口

6.1 表变更

脚本:docs/sql/migrations/2026-10-05-sample-info-handle-fields.sql(名称以落地为准)。

biz_protocol_storage_cert 在业务字段末、公共字段前增加:

列 类型 说明
handle_time DATETIME NULL 办理时间
handler_user_id VARCHAR(64) NULL 办理人 sys_user.id

biz_protocol_fullmoon_todo 同样增加 handle_time、handler_user_id。

Model / _row_to_dict 与 Create/Update 可写字段对齐(办理接口,非整单协议 CreateBody)。

6.2 列表

扩展:

  • GET /web/admin/protocol-sample-collections/list
  • GET /web/admin/research-donation-sample-collections/list

响应增加进度字段(code + label + 关键时间)。细胞存储增加 storageCertHandled、insuranceHandled(boolean)及办理时间(可选,供详情预填不是必须)。

查询参数增加进度与办理筛选。关联下游一律 tenant_no + sample_code,来源分别为 cell_storage / research_donation。

6.3 办理写入

  • PUT /web/admin/storage-certs/{protocolId}:body 仅 handleTime、handlerUserId、certImageUrls、remark。
  • PUT /web/admin/fullmoon-todos/{protocolId}/handle:body 仅 handleTime、handlerUserId、insuranceAttachments、handleRemark。

租户校验、数据权限与协议更新一致。协议详情 bundle 返回办理字段及办理人姓名。

现有 PUT .../fullmoon-todos/{id}/insurance 可保留但前端样本信息页不调用;协议整单更新不再作为本页证/保险保存路径。

6.4 前端主要改动(落地时按此拆文件)

  • web-admin/src/views/cell-storage/sample-info/index.vue:两来源 Tab + 统一列表。
  • 科研捐赠 sample-info/index.vue:复用或重定向到同一实现。
  • protocol-audit/index.vue:去掉证 / 满月 Tab。
  • ProtocolViewDialog.vue:样本进度摘要 + 证/保险办理表单。
  • DonationViewDialog.vue:样本进度摘要。
  • 可删除或停用:StorageCertTab.vue、FullmoonTodoTab.vue、四个旧进度 Tab 作为独立工作台(采集列表逻辑并入统一页)。

7. 测试要点

  • 细胞存储 / 科研捐赠列表:无下游 → 未接收 / 质检未完成 / 未入库;有 js/tg/yrk → 对应已完成类标识。
  • 多样本协议:两行;改证/保险后两行办理标识同时变化。
  • 办理保存 / 清空办理时间:标识与 status、日期同步字段一致。
  • 旧 make_status=1 且新 handle_time 空:列表仍为已办理。
  • 租户隔离与数据权限:不可见他户协议样本。
  • 科研捐赠列表响应不含证/保险办理列。

8. 决策摘要

项 结论
架构 方案 1:一页两 Tab,进度派生,不建总表
行粒度 样本行
证/保险入口 只在样本详情;协议单 Tab 撤销(选项 A)
证/保险字段 仅时间、人员、附件、备注
短信 本页不做
已办理 以 handle_time 为主,兼容旧制作/办理日期与 status
质检「已完成」 通过或不通过都算完成