This commit is contained in:
zlwu committed 2026-07-14 13:55:11 +08:00
1 parent f90726927e
commit 6eea13370c
103 files changed
+38401 -32231

No files matched your search

@@ -0,0 +1,5 @@
-- 科研捐赠单:传染病检测报告附件字段
-- 2026-07-13
ALTER TABLE `biz_research_donation`
ADD COLUMN `infectious_disease_report_urls` text COLLATE utf8mb4_unicode_ci COMMENT '传染病检测报告附件URL(逗号分隔)' AFTER `attachment_urls`;
@@ -0,0 +1,6 @@
-- 采集协议单:知情同意书、孕妇健康调查表附件字段
-- 2026-07-13
ALTER TABLE `biz_collection_protocol`
ADD COLUMN `consent_form_urls` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '知情同意书附件URL(逗号分隔)' AFTER `protocol_attachments`,
ADD COLUMN `health_survey_form_urls` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '孕妇健康调查表附件URL(逗号分隔)' AFTER `consent_form_urls`;
@@ -0,0 +1,82 @@
-- 质检物料金额查看授权:专用角色 + viewAmount 按钮菜单 + 授权管理页
-- 2026-07-13
-- 1. 按钮权限(F,visible=0,仅用于权限解析)
INSERT INTO `sys_menu`
(`id`, `menu_name`, `parent_id`, `menu_type`, `path`, `component`, `perms`, `is_frame`, `visible`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES
('95100000000000000000000000000002', '查看质检物料金额', '70000000000000000000000000000009', 'F', '', NULL, 'biz:qcMaterial:viewAmount', 1, '0', '1', 'zkxw', 1, NULL, NULL, '', NOW(), NULL, NOW(), 0),
('95100000000000000000000000000003', '查看我的物料领用金额', '92000000000000000000000000000001', 'F', '', NULL, 'biz:myQcMaterialUsage:viewAmount', 1, '0', '1', 'zkxw', 1, NULL, NULL, '', NOW(), NULL, NOW(), 0)
ON DUPLICATE KEY UPDATE
`menu_name` = VALUES(`menu_name`),
`parent_id` = VALUES(`parent_id`),
`menu_type` = VALUES(`menu_type`),
`perms` = VALUES(`perms`),
`visible` = VALUES(`visible`),
`status` = VALUES(`status`),
`del_flag` = 0;
-- 2. 授权管理页(C,挂在质检基础信息下)
INSERT INTO `sys_menu`
(`id`, `menu_name`, `parent_id`, `menu_type`, `path`, `component`, `perms`, `is_frame`, `visible`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES
('95100000000000000000000000000001', '质检物料金额查看授权', 'QCB00000000000000000000000000001', 'C', 'qc-material-amount-auth', '/quality-inspection/qc-material-amount-auth/index', 'biz:qcMaterialAmountAuth:list', 1, '1', '1', 'zkxw', 10, NULL, NULL, '', NOW(), NULL, NOW(), 0)
ON DUPLICATE KEY UPDATE
`menu_name` = VALUES(`menu_name`),
`parent_id` = VALUES(`parent_id`),
`menu_type` = VALUES(`menu_type`),
`path` = VALUES(`path`),
`component` = VALUES(`component`),
`perms` = VALUES(`perms`),
`visible` = VALUES(`visible`),
`status` = VALUES(`status`),
`order_num` = VALUES(`order_num`),
`del_flag` = 0;
-- 3. 专用角色
INSERT INTO `sys_role`
(`id`, `role_name`, `data_scope`, `status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES
('ROLE000000000000000000000000000011', '质检物料金额查看', '1', '1', 'zkxw', 0, '可查看/编辑质检物料库与我的物料领用记录中的单价与金额', NULL, '', NOW(), NULL, NOW(), 0)
ON DUPLICATE KEY UPDATE
`role_name` = VALUES(`role_name`),
`status` = VALUES(`status`),
`remark` = VALUES(`remark`),
`del_flag` = 0;
-- 4. 角色 ↔ 按钮权限
INSERT INTO `sys_role_menu`
(`id`, `role_id`, `menu_id`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
VALUES
('RM000000000000000000000000000011', 'ROLE000000000000000000000000000011', '95100000000000000000000000000002', 'zkxw', 1, NULL, NULL, '', NOW(), NULL, NOW(), 0),
('RM000000000000000000000000000012', 'ROLE000000000000000000000000000011', '95100000000000000000000000000003', 'zkxw', 2, NULL, NULL, '', NOW(), NULL, NOW(), 0)
ON DUPLICATE KEY UPDATE
`del_flag` = 0;
-- 5. 已拥有「质检物料库」菜单的角色,自动获得授权管理页
INSERT INTO `sys_role_menu`
(`id`, `role_id`, `menu_id`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`)
SELECT
CONCAT('RMAA', SUBSTRING(MD5(CONCAT(rm.role_id, '95100000000000000000000000000001')), 1, 28)),
rm.role_id,
'95100000000000000000000000000001',
'zkxw',
0,
NULL,
NULL,
'',
NOW(),
NULL,
NOW(),
0
FROM `sys_role_menu` rm
WHERE rm.menu_id = '70000000000000000000000000000009'
AND rm.del_flag = 0
AND rm.tenant_no = 'zkxw'
AND NOT EXISTS (
SELECT 1
FROM `sys_role_menu` x
WHERE x.role_id = rm.role_id
AND x.menu_id = '95100000000000000000000000000001'
AND x.del_flag = 0
);
+4 -1
View File
@@ -5323,6 +5323,8 @@ CREATE TABLE `biz_collection_protocol` (
`protocol_no` varchar(32) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '采集协议号展示',
`protocol_status` varchar(16) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'dsx' COMMENT 'dsx待生效 sxz生效中 ygq已过期 yzf已作废 zky转科研',
`protocol_attachments` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '协议附件 minio 地址逗号分隔',
`consent_form_urls` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '知情同意书附件URL(逗号分隔)',
`health_survey_form_urls` varchar(4000) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '孕妇健康调查表附件URL(逗号分隔)',
`register_date` char(8) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '登记日期YYYYMMDD',
`effective_time` datetime DEFAULT NULL COMMENT '协议生效时间',
`effective_desc` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '协议生效描述',
@@ -11925,6 +11927,7 @@ CREATE TABLE `biz_research_donation` (
`source_protocol_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '来源采集协议单ID(from_storage时关联)',
`consent_form_urls` text COLLATE utf8mb4_unicode_ci COMMENT '知情同意书附件URL(逗号分隔)',
`attachment_urls` text COLLATE utf8mb4_unicode_ci COMMENT '附件URL(逗号分隔)',
`infectious_disease_report_urls` text COLLATE utf8mb4_unicode_ci COMMENT '传染病检测报告附件URL(逗号分隔)',
`collector_user_id` varchar(64) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '采集专员用户ID',
`effective_time` datetime DEFAULT NULL COMMENT '生效时间',
`effective_desc` varchar(512) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '生效描述',
@@ -17387,4 +17390,4 @@ INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`,
INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`, `slot_status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`, `occupied_count`, `last_item_type`, `last_stored_at`) VALUES ('06DAE9C9391A42F18810921CFEF9053A', '38E4724959314DDFA1C26E7C8ADC1D08', '3', '空', 'zkxw', 1003, NULL, 'd3000000000000000000000000000001', 'b13c2be2-4e71-11f1-9f47-00163e3bdd96', '2026-06-26 04:20:32', 'd3000000000000000000000000000001', '2026-06-26 04:20:32', 0, 0, NULL, NULL);
INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`, `slot_status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`, `occupied_count`, `last_item_type`, `last_stored_at`) VALUES ('06DE851FAABD4E07928BF7FB73A0C807', 'C530BD59EE934CCCAE12411679D5AF9A', '26', '占用', 'zkxw', 3006, NULL, 'd3000000000000000000000000000001', 'b13c2be2-4e71-11f1-9f47-00163e3bdd96', '2026-06-26 04:12:30', 'd3000000000000000000000000000001', '2026-06-30 00:53:30', 0, 1, 'cell_product', '2025-08-20 00:00:00');
INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`, `slot_status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`, `occupied_count`, `last_item_type`, `last_stored_at`) VALUES ('06E019CD9A794C27842428ED073640B5', '22564DA268E44068AB159C551C815CE5', '97', '空', 'zkxw', 10007, NULL, 'd3000000000000000000000000000001', 'b13c2be2-4e71-11f1-9f47-00163e3bdd96', '2026-06-26 04:20:41', 'd3000000000000000000000000000001', '2026-06-26 04:20:41', 0, 0, NULL, NULL);
INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`, `slot_status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept_id`, `create_time`, `update_by`, `update_time`, `del_flag`, `occupied_count`, `last_item_type`, `last_stored_at`) VALUES ('06E27C81FCE14EFB89B760E049D19505', 'EF5E0C22CE24494C87BD66064347B647', '31', '空', 'zkxw', 4004, NULL, 'd3000000000000000000000000000001', 'b13c2be2-4e71-
INSERT INTO `biz_storage_facility_slot` (`id`, `facility_node_id`, `slot_code`, `slot_status`, `tenant_no`, `order_num`, `remark`, `create_by`, `create_dept
@@ -0,0 +1,51 @@
# 样本卡片协议附件迷你缩略图 Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 在预产及在途样本、样本接收卡片中按来源展示协议级附件(迷你缩略图),支持预览/下载,无附件显示「无」。
**Architecture:** 列表 API 补齐 `healthSurveyAttachmentFiles` / `infectiousDiseaseReportAttachmentFiles`;前端新建 `ProtocolAttachmentMiniReadonly` + `getSourceProtocolAttachment` + `useAttachmentActions`,三处卡片复用。
**Tech Stack:** Python FastAPI CRUD、`urls_to_attachment_list`;Vue 3 + Element Plus + SCSS
**Spec:** `docs/superpowers/specs/2026-07-13-sample-card-protocol-attachment-design.md`
---
### Task 1: 后端预产列表补细胞存储附件
**Files:**
- Modify: `backend/app/crud/pre_transit_sample.py`
- [ ] 在细胞存储行 `d = _protocol_to_dict(r)` 后增加 `healthSurveyAttachmentFiles`
### Task 2: 后端样本接收列表补协议附件
**Files:**
- Modify: `backend/app/crud/sample_reception.py`
- [ ] `_rows_to_sample_list_items` 增加 `healthSurveyAttachmentFiles`
- [ ] `_donation_rows_to_sample_list_items` 增加 `infectiousDiseaseReportAttachmentFiles`
### Task 3: 前端共享 util / composable / 迷你组件
**Files:**
- Create: `web-admin/src/utils/protocol-source-attachment.ts`
- Create: `web-admin/src/composables/useAttachmentActions.ts`
- Create: `web-admin/src/components/business/protocol-attachment-mini-readonly/index.vue`
### Task 4: 预产及在途卡片接入
**Files:**
- Modify: `web-admin/src/views/quality-inspection/pre-transit-sample/PreTransitProtocolCardList.vue`
- Modify: `web-admin/src/views/quality-inspection/pre-transit-sample/index.vue`
### Task 5: 样本接收卡片接入
**Files:**
- Modify: `web-admin/src/views/quality-inspection/sample-reception/SampleReceptionCardList.vue`
### Task 6: 验证
- [ ] `pnpm lint` 相关前端文件
- [ ] `./scripts/update-graph.sh frontend`(如有新建文件)
@@ -0,0 +1,61 @@
# 采集协议单 · 知情同意书与孕妇健康调查表附件
> 日期:2026-07-13
> 状态:已确认,实现中
> 确认项:两类附件均为**选填**;查看/编辑布局为**三行堆叠**
---
## 1. 目标
在采集协议单「基本信息」区域,除现有「协议附件」外,新增:
- **知情同意书**(`consent_form_urls`)
- **孕妇健康调查表**(`health_survey_form_urls`)
新增/编辑弹窗支持上传;所有展示「协议附件」的协议单查看弹窗同步展示上述两类附件。
## 2. 数据模型
`biz_collection_protocol` 新增两列(VARCHAR 4000,逗号分隔 MinIO URL),命名与科研捐赠单 `consent_form_urls` 对齐。
## 3. 后端
- Model / CRUD `_protocol_to_dict` / `get_protocol_detail_bundle` / create / update 读写新字段
- Bundle 输出:`consentAttachmentFiles`、`healthSurveyAttachmentFiles`(与 `attachments` 同级)
- API Create/Update Body 增加字段及 attachments 数组 alias;resolve 逻辑复用 `attachments_to_urls`
MinIO 目录:
- `protocol-consent`
- `protocol-health-survey`
## 4. 前端
### 4.1 录入/编辑(`ProtocolFormDialog.vue`)
基本信息 Tab,三行堆叠(各一行 `form-grid--attachment`):
1. 协议附件
2. 知情同意书
3. 孕妇健康调查表
UI 与现有协议附件一致(卡片化上传 + 拖拽,OpenSpec 附件规范)。
### 4.2 查看(`ProtocolViewDialog.vue`)
基本信息 Tab 底部,三行堆叠展示;备注独立一行在其下。均使用 `ProtocolAttachmentReadonly`,无附件显示「暂无附件」。
## 5. 范围外
- 样本接收 checklist(知情同意书/健康调查表勾选)
- 协议转科研时同步知情同意书(本期不做)
- 一键导入标准文本解析
## 6. 改动文件
| 层 | 文件 |
|----|------|
| DB | `docs/sql/migrate-protocol-consent-health-survey.sql`、`docs/sql/zkxw.sql` |
| Backend | `models.py`、`crud/collection_protocol.py`、`api/collection_protocol.py` |
| Frontend | `ProtocolFormDialog.vue`、`ProtocolViewDialog.vue` |
@@ -0,0 +1,219 @@
# 样本卡片 · 协议级附件迷你缩略图展示
> 日期:2026-07-13
> 状态:已确认(展示形态 B · 迷你缩略图)
> 关联:`2026-07-13-protocol-consent-health-survey-design.md`(孕妇健康调查表字段)、捐赠单传染病检测报告字段
---
## 1. 目标
在以下三个卡片场景中,按来源展示协议单级附件,支持点击预览/下载;无附件显示「**无**」。
| 页面 | 位置 |
|------|------|
| 预产及在途样本 | 紧凑小卡片 + 展开详情卡片 |
| 样本接收 | 待接收 Tab 卡片 + 已接收 Tab 卡片 |
### 1.1 来源与附件映射
| `sourceType` | 展示标签 | 数据字段 |
|--------------|----------|----------|
| `cell_storage`(默认) | 孕妇健康调查表 | `healthSurveyAttachmentFiles` |
| `research_donation` | 传染病检测报告 | `infectiousDiseaseReportAttachmentFiles` |
**说明**:展示的是协议/捐赠单录入的附件,**不是**样本接收登记时的 `receiveAttachmentFiles`。
### 1.2 已确认交互(B · 迷你缩略图)
- 每个附件一张 **迷你卡片**:缩略图区 + 单行文件名 + 下载图标
- 图片:缩略图 `object-fit: cover`;文档/视频:与 `ProtocolAttachmentReadonly` 相同的类型图标
- 点击缩略图:图片新开页预览;非图片仅下载区可点
- 点击下载图标:走现有 `downloadAttachmentFile`
- 无附件:标签下方显示「无」(不用「暂无附件」)
- 多附件:横向排列,超出宽度换行
---
## 2. 现状缺口
### 2.1 后端
| 接口 | 细胞存储 | 科研捐赠 |
|------|----------|----------|
| 预产及在途列表 | 仅有 `healthSurveyFormUrls` 字符串 | 已有 `infectiousDiseaseReportAttachmentFiles` |
| 样本接收待/已接收列表 | 无协议附件字段 | 无协议附件字段 |
### 2.2 前端
- `PreTransitProtocolCardList.vue`、`SampleReceptionCardList.vue` 均未展示协议附件
- `ProtocolAttachmentReadonly.vue` 为标准尺寸(140×96),不适合紧凑卡片
---
## 3. 方案(列表 API 补齐 + 共享迷你组件)
采用列表接口直接返回 `*AttachmentFiles`(与协议 CRUD 字段命名一致),前端新建迷你缩略图组件统一渲染。不做懒加载详情、不做前端 URL 手拆。
---
## 4. 后端
### 4.1 `pre_transit_sample.py`
细胞存储行构建处(`_protocol_to_dict` 之后),补充:
```python
d["healthSurveyAttachmentFiles"] = urls_to_attachment_list(
r.health_survey_form_urls, db, tenant_no
)
```
科研捐赠侧 `_donation_to_dict(r, db, tenant_no)` 已含 `infectiousDiseaseReportAttachmentFiles`,无需改动。
### 4.2 `sample_reception.py`
在 `_rows_to_sample_list_items`、`_donation_rows_to_sample_list_items` 构建 `item` 时,从已 join 的 `protocol` / `donation` 实体补充:
- 细胞存储:`healthSurveyAttachmentFiles` ← `protocol.health_survey_form_urls`
- 科研捐赠:`infectiousDiseaseReportAttachmentFiles` ← `donation.infectious_disease_report_urls`
使用现有 `urls_to_attachment_list`;协议/捐赠对象已在查询行中,不额外 N+1。
### 4.3 范围外
- 不修改样本接收登记/编辑 API 写入逻辑
- 不修改 checklist 检查项
- 不修改生产工单、质检工单卡片
---
## 5. 前端
### 5.1 新建 `ProtocolAttachmentMiniReadonly.vue`
路径:`web-admin/src/components/business/protocol-attachment-mini-readonly/index.vue`
**Props**
| 属性 | 类型 | 说明 |
|------|------|------|
| `label` | `string` | 字段标签,如「孕妇健康调查表」 |
| `files` | `Array<Record<string, unknown>>` | 附件列表 |
| `emptyText` | `string` | 默认 `'无'` |
**Events**:`preview`、`download`(与 `ProtocolAttachmentReadonly` 一致,由父级或 composable 处理)
**尺寸与样式**(对齐 Fresh Mint,缩小版 `ProtocolAttachmentReadonly`)
| 元素 | 尺寸 |
|------|------|
| 单卡宽度 | 80px |
| 缩略图区高度 | 56px |
| 圆角 | 6px |
| 边框 | `#e2e8f0`,hover `#047857` |
| 文件名字号 | 10px,单行 ellipsis |
| 下载图标 | 18×18,与标准组件同色交互 |
| 列表 gap | 6px,横向 flex-wrap |
**空态**:仅显示 `label` + `emptyText`(「无」),不渲染缩略图占位。
**逻辑复用**:`resolveFileUrl`、`isImageFile`、`isVideoFile` 与 `ProtocolAttachmentReadonly.vue` 保持一致(可后续抽 util,本期允许组件内复制以保持最小 diff)。
### 5.2 共享工具
**`web-admin/src/utils/protocol-source-attachment.ts`**
```ts
export function getSourceProtocolAttachment(row: Record<string, unknown>): {
label: string
files: Array<Record<string, unknown>>
}
```
按 `sourceType` 返回标签与 files 数组。
**`web-admin/src/composables/useAttachmentActions.ts`**(或复用 `qc-work-order/composables/useQcViewAttachmentHelpers.ts` 模式)
- `fullFileUrl(url)`
- `handleAttachmentPreview(file)` → `window.open`
- `handleAttachmentDownload(file)` → `downloadAttachmentFile`
供预产页、样本接收页、卡片组件父级共用。
### 5.3 `PreTransitProtocolCardList.vue`
**紧凑卡片**(`protocol-card-compact__body` 底部,展开按钮之上):
```html
<ProtocolAttachmentMiniReadonly
:label="attachmentMeta(row).label"
:files="attachmentMeta(row).files"
@preview="emit('attachment-preview', $event)"
@download="emit('attachment-download', $event)"
/>
```
**展开卡片**(「基础信息」`protocol-card__kv-grid` 末尾,占满一行 `protocol-card__kv--stack`):
- 同上组件;`files` 较多时可横向换行,不限高度截断
**卡片高度**:紧凑卡 `--compact-card-height` 增加约 **52px**(标签 10px + 缩略图 56px + 间距);`has-special-sample` 变体同步上调。
**事件**:组件 `emit` 上抛 `attachment-preview` / `attachment-download`,由 `pre-transit-sample/index.vue` 接入 composable。
### 5.4 `SampleReceptionCardList.vue`
在 `sample-reception-card__meta` 末尾增加 `meta-item`(`grid-column: 1 / -1` 或 `minmax(160px, 1fr)` 以保证缩略图行宽度):
```html
<div class="sample-reception-card__meta-item sample-reception-card__meta-item--attachment">
<dt>{{ attachmentMeta(row).label }}</dt>
<dd>
<ProtocolAttachmentMiniReadonly
:label="''"
:files="attachmentMeta(row).files"
...
/>
</dd>
</div>
```
`label` 放在 `dt`,组件内 `label` 传空避免重复。
待接收 / 已接收 **同一展示逻辑**。
### 5.5 类型(可选)
`web-admin/src/api/pre-transit-sample.ts` 可为 `PreTransitProtocolRow` 补充附件字段注释;样本接收列表仍为 `Record<string, unknown>`,不强制改类型。
---
## 6. 测试要点
1. 细胞存储协议有/无孕妇健康调查表:预产紧凑卡、展开卡、样本接收待/已接收均正确
2. 科研捐赠有/无传染病检测报告:同上
3. 多附件横向换行;图片预览、PDF 下载
4. 预产「样本未录入」协议(仅有附件、无样本)仍展示附件
5. 列表分页切换后附件仍对应正确协议
6. 租户隔离:不串附件
---
## 7. 改动文件清单
| 层 | 文件 |
|----|------|
| DB | 无(字段已存在) |
| Backend | `pre_transit_sample.py`、`sample_reception.py` |
| Frontend 新建 | `protocol-attachment-mini-readonly/index.vue`、`utils/protocol-source-attachment.ts`、`composables/useAttachmentActions.ts` |
| Frontend 修改 | `PreTransitProtocolCardList.vue`、`SampleReceptionCardList.vue`、`pre-transit-sample/index.vue`、`sample-reception/index.vue`(或 `SampleReceptionCardList` 内直接 composable) |
---
## 8. 不在本期
- 样本接收 checklist 勾选
- 知情同意书在卡片展示
- 生产/质检工单卡片
- 将 `ProtocolAttachmentReadonly` 改为 size prop(本期独立迷你组件)