日期:2026-07-13
状态:已确认(展示形态 B · 迷你缩略图)
关联:2026-07-13-protocol-consent-health-survey-design.md(孕妇健康调查表字段)、捐赠单传染病检测报告字段
在以下三个卡片场景中,按来源展示协议单级附件,支持点击预览/下载;无附件显示「无」。
| 页面 | 位置 |
|---|---|
| 预产及在途样本 | 紧凑小卡片 + 展开详情卡片 |
| 样本接收 | 待接收 Tab 卡片 + 已接收 Tab 卡片 |
sourceType |
展示标签 | 数据字段 |
|---|---|---|
cell_storage(默认) |
孕妇健康调查表 | healthSurveyAttachmentFiles |
research_donation |
传染病检测报告 | infectiousDiseaseReportAttachmentFiles |
说明:展示的是协议/捐赠单录入的附件,不是样本接收登记时的 receiveAttachmentFiles。
object-fit: cover;文档/视频:与 ProtocolAttachmentReadonly 相同的类型图标downloadAttachmentFile| 接口 | 细胞存储 | 科研捐赠 |
|---|---|---|
| 预产及在途列表 | 仅有 healthSurveyFormUrls 字符串 |
已有 infectiousDiseaseReportAttachmentFiles |
| 样本接收待/已接收列表 | 无协议附件字段 | 无协议附件字段 |
PreTransitProtocolCardList.vue、SampleReceptionCardList.vue 均未展示协议附件ProtocolAttachmentReadonly.vue 为标准尺寸(140×96),不适合紧凑卡片采用列表接口直接返回 *AttachmentFiles(与协议 CRUD 字段命名一致),前端新建迷你缩略图组件统一渲染。不做懒加载详情、不做前端 URL 手拆。
pre_transit_sample.py细胞存储行构建处(_protocol_to_dict 之后),补充:
d["healthSurveyAttachmentFiles"] = urls_to_attachment_list(
r.health_survey_form_urls, db, tenant_no
)
科研捐赠侧 _donation_to_dict(r, db, tenant_no) 已含 infectiousDiseaseReportAttachmentFiles,无需改动。
sample_reception.py在 _rows_to_sample_list_items、_donation_rows_to_sample_list_items 构建 item 时,从已 join 的 protocol / donation 实体补充:
healthSurveyAttachmentFiles ← protocol.health_survey_form_urlsinfectiousDiseaseReportAttachmentFiles ← donation.infectious_disease_report_urls使用现有 urls_to_attachment_list;协议/捐赠对象已在查询行中,不额外 N+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)。
web-admin/src/utils/protocol-source-attachment.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.openhandleAttachmentDownload(file) → downloadAttachmentFile供预产页、样本接收页、卡片组件父级共用。
PreTransitProtocolCardList.vue紧凑卡片(protocol-card-compact__body 底部,展开按钮之上):
<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。
SampleReceptionCardList.vue在 sample-reception-card__meta 末尾增加 meta-item(grid-column: 1 / -1 或 minmax(160px, 1fr) 以保证缩略图行宽度):
<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 传空避免重复。
待接收 / 已接收 同一展示逻辑。
web-admin/src/api/pre-transit-sample.ts 可为 PreTransitProtocolRow 补充附件字段注释;样本接收列表仍为 Record<string, unknown>,不强制改类型。
| 层 | 文件 |
|---|---|
| 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) |
ProtocolAttachmentReadonly 改为 size prop(本期独立迷你组件)