fix(web-admin): 样本接收展示协议知情同意书等附件

质检样本接收列表与弹窗需查看采集协议侧附件。后端待接收/已接收列表补齐协议附件字段;前端列表增加知情同意书缩略图,接收弹窗右侧改为上运输、下协议附件分组展示。

关联 #43

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
zlwuandCursor committed 2026-11-05 21:53:56 +08:00
1 parent 9cf1110495
commit c40feab76a
6 files changed
+362 -34

No files matched your search

@@ -0,0 +1,62 @@
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import {
getConsentProtocolAttachment,
getSourceProtocolAttachment,
getSourceProtocolAttachmentGroups
} from './protocol-source-attachment'
describe('protocol-source-attachment', () => {
it('returns health survey as primary for cell storage', () => {
const meta = getSourceProtocolAttachment({
sourceType: 'cell_storage',
healthSurveyAttachmentFiles: [{ id: '1', fileUrl: '/a.png' }]
})
assert.equal(meta.label, '孕妇健康调查表')
assert.equal(meta.files.length, 1)
})
it('returns infectious disease report as primary for research donation', () => {
const meta = getSourceProtocolAttachment({
sourceType: 'research_donation',
infectiousDiseaseReportAttachmentFiles: [{ id: '2', fileUrl: '/b.png' }]
})
assert.equal(meta.label, '传染病检测报告')
assert.equal(meta.files.length, 1)
})
it('returns consent attachment from shared field', () => {
const meta = getConsentProtocolAttachment({
consentAttachmentFiles: [{ id: '3', fileUrl: '/c.png' }]
})
assert.equal(meta.label, '知情同意书')
assert.equal(meta.files.length, 1)
})
it('groups cell storage attachments for reception dialog', () => {
const groups = getSourceProtocolAttachmentGroups({
sourceType: 'cell_storage',
protocolAttachmentFiles: [{ id: 'p' }],
consentAttachmentFiles: [{ id: 'c' }],
healthSurveyAttachmentFiles: [{ id: 'h' }]
})
assert.deepEqual(
groups.map((g) => g.label),
['协议附件', '知情同意书', '孕妇健康调查表']
)
assert.ok(groups.every((g) => g.files.length === 1))
})
it('groups research donation attachments for reception dialog', () => {
const groups = getSourceProtocolAttachmentGroups({
sourceType: 'research_donation',
consentAttachmentFiles: [{ id: 'c' }],
infectiousDiseaseReportAttachmentFiles: [{ id: 'i' }],
attachmentFiles: [{ id: 'o' }]
})
assert.deepEqual(
groups.map((g) => g.label),
['知情同意书', '传染病检测报告', '其他附件']
)
})
})
@@ -8,7 +8,7 @@ function normalizeAttachmentFiles(raw: unknown): Array<Record<string, unknown>>
return raw.filter((item) => item && typeof item === 'object') as Array<Record<string, unknown>>
}
/** 按来源返回协议级附件标签与文件列表(细胞存储=孕妇健康调查表,科研捐赠=传染病检测报告) */
/** 按来源返回协议级主附件标签与文件列表(细胞存储=孕妇健康调查表,科研捐赠=传染病检测报告) */
export function getSourceProtocolAttachment(
row: Record<string, unknown>
): ProtocolSourceAttachmentMeta {
@@ -24,3 +24,54 @@ export function getSourceProtocolAttachment(
files: normalizeAttachmentFiles(row.healthSurveyAttachmentFiles)
}
}
/** 知情同意书(细胞存储与科研捐赠共用字段) */
export function getConsentProtocolAttachment(
row: Record<string, unknown>
): ProtocolSourceAttachmentMeta {
return {
label: '知情同意书',
files: normalizeAttachmentFiles(row.consentAttachmentFiles)
}
}
/**
* 样本接收弹窗:按来源返回质检需查看的协议附件分组。
* 细胞存储:协议附件 / 知情同意书 / 孕妇健康调查表
* 科研捐赠:知情同意书 / 传染病检测报告 / 其他附件
*/
export function getSourceProtocolAttachmentGroups(
row: Record<string, unknown>
): ProtocolSourceAttachmentMeta[] {
const source = String(row.sourceType || 'cell_storage').trim()
if (source === 'research_donation') {
return [
{
label: '知情同意书',
files: normalizeAttachmentFiles(row.consentAttachmentFiles)
},
{
label: '传染病检测报告',
files: normalizeAttachmentFiles(row.infectiousDiseaseReportAttachmentFiles)
},
{
label: '其他附件',
files: normalizeAttachmentFiles(row.attachmentFiles)
}
]
}
return [
{
label: '协议附件',
files: normalizeAttachmentFiles(row.protocolAttachmentFiles)
},
{
label: '知情同意书',
files: normalizeAttachmentFiles(row.consentAttachmentFiles)
},
{
label: '孕妇健康调查表',
files: normalizeAttachmentFiles(row.healthSurveyAttachmentFiles)
}
]
}