# 采集协议单 · 一键导入标准信息 > 日期:2026-07-02 > 状态:已实现 > 关联:`ProtocolFormDialog.vue`、捐赠单 `DonationFormDialog.vue` + `donation-standard-import-parse.ts` > 参考样例:客户提供的标准信息1(单样本趸交)、标准信息2(双存部分缴费) --- ## 1. 背景与目标 采集协议单**新增**弹窗需支持「一键导入」:粘贴客户标准文本,解析后填充各 Tab 字段。交互与捐赠协议单一致(左侧粘贴区 + 右侧基本信息,仅新增模式展示)。 ### 1.1 已确认业务规则 | 规则 | 决策 | |------|------| | **金额** | **以标准信息中的金额为准**(合同金额、转账金额等),不以样本优惠价自动合计覆盖导入结果 | | **缴费方式** | 文本为「微信 / 支付宝 / 银行卡 / 现金」等时,**默认趸交 `dj`**;仅当明确出现「分期」时设为 `fq` | | **转账方式** | 「转账方式:微信」或「缴费方式:微信」(非分期语义)→ 映射字典 `zzfs`(如微信→`wxzz`) | | **导入策略** | 点击一键导入时**先清空**可覆盖字段,再按当前粘贴内容填充(与捐赠单一致) | | **协议级采集时间** | 多样本时取各样本采集时间中的**最早值** | ### 1.2 非目标 - 后端新 API(纯前端解析 + 既有 lookup 接口) - 编辑模式下一键导入 - 附件、协议号自动生成规则变更 --- ## 2. 标准文本格式 ### 2.1 标准信息1(单样本 · 趸交 · 两笔转账) ``` 围产期干细胞储存 造血干细胞:ZKZX34000870 产妇姓名:刘晓艳 … 缴费方式:趸交 转账方式:微信 合同金额:22880元 转账金额:22880元 转账时间:2026年6月17日13时09分05秒2000元,6月18日15:50:12付20880元 孕妇电话:13966850002 运输方式:顺丰快递 预计送达时间: ``` ### 2.2 标准信息2(双存 · 部分缴费 · 人员携带) ``` 围产期干细胞储存(双存) 造血干细胞:ZKZX34000922 脐带间充质干细胞:ZKQD34000839 … 缴费方式:微信 合同金额:37000元 转账金额:2000元 转账时间:2026年3月10日11:34:40 运输方式:露露帮助到医院取样本送到实验室 备注:剩余尾款两天内交清 ``` --- ## 3. 字段映射 ### 3.1 公共字段(与捐赠类似) | 客户 key / 模式 | 目标字段 | 备注 | |-----------------|----------|------| | 产妇姓名 | 母亲姓名 / 关联客户 | 远程匹配 | | 孕妇电话 | `motherPhone` | 去空格 | | 新生儿性别 | `newbornSex` | 男孩/女孩 | | 新生儿体重 | `newbornWeightGram` | | | 新生儿评分 | `apgar1min` | | | 分娩时间 | `newbornDeliveryTime` | | | 母血采集时间 | `maternalBloodCollectTime` | 未采集→清空 | | 分娩方式 | `deliveryMode` | 含「刨宫产」→ `pgc` | | 胎次 | `birthOrder` | 中文数字 | | 采集医护 | `medicalStaff` | | | 采集医院 | `regionId` + `hospitalId` | | | 销售人员 | `salesUserId` | **仅销售,不改采集专员** | | 备注 | `remark` | | | 运输方式 | 样本 `transport` | 见 §3.4 | | 预计送达时间 | `transport.etaTime` | 空则跳过 | ### 3.2 样本:编码行 + 采集时间行 **编码行**(优先识别样本行): ``` 造血干细胞:ZKZX34000870 脐带间充质干细胞:ZKQD34000839 ``` | 类型关键词 | 系统类型名 | typeKey | |------------|------------|---------| | 造血干细胞(非间充质) | 围产期造血干细胞 | `hsc` | | 脐带间充质干细胞 | 脐带间充质干细胞 | `uc_msc` | **采集时间行**(与编码行按 typeKey 合并): | 字段名(含别名) | typeKey | |------------------|---------| | 造血干细胞采集时间、造血干细胞样本采集时间 | `hsc` | | 脐带间充质干细胞采集时间、脐带采集时间 | `uc_msc` | - 首行标题(围产期干细胞储存…)仅作**无编码/无时间行**时的兜底类型匹配。 - 协议级 `sampleCollectTime` = 各 hint 已解析 `collectTime` 的**最早值**。 **样本编码**:按文本中的 `ZK…` 编码远程查 `fetchSampleCodeList`,写入 `sampleCodeId` + `sampleCode`;找不到则 warning。 **样本价格**:匹配样本类型后带出 `storagePrice` 作为原价/优惠价初始值;**合同金额仍以文本「合同金额」为准**(§3.3)。 ### 3.3 缴费(金额以标准信息为准) | 客户字段 | 解析 | 写入 | |----------|------|------| | 缴费方式:趸交 | `payMode = dj` | 缴费主表 | | 缴费方式:分期 | `payMode = fq` | 缴费主表 + 分期默认参数 | | 缴费方式:微信/支付宝/… | **`payMode = dj`**(非分期) | 同时作为转账方式 hint | | 转账方式:微信 | `transferType` | 字典匹配 `zzfs` | | 合同金额:22880元 | `22880` | **`formData.contractAmount`**(权威,覆盖自动合计) | | 转账金额 | 单值或明细金额 | 缴费明细 `transferAmount` | | 转账时间 | 见 §3.3.1 | 缴费明细 `transferTime` | **趸交 + 部分已转**(标准2):`payMode=dj`,合同 37000,明细 1 条 transfer 2000;`syncPaymentDueAmounts()` 计算待缴应缴额。 **趸交 + 多笔转账**(标准1):解析 2 条明细(2000 + 20880),转账方式均为微信;合计应等于合同金额,不等则 warning。 #### 3.3.1 转账时间复杂格式 支持拆段,例如: `2026年6月17日13时09分05秒2000元,6月18日15:50:12付20880元` → 两条 `{ transferTime, transferAmount }`。 单段格式:`2026年3月10日11:34:40` + 全局「转账金额」字段。 ### 3.4 运输 复用 `resolveTransportType`(含顺丰快递→`kdys`、顺丰车→`ryxd`、顺风车/露露帮助…→`ryxd`)。 - `kdys`:匹配快递公司,填 `expressCompanyId` - `ryxd`:不填快递;可选从文本提取人名(如「露露」)→ `carrierName` --- ## 4. 技术设计 ### 4.1 新建解析器 **文件**:`web-admin/src/utils/protocol-standard-import-parse.ts` ```typescript export type ProtocolSampleImportHint = { typeKey: 'hsc' | 'uc_msc' typeName: string sampleCode?: string collectTime?: string } export type ProtocolPaymentTransferHint = { transferAmount: number transferTime: string // YYYY-MM-DD HH:mm:ss } export type ProtocolStandardImportParsed = { sampleTypeHeader: string sampleHints: ProtocolSampleImportHint[] motherName?: string motherPhone?: string newbornSex?: '1' | '0' newbornWeightGram?: number | null apgarScore?: number | null newbornDeliveryTime?: string sampleCollectTime?: string maternalBloodCollectTime?: string maternalBloodExplicitEmpty?: boolean deliveryMode?: string birthOrder?: number | null medicalStaff?: string hospitalName?: string salesUserName?: string payMode?: 'dj' | 'fq' contractAmount?: number | null transferTypeLabel?: string // 原始「微信」等,填充时查字典 paymentTransfers: ProtocolPaymentTransferHint[] transportModeText?: string transportType?: 'kdys' | 'ryxd' etaTime?: string remark?: string } ``` **复用**(import from 已有模块): - `parseChineseDatetimeText` / `formatDatetimeToMinute` - `parseBirthOrder` - `resolveTransportType` - `matchSampleTypeByExactName` / `matchCellSampleType` - `isBlankString` / `extractNumericPart` **新增**: - `parsePayMode(text)`:`分期`→`fq`,否则 `dj`(趸交、微信、空均默认 dj) - `parseSampleCodeLine(key, value)`:类型名 + ZK 编码 - `parsePaymentTransferSegments(text)`:多笔转账时间行 - `resolveTransferTypeCode(label, dictOptions)`:label→`wxzz` 等 ### 4.2 UI **文件**:`ProtocolFormDialog.vue` - 新增模式 Tab「基本信息」:左侧 `section-card--import`(与捐赠同布局类名,见 `DonationFormDialog` SCSS) - `standardImportText` + `handleStandardImport` - `clearFormBeforeStandardImport()`:清空导入覆盖范围(含 samples、paymentDetails、缴费主表金额字段、客户/采集字段;**保留**协议状态、登记日期、采集专员、附件) - `handleStandardImport` 流程见 §4.3 ### 4.3 填充流程 ``` 1. parseProtocolStandardImportText(text) 2. clearFormBeforeStandardImport() 3. 预加载:样本类型、站点、快递、转账字典 zzfs 4. 并行:母亲(by name/phone)、医院、销售用户 5. 写入采集/客户/新生儿字段 6. 按 sampleHints 创建样本行(类型+编码 lookup+运输) 7. formData.contractAmount = parsed.contractAmount(来自标准信息) 8. formData.payMode = parsed.payMode ?? 'dj' 9. 重建 paymentDetails from paymentTransfers + transferType 10. syncFormSamplesAfterImport() 11. syncPaymentDueAmounts()(不调用 syncContractAmount 覆盖合同额) 12. 若样本价合计与合同金额差异 > 0.01 → warning(提示人工核对样本优惠价) 13. ElMessage success/warning ``` ### 4.4 与捐赠差异摘要 | 项 | 捐赠 | 采集协议 | |----|------|----------| | 样本编码 | 自动生成 | 文本指定 + API 匹配 | | 合同金额 | 无 | **标准信息为准** | | 缴费 | 无 | 主表 + 明细 | | 销售导入 | 同时写采集专员 | **仅 salesUserId** | | 孕妇电话 | 无 | 有 | --- ## 5. 测试用例 | 用例 | 断言 | |------|------| | 标准信息1 全文 | 1 样本 ZKZX…;contract=22880;payMode=dj;2 条明细 2000+20880;运输 kdys | | 标准信息2 全文 | 2 样本;contract=37000;payMode=dj;1 明细 2000;运输 ryxd;remark 有值 | | 缴费方式:微信 | payMode=dj,transferType 匹配微信 | | 缴费方式:分期 | payMode=fq | | 刨宫产 / 头胎 | deliveryMode=pgc,birthOrder=1 | | 重复点击导入 | 旧数据清空,仅保留新粘贴结果 | --- ## 6. 改动文件清单 | 文件 | 改动 | |------|------| | `utils/protocol-standard-import-parse.ts` | 新建 | | `views/cell-storage/protocol/ProtocolFormDialog.vue` | UI + 导入逻辑 + SCSS | | `utils/donation-standard-import-parse.ts` | 可选:导出共享函数,避免重复 | | `utils/chinese-datetime-parse.ts` | 如需支持「付20880元」段内金额,扩展解析 | **不改**:后端、DB。 --- ## 7. 决策记录 | 日期 | 决策 | |------|------| | 2026-07-02 | 金额以标准信息为准,不用样本价自动合计覆盖合同金额 | | 2026-07-02 | 缴费方式「微信」等默认趸交,仅明确「分期」时分期 | | 2026-07-02 | 协议级 sampleCollectTime 取最早采集时间 | | 2026-07-02 | 导入前清空可覆盖字段 |