314 lines
13 KiB
Markdown
314 lines
13 KiB
Markdown
# 双部门样本接收 — 质检域与生产域拆分
|
||
|
||
> 日期:2026-06-29
|
||
> 状态:待审核
|
||
> 关联:`2026-05-19-unified-sample-reception-design.md`、`2026-05-19-production-work-order-design.md`、`2026-06-03-sample-reception-lab-storage-code-design.md`
|
||
> 关联模块:样本接收、入库生产工单、协议/捐赠查看弹窗、质检工单查看
|
||
|
||
---
|
||
|
||
## 1. 背景与目标
|
||
|
||
### 1.1 现状问题
|
||
|
||
当前 **质检管理 → 样本接收** 与 **生产管理 → 生产工单 → 样本接收信息填写** 共用同一张表 `biz_sample_reception`、同一套 submit/update API,两侧均可修改全部字段(含体积、净重、检查项、接收结论等)。与客户「质检登记」与「生产登记」分属不同部门、字段不同的诉求不符。
|
||
|
||
### 1.2 目标
|
||
|
||
1. **质检域**:仅在【质检管理 → 样本接收】填写;去掉 **体积(ml)**、**净重(g)**。
|
||
2. **生产域**:仅在【生产工单 → 样本接收信息填写】填写;字段按 **来源 × 样本类型** 动态展示。
|
||
3. **互读互斥写**:质检弹窗可见生产信息(只读);生产弹窗可见质检信息(只读)。
|
||
4. **展示统一**:所有展示样本接收信息的查看弹窗/详情,同时展示 **质检接收** 与 **生产接收** 两块。
|
||
5. **历史数据(已确认)**:`volume_ml`、`net_weight_g` **仅从界面与读写 API 去掉**;库中保留旧值,**不再展示、不迁移**。
|
||
|
||
---
|
||
|
||
## 2. 业务规则
|
||
|
||
### 2.1 填写入口与权限
|
||
|
||
| 入口 | 可写域 | 只读域 | 写权限 |
|
||
|------|--------|--------|--------|
|
||
| 质检 → 样本接收(待接收/已接收/批量) | 质检接收 | 生产接收 | 现网:`采集接受人`(经手人)、`质量主管`(编辑已接收) |
|
||
| 生产工单 → 样本接收信息填写 | 生产接收 | 质检接收 | **实验专员**(处理人候选与操作角色一致;可复用 `PRODUCTION_STEP_ASSIGNEE_ROLE`) |
|
||
|
||
后端 **必须** 在 API 层拒绝跨域写入,不依赖前端 `disabled`。
|
||
|
||
### 2.2 流程依赖
|
||
|
||
- 入库生产工单在 **质检接收结论 = 接收(js)** 后自动创建(现网逻辑不变)。
|
||
- **生产接收填写** 入口仅在入库类生产工单卡片展示(`inbound_cell_storage` / `inbound_research_donation`)。
|
||
- **质检拒收(bj)**:生产弹窗不展示填写能力;只读展示质检结论即可。
|
||
- **填写顺序**:须已存在质检接收记录后,生产方可保存生产接收(生产 API 校验 `reception_id` 存在)。
|
||
|
||
### 2.3 样本类型匹配
|
||
|
||
与 `web-admin/src/utils/sample-reception-lab-storage-code.ts` 一致,按 **样本类型名称** 匹配:
|
||
|
||
| 名称 | 说明 |
|
||
|------|------|
|
||
| `围产期造血干细胞` | 对应需求文档编码 `wcqzxgxb` |
|
||
| `脐带间充质干细胞` | 对应需求文档编码 `qdjczgxb` |
|
||
|
||
**未在矩阵中的类型**(如 `胎盘亚全能干细胞`):生产弹窗仅展示公共字段(处理人、处理时间),无类型专属字段;专属字段不做必填校验。
|
||
|
||
### 2.4 历史字段 `volume_ml` / `net_weight_g`
|
||
|
||
- **决策:选项 A** — 停止读写与展示;`biz_sample_reception` 列保留,不执行数据迁移脚本。
|
||
- `_reception_to_dict` 及前端类型定义 **不再输出** 这两字段(或输出但全链路忽略)。
|
||
- 新生产域字段与历史体积/净重 **无自动映射**。
|
||
|
||
---
|
||
|
||
## 3. 字段矩阵
|
||
|
||
### 3.1 质检域(`biz_sample_reception`,现有表)
|
||
|
||
| 字段 | 变更 |
|
||
|------|------|
|
||
| reception_time, handler_user_id, handler_name | 保留 |
|
||
| receive_temperature | 保留 |
|
||
| check_results(子表) | 保留 |
|
||
| accept_conclusion, lab_storage_code | 保留 |
|
||
| receive_attachments, remark | 保留 |
|
||
| **volume_ml, net_weight_g** | **停止 API 入参/出参及 UI 展示** |
|
||
|
||
### 3.2 生产域(新表 `biz_sample_production_reception`)
|
||
|
||
**公共字段(所有来源×类型)**
|
||
|
||
| 字段 | 类型 | 规则 |
|
||
|------|------|------|
|
||
| handler_user_id | varchar(64) | 处理人;默认当前登录用户 |
|
||
| handler_name | varchar(100) | 处理人姓名快照 |
|
||
| process_time | datetime | 处理时间;默认当前时间 |
|
||
|
||
**细胞存储 + 围产期造血干细胞**
|
||
|
||
| 字段 | 类型 | 标签 |
|
||
|------|------|------|
|
||
| original_blood_weight_g | decimal(18,4) | 原血重量/g |
|
||
| hes_volume_ml | decimal(18,4) | HES用量/ml |
|
||
| blood_type | varchar(32) | 血型(文本输入,非下拉) |
|
||
| infectious_four_test_result | varchar(16) | 传染四项检测(检测卡):`zc` 正常 / `bzc` 不正常 |
|
||
| enriched_blood_weight_g | decimal(18,4) | 富集后血量/g |
|
||
| cryopreservation_volume_ml | decimal(18,4) | 冻存液用量/ml |
|
||
|
||
**细胞存储 + 脐带间充质干细胞**
|
||
|
||
| 字段 | 类型 | 标签 |
|
||
|------|------|------|
|
||
| inoculation_amount | decimal(18,4) | 接种量 |
|
||
| cryopreservation_time | datetime | 冻存时间 |
|
||
| storage_total_tubes | int | 储存总量(管) |
|
||
| available_cell_count_1e7 | decimal(18,4) | 可提供细胞数量/*10E7 |
|
||
|
||
**科研捐赠 + 脐带间充质干细胞**
|
||
|
||
| 字段 | 类型 | 标签 |
|
||
|------|------|------|
|
||
| inoculation_amount | decimal(18,4) | 接种量 |
|
||
| cryopreservation_time | datetime | 冻存时间 |
|
||
|
||
**科研捐赠 + 围产期造血干细胞**
|
||
|
||
| 字段 | 类型 | 标签 |
|
||
|------|------|------|
|
||
| original_blood_volume_ml | decimal(18,4) | 原血体积/ml |
|
||
| nucleated_cell_count_1e8 | decimal(18,4) | 有核细胞数/10E8 |
|
||
|
||
**必填规则**:对当前样本命中的类型专属字段 + 公共字段做前后端必填校验;未命中类型的专属列保持 NULL。
|
||
|
||
---
|
||
|
||
## 4. 数据库设计
|
||
|
||
### 4.1 新表
|
||
|
||
```sql
|
||
-- docs/sql/migrate_sample_production_reception.sql
|
||
|
||
CREATE TABLE `biz_sample_production_reception` (
|
||
`id` varchar(64) NOT NULL COMMENT '主键ID',
|
||
`reception_id` varchar(64) NOT NULL COMMENT '关联 biz_sample_reception.id',
|
||
`sample_code` varchar(32) DEFAULT NULL COMMENT '样本编码快照',
|
||
`reception_source` varchar(20) NOT NULL DEFAULT 'cell_storage' COMMENT '来源 cell_storage/research_donation',
|
||
`sample_type_name` varchar(100) DEFAULT NULL COMMENT '样本类型名称快照',
|
||
`handler_user_id` varchar(64) DEFAULT NULL COMMENT '处理人用户ID',
|
||
`handler_name` varchar(100) DEFAULT NULL COMMENT '处理人姓名',
|
||
`process_time` datetime NOT NULL COMMENT '处理时间',
|
||
`original_blood_weight_g` decimal(18,4) DEFAULT NULL COMMENT '原血重量/g',
|
||
`hes_volume_ml` decimal(18,4) DEFAULT NULL COMMENT 'HES用量/ml',
|
||
`blood_type` varchar(32) DEFAULT NULL COMMENT '血型',
|
||
`infectious_four_test_result` varchar(16) DEFAULT NULL COMMENT '传染四项 zc正常 bzc不正常',
|
||
`enriched_blood_weight_g` decimal(18,4) DEFAULT NULL COMMENT '富集后血量/g',
|
||
`cryopreservation_volume_ml` decimal(18,4) DEFAULT NULL COMMENT '冻存液用量/ml',
|
||
`inoculation_amount` decimal(18,4) DEFAULT NULL COMMENT '接种量',
|
||
`cryopreservation_time` datetime DEFAULT NULL COMMENT '冻存时间',
|
||
`storage_total_tubes` int DEFAULT NULL COMMENT '储存总量(管)',
|
||
`available_cell_count_1e7` decimal(18,4) DEFAULT NULL COMMENT '可提供细胞数量/*10E7',
|
||
`original_blood_volume_ml` decimal(18,4) DEFAULT NULL COMMENT '原血体积/ml',
|
||
`nucleated_cell_count_1e8` decimal(18,4) DEFAULT NULL COMMENT '有核细胞数/10E8',
|
||
`tenant_no` varchar(64) NOT NULL DEFAULT 'zkxw',
|
||
`order_num` int DEFAULT NULL,
|
||
`remark` varchar(512) DEFAULT NULL,
|
||
`create_by` varchar(64) DEFAULT NULL,
|
||
`create_dept_id` varchar(64) NOT NULL DEFAULT '',
|
||
`create_time` datetime NOT NULL,
|
||
`update_by` varchar(64) DEFAULT NULL,
|
||
`update_time` datetime NOT NULL,
|
||
`del_flag` smallint NOT NULL DEFAULT '0',
|
||
PRIMARY KEY (`id`),
|
||
UNIQUE KEY `uk_reception_id` (`reception_id`,`del_flag`),
|
||
KEY `idx_sample_code` (`tenant_no`,`sample_code`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='生产部门样本接收登记';
|
||
```
|
||
|
||
**关系**:与 `biz_sample_reception` **1:1**(`reception_id` 唯一);软删除遵循 `del_flag`。
|
||
|
||
### 4.2 现有表
|
||
|
||
- `biz_sample_reception.volume_ml`、`net_weight_g`:**不删列**;应用层停用。
|
||
|
||
---
|
||
|
||
## 5. API 设计
|
||
|
||
### 5.1 质检 API(调整现有 `/web/admin/sample-receptions`)
|
||
|
||
- `POST` / `PUT`:请求体 **移除** `volumeMl`、`netWeightG`。
|
||
- `GET` 详情 / 列表 / `by-sample-code`:响应增加 `productionReception`(对象或 `null`);响应 **移除** `volumeMl`、`netWeightG`。
|
||
- 写接口 **拒绝** 任何生产域字段(若误传则忽略或 400)。
|
||
|
||
### 5.2 生产 API(新增)
|
||
|
||
前缀建议:`/web/admin/production-sample-receptions`
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
|------|------|------|
|
||
| GET | `/by-sample-code?sampleCode=&sourceType=` | 返回 `{ receptionId, qcReception, productionReception, sampleInfo }` |
|
||
| GET | `/{id}` | 生产接收详情 |
|
||
| POST | `/` | 创建(body 含 `receptionId` 或 `sampleCode`+`sourceType`) |
|
||
| PUT | `/{id}` | 更新生产域字段 |
|
||
|
||
- 校验:关联质检记录存在;`accept_conclusion !== 'bj'`;当前用户具备实验专员角色或等于处理人(编辑策略与质检对称,首版:**实验专员可写**)。
|
||
- 写接口 **禁止** 修改 `biz_sample_reception` 任意字段。
|
||
|
||
### 5.3 聚合读
|
||
|
||
以下详情接口的 `reception` 或等价字段扩展为:
|
||
|
||
```json
|
||
{
|
||
"qcReception": { "...质检字段..." },
|
||
"productionReception": { "...生产字段..." }
|
||
}
|
||
```
|
||
|
||
或保持扁平 `reception` 为质检数据,另增 `productionReception`。实现时 `_row_to_dict` 为单一真相源。
|
||
|
||
**影响面**:生产工单详情、质检工单入库查看、协议/捐赠样本卡片接口(若内嵌 `sampleReception`)。
|
||
|
||
---
|
||
|
||
## 6. 前端设计
|
||
|
||
### 6.1 可写表单
|
||
|
||
| 组件 | 改造 |
|
||
|------|------|
|
||
| `quality-inspection/sample-reception/index.vue` | 去掉体积/净重;表单下增加 **生产接收信息(只读)** 区块;拉取聚合详情 |
|
||
| `production-work-order/SampleReceptionDialog.vue` | **重写**:上为质检只读,下为生产可编辑(按类型字段模板);**不再** 调用质检 submit/update |
|
||
| `production/sample-reception-completion/index.vue` | 废弃或改为跳转生产工单;菜单保持隐藏 |
|
||
|
||
### 6.2 公共只读组件(新建)
|
||
|
||
建议:`web-admin/src/components/business/sample-reception-dual-readonly-panel/`
|
||
|
||
- Props:`qcReception`、`productionReception`、`sourceType`、`sampleTypeName`
|
||
- 内置 4 套类型字段展示模板 + 空态(「生产尚未登记」/「暂未接收」)
|
||
- 供协议查看、捐赠查看、工单查看、质检任务查看等复用
|
||
|
||
### 6.3 只读展示改造清单
|
||
|
||
| 文件 | 改造 |
|
||
|------|------|
|
||
| `ProtocolViewDialog.vue` | 样本卡片拆「质检接收」「生产接收」 |
|
||
| `DonationViewDialog.vue` | 同上 |
|
||
| `production-view-sections.ts` | 拆两段 section |
|
||
| `inbound-view-sections.ts` | 同上 |
|
||
| `QcTaskViewDialog` | 同上 |
|
||
| `QcWorkOrderTaskSubList` | 同上 |
|
||
| `StorageReleaseViewDialog` | 同上 |
|
||
| 质检样本接收「接收详情」弹窗 | 增加生产只读块 |
|
||
|
||
### 6.4 生产处理人下拉
|
||
|
||
复用 `fetchProductionStepAssigneeUsers`(角色 `实验专员`);打开弹窗时默认选中当前登录用户(若在列表中)。
|
||
|
||
### 6.5 UI 规范
|
||
|
||
- 弹窗:`dialog-form-layout`、`label-position="top"`、只读块用 `readonly-grid` / `data-grid` 与现网样本接收弹窗一致。
|
||
- 质检块标题:**质检接收信息**;生产块:**生产接收信息**。
|
||
- 传染四项:`el-select`,选项「正常」「不正常」。
|
||
|
||
---
|
||
|
||
## 7. 后端模块
|
||
|
||
| 路径 | 职责 |
|
||
|------|------|
|
||
| `backend/app/models/models.py` | `BizSampleProductionReception` |
|
||
| `backend/app/crud/sample_production_reception.py` | CRUD、类型校验、`_row_to_dict` |
|
||
| `backend/app/api/sample_production_reception.py` | 路由 |
|
||
| `backend/app/crud/sample_reception.py` | 去掉 volume/netWeight 出参;详情挂载 production |
|
||
| `backend/app/api/__init__.py` + `main.py` | 注册新路由 |
|
||
|
||
字段一致性:运行 `python scripts/check_field_consistency.py`(若纳入检查范围)。
|
||
|
||
---
|
||
|
||
## 8. 权限与菜单
|
||
|
||
- 新增按钮权限(建议):`production:sample-reception:add`、`production:sample-reception:edit`,挂在生产工单或生产管理菜单下。
|
||
- 质检权限不变:`biz:sampleReception:*`。
|
||
|
||
---
|
||
|
||
## 9. 测试要点
|
||
|
||
1. 质检接收(js) → 生产工单出现 → 生产填写 4 种类型组合字段 → 质检页只读可见。
|
||
2. 质检编辑后 → 生产页只读更新;生产编辑后 → 质检页只读更新;双方 API 互不能改对方域。
|
||
3. 质检拒收 → 生产无填写入口。
|
||
4. 历史记录:`volume_ml`/`net_weight_g` 有值的旧数据,界面与 API 均不出现。
|
||
5. 未覆盖样本类型:仅公共字段可保存。
|
||
6. 实验专员/非实验专员写权限边界。
|
||
|
||
---
|
||
|
||
## 10. 实施顺序
|
||
|
||
1. SQL + Model + 生产 CRUD/API
|
||
2. 质检 API 瘦身 + 聚合读
|
||
3. `SampleReceptionDialog` 重写 + 质检页调整
|
||
4. `sample-reception-dual-readonly-panel` + 各查看弹窗接入
|
||
5. 权限 SQL + 回归
|
||
|
||
---
|
||
|
||
## 11. 不在本次范围
|
||
|
||
- 隐藏菜单「样本接收信息完善」路由删除(可后续清理)。
|
||
- 小程序端样本接收(若有)不同步,除非另行立项。
|
||
- `volume_ml`/`net_weight_g` 列的数据库物理删除。
|
||
|
||
---
|
||
|
||
## 12. 已确认决策
|
||
|
||
| 议题 | 决策 |
|
||
|------|------|
|
||
| 历史体积/净重 | **A** — 库保留,界面与 API 去掉,不展示不迁移 |
|
||
| 数据模型 | 新表 `biz_sample_production_reception`,1:1 关联质检接收 |
|
||
| 未覆盖样本类型 | 仅公共字段,无专属必填 |
|