2026-05-23-storage-release-review-design.md 16 KB

入库放行审核 — 设计文档

日期:2026-05-23 状态:待审阅 模块:质检任务 → 入库放行审核

1. 背景与目标

现状

当前系统流程:采集协议单/捐赠协议单录入 → 样本接收 → 入库质检工单(含实验室自检和第三方检测)→ 入库生产工单 → 细胞产品入库。

需求

客户要求在上述流程中增加一个"入库放行审核"环节。所有采集协议单和捐赠协议单的样本,在经过接收、质检、生产后,需经过放行审核通过后才算真正通过并存入库中。

目标

在【质检任务】菜单下新增【入库放行审核】子菜单,提供:

  1. 样本级别的放行审核列表(采集协议 + 捐赠协议混合展示)
  2. 查看每个样本的全链路信息(基础、运输、接收、质检、生产)
  3. 审核操作(通过/不通过 + 备注 + 附件),支持批量
  4. 样本入库操作,支持批量
  5. 审核后可继续修改结论、备注、附件

2. 需求确认记录

维度 决定
审核粒度 样本级别 — 每个样本一行,独立审核
显示时机 样本接收后(accept_conclusion=js)即显示在列表中
结论选项 通过 / 不通过(tg / btg)
审核后动作 仅记录结论;另设"样本入库"按钮单独触发入库
入库动作 仅更新样本状态,不涉及库位分配
批量操作 支持批量审核 + 批量入库
审核可修改 审核完成后可继续修改结论、备注、附件

3. 数据模型

3.1 新增表 biz_storage_release_review

