日期:2026-07-02
状态:已确认 / 已实现
关联模块:web-admin捐赠协议单新增弹窗(DonationFormDialog.vue)
关联常量:SAMPLE_TYPE_PERINATAL_HSC、SAMPLE_TYPE_UC_MSC(sample-production-reception-fields.ts)
科研捐赠协议单新增时,左侧「一键导入」支持粘贴客户提供的标准文本,解析后自动填充右侧表单。客户文本存在两种典型场景:
当前实现仅支持首行标题推断一个样本类型、固定快递运输、胎次仅识别阿拉伯数字、时间格式不支持「点」,无法正确导入多样本数据。
kdys,顺风车等 → ryxd(人员携带)。2)。18点05分 格式(与 12时17分 等价)。sampleCollectTime 取各样本采集时间中的最早值(已确认:选项 A)。sample_collect_time 字段(方案 B,后续若产品要求再立项)。围产期干细胞(捐献)
产妇姓名:李会
新生儿性别:男
新生儿体重:3900g
新生儿评分: 9
分娩时间:2026年6月22日12时17分
造血干细胞采集时间:2026年6月22日12时18分
母血采集时间:未采集
分娩方式:顺产
胎次:3
采集医护:王天琪
采集医院:利辛县人民医院
运输方式:顺丰快递
销售人员:赵文静
采集医院:利辛县人民医院
期望结果:1 条样本(围产期造血干细胞);运输 kdys + 顺丰;胎次 3。
围产期干细胞(科研脐带)
产妇姓名:陆玲
新生儿性别:男孩
新生儿体重:3700g
分娩时间:2026年3月14日 18点05分
造血干细胞样本采集时间:2026年3月14日 18点06分
脐带采集时间:2026年3月14日 18点08分
母血采集时间:2026年3月14日 19点40分
分娩方式:顺产
胎次:二胎
运输方式:顺风车
销售人员:张慧茹
采集医院:涡阳县中医院
期望结果:2 条样本(围产期造血干细胞、脐带间充质干细胞);协议级 sampleCollectTime = 2026-03-14 18:06(最早);运输 ryxd,不填快递公司;胎次 2。
| 优先级 | 规则 | 说明 |
|---|---|---|
| 1 | 采集时间字段 | 存在且值可解析 → 创建对应样本行(可多条) |
| 2 | 首行标题 | 无采集时间字段时,回退现有 matchCellSampleType(header) 逻辑 |
采集时间字段 → 样本类型映射:
| 字段名(含别名) | 目标类型名 | typeKey |
|---|---|---|
造血干细胞样本采集时间、造血干细胞采集时间、样本采集时间 |
围产期造血干细胞 | hsc |
脐带采集时间 |
脐带间充质干细胞 | uc_msc |
formData.sampleCollectTime → biz_research_donation_collection.sample_collect_time。YYYY-MM-DD HH:mm)。客户文本字段仍为 运输方式;解析结果区分 模式 与 原始标签:
| 客户文本特征 | transportType |
后续处理 |
|---|---|---|
| 含「快递」「顺丰」「圆通」「中通」「韵达」「EMS」等 | kdys |
匹配 expressCompanyId(现有 matchExpressCompany) |
| 含「顺风车」「顺丰车」(后者为笔误)、「自行」「人员携带」「自带」「自送」等 | ryxd |
不填 expressCompanyId;可选后续人工填携带人 |
| 无法识别 | — | warning,不填运输 |
transport.transportType 为空时写入。| 输入示例 | 解析结果 |
|---|---|
3 |
3 |
二胎、三胎 |
2、3 |
第二胎 |
2 |
| 无法解析 | warning,不填 |
实现:parseBirthOrder(text) — 先 extractNumericPart;若无阿拉伯数字,再解析中文数字(一~十及「N胎」模式)。
| 字段 | 规则 |
|---|---|
| 新生儿性别 | 扩展识别 男孩→1、女孩→0 |
| 母血采集时间 | 「未采集」等 → 清空(已有) |
| 采集医院重复行 | 首次有效值为准(已有) |
| 母亲 / 医院 / 销售 | 远程匹配(已有) |
| 样本编码 | 每行样本 assignDonationSampleCodeIfMissing(已有) |
formData.samples 已有同类型样本且 sampleTypeId 非空,不重复添加;若为空行可复用。ElMessage.success 列出已填充项;ElMessage.warning 列出未匹配项。文件:web-admin/src/utils/donation-standard-import-parse.ts
扩展 DonationStandardImportParsed(或新增子类型):
export type DonationSampleImportHint = {
typeKey: 'hsc' | 'uc_msc'
typeName: string
collectTime?: string // 已解析为标准 datetime-minute
}
export type DonationStandardImportParsed = {
sampleTypeHeader: string
sampleHints: DonationSampleImportHint[] // 新增:0..N
transportModeText?: string // 原始运输方式文本
transportType?: 'kdys' | 'ryxd' // 新增:解析后的系统码
// ... 现有 common 字段保持不变
}
新增 / 导出函数:
| 函数 | 职责 |
|---|---|
parseBirthOrder(text) |
阿拉伯 + 中文胎次 |
resolveTransportType(text) |
运输文本 → kdys | ryxd | null |
matchSampleTypeByExactName(name, types) |
按 typeName 精确匹配(优先于 segment 评分) |
采集时间字段识别:在 KEY_ALIASES 之外,对 key 做 pattern 匹配(支持「造血干细胞样本采集时间」等变体),命中后写入 sampleHints 而非单一 sampleCollectTime。
回退:sampleHints.length === 0 时,保留现有 sampleCollectTime + 首行 matchCellSampleType 行为。
文件:web-admin/src/utils/chinese-datetime-parse.ts
[时::点] 均视为小时分隔符。2026年3月14日 18点06分 → 2026-03-14 18:06。可选新文件:web-admin/src/utils/chinese-numeral-parse.ts
parseChineseNumeral(text: string): number | null — 支持「二」「二胎」「三胎」等;供 parseBirthOrder 调用。文件:web-admin/src/views/research-donation/list/DonationFormDialog.vue — handleStandardImport()
1. parseDonationStandardImportText(text)
2. 并行:母亲 / 医院 / 销售 / 字典预加载(现有)
3. common 字段填空(性别、体重、评分、分娩时间、母血、分娩方式、胎次、医护…)
4. 样本行:
if sampleHints.length > 0:
for each hint:
matchSampleTypeByExactName(hint.typeName)
获取或创建对应样本行
assignDonationSampleCodeIfMissing
sampleCollectTime = min(hint.collectTime) // 最早
else:
现有单样本逻辑(首行 + 一行样本)
5. 运输:
if parsed.transportType === 'kdys': 匹配快递公司
if parsed.transportType === 'ryxd': transportType=ryxd,跳过 expressCompanyId
6. hydrateSampleLookupOptions + 消息反馈
| 实体 | 字段 | 说明 |
|---|---|---|
biz_research_donation_collection |
sample_collect_time |
协议级;多样本取最早采集时间 |
biz_research_donation_sample |
— | 无 per-sample 采集时间;本期不加 |
biz_research_donation_sample_transport |
transport_type |
kdys / ryxd |
新建:web-admin/src/utils/donation-standard-import-parse.test.ts(或项目现有 vitest 路径)
| 用例 | 断言 |
|---|---|
| 单样本完整文本(§2.1) | 1 个 hint(hsc);transportType=kdys;birthOrder=3 |
| 多样本完整文本(§2.2) | 2 个 hint(hsc+uc_msc);最早时间 18:06;transportType=ryxd;birthOrder=2 |
| 胎次「二胎」「3」 | 2、3 |
| 时间「18点06分」「12时18分」 | 等价解析 |
| 仅首行无采集时间 | sampleHints 空,回退首行匹配 |
| 运输「顺风车」「顺丰快递」 | ryxd / kdys |
手工验收(/#/market/research-donation/audit 或 list 页新增):
| 文件 | 改动类型 |
|---|---|
web-admin/src/utils/donation-standard-import-parse.ts |
扩展解析:多样本 hints、运输、胎次 |
web-admin/src/utils/chinese-datetime-parse.ts |
支持「点」 |
web-admin/src/utils/chinese-numeral-parse.ts |
新建(可选,也可内联于 parse 文件) |
web-admin/src/views/research-donation/list/DonationFormDialog.vue |
handleStandardImport 多样本 + 运输 |
web-admin/src/utils/donation-standard-import-parse.test.ts |
新建单元测试 |
不改:backend/、docs/sql/、OpenSpec(除非评审要求补充 ui-conventions 条目)。
ryxd 模式下客户文本通常不含携带人姓名;导入后可能需人工补全。SAMPLE_COLLECT_TIME_RULES;本期仅 hsc / uc_msc。18点06分 时间正确解析。| 日期 | 决策 | 理由 |
|---|---|---|
| 2026-07-02 | 方案 A:纯前端增强,不改表 | 最小改动、与现架构一致 |
| 2026-07-02 | 协议级 sampleCollectTime 取最早采集时间 |
用户确认选项 A |
| 2026-07-02 | 多样本以采集时间字段为准,首行标题仅作回退 | 避免标题歧义 |