2026-07-02-protocol-standard-import-design.md 10 KB

采集协议单 · 一键导入标准信息

日期: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

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 导入前清空可覆盖字段