CREATE TABLE `biz_storage_release_review` (
  -- 主键
  `id`                  VARCHAR(64)  NOT NULL COMMENT '主键ID',

  -- 业务字段
  `sample_code`         VARCHAR(64)  NOT NULL COMMENT '样本编码(关联键)',
  `reception_source`    VARCHAR(32)  NOT NULL COMMENT '来源:cell_storage=采集/research_donation=捐赠',
  `protocol_id`         VARCHAR(64)  DEFAULT NULL COMMENT '协议单ID(冗余加速查询)',
  `reception_id`        VARCHAR(64)  DEFAULT NULL COMMENT '样本接收记录ID',
  `protocol_no`         VARCHAR(64)  DEFAULT NULL COMMENT '协议编号(冗余展示用)',
  `sample_name`         VARCHAR(128) DEFAULT NULL COMMENT '样本名称(冗余展示用)',

  -- 审核字段
  `review_conclusion`   VARCHAR(16)  DEFAULT NULL COMMENT '审核结论:tg=通过/btg=不通过/NULL=待审核',
  `review_remark`       VARCHAR(512) DEFAULT NULL COMMENT '审核备注',
  `review_attachments`  VARCHAR(4000) DEFAULT NULL COMMENT '审核附件(逗号分隔URL)',
  `review_by`           VARCHAR(64)  DEFAULT NULL COMMENT '审核人ID',
  `review_by_name`      VARCHAR(64)  DEFAULT NULL COMMENT '审核人姓名',
  `review_time`         DATETIME     DEFAULT NULL COMMENT '审核时间',

  -- 入库字段
  `storage_status`      VARCHAR(16)  NOT NULL DEFAULT 'drk' COMMENT '入库状态:drk=待入库/yrk=已入库',
  `storage_by`          VARCHAR(64)  DEFAULT NULL COMMENT '入库操作人ID',
  `storage_by_name`     VARCHAR(64)  DEFAULT NULL COMMENT '入库操作人姓名',
  `storage_time`        DATETIME     DEFAULT NULL COMMENT '入库时间',

  -- 公共字段
  `tenant_no`           VARCHAR(64)  NOT NULL DEFAULT '' COMMENT '租户编号',
  `order_num`           INT(11)      DEFAULT NULL COMMENT '排序号',
  `remark`              VARCHAR(512) DEFAULT NULL COMMENT '备注',
  `create_by`           VARCHAR(64)  DEFAULT NULL COMMENT '创建人ID',
  `create_dept_id`      VARCHAR(64)  NOT NULL DEFAULT '' COMMENT '创建人部门ID',
  `create_time`         DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by`           VARCHAR(64)  DEFAULT NULL COMMENT '更新人ID',
  `update_time`         DATETIME     NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  `del_flag`            TINYINT(4)   NOT NULL DEFAULT 0 COMMENT '删除标记:0-正常 1-已删除',

  PRIMARY KEY (`id`),
  KEY `idx_srr_sample`   (`tenant_no`, `sample_code`, `del_flag`),
  KEY `idx_srr_protocol` (`tenant_no`, `protocol_id`, `del_flag`),
  KEY `idx_srr_status`   (`tenant_no`, `review_conclusion`, `storage_status`, `del_flag`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='入库放行审核';

3.2 跨表关联

biz_storage_release_review
  ├─ sample_code + tenant_no → biz_protocol_sample / biz_research_donation_sample
  ├─ protocol_id → biz_collection_protocol / biz_research_donation(基础信息)
  ├─ sample_code → biz_protocol_sample_transport / biz_research_donation_sample_transport(运输信息)
  ├─ reception_id → biz_sample_reception + biz_sample_reception_check_result(接收信息)
  ├─ sample_code → biz_qc_work_order + biz_qc_task(质检信息)
  └─ sample_code → biz_production_work_order + biz_production_task(生产信息)

3.3 数据流转

样本接收完成 (accept_conclusion=js)
  → 自动 INSERT biz_storage_release_review (review_conclusion=NULL, storage_status=drk)
  → 冗余写入 protocol_no, sample_name, protocol_id, reception_id, reception_source

审核人提交审核
  → UPDATE review_conclusion/review_remark/review_attachments/review_by/review_by_name/review_time
  → 可反复修改(每次 UPDATE 覆盖)

点击"样本入库"
  → UPDATE storage_status=yrk, storage_by, storage_by_name, storage_time
  → 同步 UPDATE biz_protocol_sample.sample_status = 'yrk'(仅采集协议样本)

3.4 状态组合

review_conclusion storage_status 列表标签 可用操作
NULL drk 待审核 查看、审核
tg drk 审核通过 查看、审核(修改)、样本入库
btg drk 审核不通过 查看、审核(修改)
tg yrk 已入库 查看、审核(修改)
btg yrk 不通过-已入库 查看、审核(修改)— 异常状态,理论上不出现

4. 后端设计

4.1 新增/修改文件清单

操作 文件 职责
新增 backend/app/schemas/storage_release_review.py Pydantic schemas
新增 backend/app/crud/storage_release_review.py CRUD + 聚合查询
新增 backend/app/api/storage_release_review.py API 路由
修改 backend/app/models/models.py 新增 BizStorageReleaseReview 模型
修改 backend/app/api/__init__.py 注册新路由
修改 backend/app/main.py 注册新路由
修改 backend/app/crud/sample_reception.py 样本接收完成时自动创建审核记录

4.2 API 端点

方法 路径 功能
GET /api/admin/storage-release-reviews 分页列表
GET /api/admin/storage-release-reviews/{id}/detail 详情(聚合全链路)
POST /api/admin/storage-release-reviews/{id}/review 提交/修改审核
POST /api/admin/storage-release-reviews/batch-review 批量审核
POST /api/admin/storage-release-reviews/{id}/store 样本入库
POST /api/admin/storage-release-reviews/batch-store 批量入库

4.3 列表接口

GET /api/admin/storage-release-reviews

请求参数:

  • page / pageSize — 分页
  • reception_source — 筛选协议类别(cell_storage / research_donation)
  • review_conclusion — 筛选审核结论(tg / btg / null)
  • storage_status — 筛选入库状态(drk / yrk)
  • keyword — 模糊搜索(协议编号、样本编码、样本名称)
  • tenant_no — 租户隔离(从当前用户提取)

返回:分页列表,默认排序 create_time DESC。

4.4 详情接口

GET /api/admin/storage-release-reviews/{id}/detail

聚合查询逻辑:

  1. 读取 biz_storage_release_review 记录本身
  2. 根据 reception_source 决定 JOIN 哪张协议主表:
    • cell_storage → biz_collection_protocol + biz_protocol_sample + biz_protocol_sample_transport
    • research_donation → biz_research_donation + biz_research_donation_sample + biz_research_donation_sample_transport
  3. JOIN biz_sample_reception + biz_sample_reception_check_result(接收信息)
  4. JOIN biz_qc_work_order + biz_qc_task + biz_qc_task_result(质检信息)
  5. JOIN biz_production_work_order + biz_production_task(生产信息)

返回结构:

{
  "review": { "...审核记录本身" },
  "protocolInfo": { "...协议基础信息" },
  "transportInfo": { "...运输信息" },
  "receptionInfo": { "...接收信息+检查项" },
  "qcInfo": {
    "workOrder": { "...工单信息" },
    "tasks": [{ "...任务列表含结论" }]
  },
  "productionInfo": {
    "workOrder": { "...生产工单" },
    "tasks": [{ "...生产任务" }]
  }
}

4.5 审核接口

POST /api/admin/storage-release-reviews/{id}/review

请求体:

{
  "review_conclusion": "tg",
  "review_remark": "样本质量合格",
  "review_attachments": "url1,url2"
}

逻辑:

  • 验证记录存在 + 租户隔离
  • UPDATE review_conclusion, review_remark, review_attachments, review_by, review_by_name, review_time
  • 若 storage_status=yrk 且结论改为 btg,保持 storage_status 不变(入库动作不可通过改结论回退)

POST /api/admin/storage-release-reviews/batch-review

请求体:

{
  "ids": ["id1", "id2"],
  "review_conclusion": "tg",
  "review_remark": "批量审核通过",
  "review_attachments": ""
}

4.6 入库接口

POST /api/admin/storage-release-reviews/{id}/store

前置条件:review_conclusion = tg 且 storage_status = drk

逻辑:

  • UPDATE storage_status=yrk, storage_by, storage_by_name, storage_time
  • 同步更新 biz_protocol_sample.sample_status = 'yrk'(采集协议样本,通过 sample_code + tenant_no 关联)

POST /api/admin/storage-release-reviews/batch-store

请求体:

{ "ids": ["id1", "id2"] }

前置条件:所有记录 review_conclusion=tg 且 storage_status=drk。

4.7 自动创建触发点

在 backend/app/crud/sample_reception.py 中,样本接收完成逻辑(accept_conclusion 设为 js 时):

  • INSERT biz_storage_release_review
  • 冗余写入 sample_code, reception_source, protocol_id, reception_id, protocol_no, sample_name
  • 初始状态:review_conclusion=NULL, storage_status=drk

5. 前端设计

5.1 新增/修改文件清单

操作 文件 职责
新增 web-admin/src/api/storage-release-review.ts API 调用模块
新增 web-admin/src/views/quality-inspection/storage-release-review/index.vue 列表页
新增 web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseViewDialog.vue 查看弹窗
新增 web-admin/src/views/quality-inspection/storage-release-review/StorageReleaseReviewDialog.vue 审核弹窗
修改 web-admin/src/router/modules/sqxp.ts 在质检任务路由组下添加子路由

5.2 路由配置

在 sqxp.ts 的质检任务(QualityInspection)路由组下添加:

{
  path: '/quality-inspection/storage-release-review',
  name: 'StorageReleaseReview',
  component: () => import('@views/quality-inspection/storage-release-review/index.vue'),
  meta: {
    title: '入库放行审核',
    // 菜单图标仅一级显示
  }
}

5.3 列表页 (index.vue)

参照模板:protocol-audit/index.vue(含批量审核的列表页)

筛选栏:

  • 协议类别(下拉:全部 / 采集协议 / 捐赠协议)
  • 审核状态(下拉:全部 / 待审核 / 通过 / 不通过)
  • 入库状态(下拉:全部 / 待入库 / 已入库)
  • 搜索关键词(输入框:协议编号/样本编码/样本名称)

工具栏:

  • 左侧:已选 N 项
  • 右侧:[批量审核] [批量入库] — 仅一条按钮为 type="primary"

表格列:

列 字段 渲染 宽度
选择框 — el-table-column type=selection 50
协议编号 protocol_no 文本 160
样本编码 sample_code 文本 140
样本名称 sample_name 文本 140
协议类别 reception_source el-tag: cell_storage→primary, research_donation→success 100
审核结论 review_conclusion el-tag: tg→success, btg→danger, null→info("待审核") 100
入库状态 storage_status el-tag: drk→warning("待入库"), yrk→success("已入库") 100
审核人 review_by_name 文本 100
审核时间 review_time 日期时间 170
操作 — fixed=right, min-width=260 260+

操作按钮:

  • 查看 — 始终显示
  • 审核 — 始终显示
  • 样本入库 — 仅 review_conclusion=tg 且 storage_status=drk 时显示

5.4 查看弹窗 (StorageReleaseViewDialog.vue)

参照模板:qc-task-view-dialog/index.vue(多分区信息展示弹窗)

布局:使用 SystemViewDialog 或自定义 el-dialog,内部分为 5 个信息区域:

  1. ▎基础信息 — 协议编号、协议类别、样本编码、样本名称、客户姓名、联系电话
  2. ▎运输信息 — 运输方式、运输温度、运输时长、运输公司
  3. ▎接收信息 — 接收时间、接收人、接收结论(el-tag: js→success, bj→danger)、检查项表格
  4. ▎质检信息 — 工单编号、工单状态(el-tag)、任务列表(各任务名称 + 结论 el-tag)
  5. ▎生产信息 — 生产工单编号、工单状态(el-tag)、任务列表(各任务名称 + 状态 el-tag)
  6. ▎放行审核 — 审核结论(el-tag)、审核人、审核时间、审核备注、审核附件(文件列表,支持预览/下载)

所有区域均为只读展示。

5.5 审核弹窗 (StorageReleaseReviewDialog.vue)

参照模板:ProtocolAuditDialog.vue(审核弹窗)

上半部分:与查看弹窗完全相同(只读展示 5 个信息区域)

下半部分(表单区域):

  • 审核结论:el-radio-group(通过 / 不通过)
  • 备注:el-input type=textarea
  • 附件:使用 ProtocolFinanceConfirmFields 或类似上传组件

底部按钮:[取消] [确定]

批量审核:不展示上半部分信息,仅显示审核表单(结论 + 备注 + 附件)。参照 ProtocolAuditDialog 批量模式。

5.6 可复用组件

考虑将信息展示区域(基础信息 + 运输信息 + 接收信息 + 质检信息 + 生产信息)抽取为共享子组件,供查看弹窗和审核弹窗复用。

候选组件:

  • SampleQcInfoCards — 已有,可复用质检信息展示
  • 新建 StorageReleaseInfoSection.vue — 统一封装 5 个信息区域的只读展示

5.7 状态标签注册

在 status-tag-registry.ts 中新增:

storageReleaseConclusion: {
  tg: { label: '通过', type: 'success' },
  btg: { label: '不通过', type: 'danger' },
  null: { label: '待审核', type: 'info' },
},
storageStatus: {
  drk: { label: '待入库', type: 'warning' },
  yrk: { label: '已入库', type: 'success' },
}

6. 菜单配置

在系统管理的静态菜单树中,质检任务节点下添加:

字段 值
菜单名称 入库放行审核
路由路径 /quality-inspection/storage-release-review
组件路径 quality-inspection/storage-release-review/index
菜单类型 菜单(C)
上级菜单 质检任务
排序 在现有质检子菜单之后
图标 无(二级菜单不显示图标)

7. 权限设计

使用现有角色-菜单权限体系:

  • 新增菜单节点后,由管理员在角色管理中分配权限
  • 数据权限遵循现有数据范围规则(全部/本部门/本部门及以下/仅本人/自定义)

8. 边界与约束

不做的事

  • 不涉及库位分配逻辑
  • 不涉及工作流引擎(使用简单直审模式)
  • 不改变现有样本接收、质检、生产工单的逻辑
  • 不新增独立的权限角色(复用现有菜单权限体系)

异常处理

  • 批量审核时,部分记录可能已被审核 → 覆盖更新(以最新提交为准)
  • 批量入库时,跳过不满足条件的记录(结论非 tg 或已入库),返回成功/失败数量
  • 修改审核结论时,已入库的记录不回退入库状态

附件处理

  • 遵循现有模式:review_attachments 字段存储逗号分隔的 MinIO URL
  • 上传使用现有 fetchUploadAttachment 接口
  • 附件业务类型:storage-release-review