# **PRD:Tool A \- 医疗数据超级合并?(The Super Merger)** | 文档版本 | V2.0 (基准锚定? | | :---- | :---- | | **产品形?* | Web 端工具(分步向导?Wizard?| | **核心价?* | **解决临床科研中“一对多”数据对齐难题?* 基于“访视(Visit)”和“时间窗”逻辑,将散乱的化验、检查数据精准挂载到住院/门诊记录上?| | **目标用户** | 临床医生、科研助?| ## **一?产品流程?(User Flow)** 1\. 数据装载 (Payload) \-\> 2\. 定基?(Anchor & Window) \-\> 3\. 选列与预?(Schema) \-\> 4\. 智能合并 \-\> 5\. 结果与流? ## **二?核心功能需?(Functional Requirements)** ### **1\. 步骤一:数据装?(Payload)** * **P0:** **多文件上传:** 支持拖拽上传 .xlsx, .csv。建议大?\< 50MB/文件? * **P0:** **自动预检 (Pre-flight Check)?* * 上传即解析表头? * **红灯拦截?* 文件加密、表头为空、文件损?\-\> 禁止下一步? * **P1:** **加载配置/模板?* 若用户之前保存过“肺癌门诊合并规则”,允许一键加载,跳过后续配置? ### **2\. 步骤二:定基?(The Anchor) —?核心算法逻辑** 此步骤决定了最终大表的“骨架”(行数)和“归类逻辑”? #### **2.1 主表选择 (The Backbone)** * **P0:** 用户必须从上传的文件中指定一个作?**“主?(Visit Base)?*? * **定义?* 主表的每一行,代表最终大表的一个基准行(一次就?访视)。通常是《住院记录》或《门诊挂号》? #### **2.2 关键列映?(Key Mapping)** * **P0:** **ID 列对齐:** 用户需指定主表?Patient\_ID 列。系统自动在辅表中寻找同名列,允许人工修正? * **P0:** **时间基准列:** 用户需指定主表?Date 列(如“入院日期”)。这将作为时间窗的圆心? #### **2.3 辅表匹配策略 (Matching Strategy)** * **P0:** **时间窗配?(Time Window)?* * 设定规则:辅表的检查时间必须在 \[主表时间 \- X? 主表时间 \+ Y天\] 范围内? * **默认值:** $\\pm 7$ 天? * **P0:** **冲突处理 (Collision Handling)?* * *场景? 单次时间窗内,辅表有多条记录(如做了两次血常规)? * *选项 A (默认 \- 纵向展开)? 保留所有记录。主表信息复制,行数增加? * *选项 B (最近匹?? 仅保留离主表时间最近的一条,丢弃其他? ### **3\. 步骤三:选列与预?(The Schema)** 此步骤决定了最终大表的“血肉”(列宽)? #### **3.1 树状选择?(Tree Picker)** * **P0:** 展示所有文件的列结构? * 📂 主表 * ?住院? * ?诊断 * 📂 辅表 A (化验) * ?白细? * ?审核医生 (不勾? * **交互?* 支持按文件全?反选? #### **3.2 实时结构预览 (Live Schema Preview)** * **P0:** 在屏幕右侧实时展示\*\*“最终表头结构”\*\*(仅表头,不计算数据)? * **价值:** 让用户直观看到:“哦,原来我的表会变成这么长,包含这些列”? ### **4\. 步骤四:结果与流?(The Result)** * **P0:** **处理进度条:** 显示动态文案(“正在构建哈希索?..”、“正在进行时间窗碰撞...”)? * **P0:** **黄金预览 (Golden Preview)?* * 必须展示合并结果?**?5-10 ?* 真实数据? * 用于用户肉眼核对 ID 是否对齐? * **P0:** **质量看板?* * 成功生成行数? * 丢弃行数(ID不匹配或时间窗外)? * **P0:** **行动流转?* * \[下载 Excel\] * \[发送到 AI 结构化工具\] (流转 Token) * \[发送到 编辑器清洗\] (流转 Token) ## **三?核心算法逻辑 (Technical Logic)** ### **1\. 算法名称:基于时间窗的哈希流式连?(Time-Windowed Stream Hash Join)** ### **2\. 执行伪代?* // 1\. 内存构建 (Build Phase) // 将辅?(Small Tables) 读入内存 Map const lookupMap \= { "patient\_001": \[ { type: "lab", date: "2023-01-02", data: {...} }, // 记录1 { type: "lab", date: "2023-05-01", data: {...} } // 记录2 \] }; // 2\. 流式探测 (Probe Phase) // 逐行读取主表 (Main Table) streamMainTable.on('data', (mainRow) \=\> { const pId \= mainRow.id; const tStart \= mainRow.date \- 7 days; const tEnd \= mainRow.date \+ 7 days; // 在辅表中寻找符合时间窗的记录 const matchLabs \= lookupMap\[pId\].filter(lab \=\> lab.date \>= tStart && lab.date \<= tEnd ); if (matchLabs.length \=== 0\) { // 没匹配到,只输出主表信息 output.write({ ...mainRow, lab\_data: null }); } else { // 匹配到了 (处理一对多) matchLabs.forEach(lab \=\> { output.write({ ...mainRow, ...lab.data }); // 纵向展开 }); } }); ## **四?界面原型参?(UI Reference)** 请参?工具A\_超级合并器\_原型设计.tsx (V1.0) 中的 Step 2 ?Step 3 界面? * **Step 2 重点?* 主表选择单选框、时间列下拉框、策略单选钮? * **Step 3 重点?* 左右分栏布局(左侧树状勾选,右侧表格骨架预览)? ## **五?风险规避检?(Risk Check)** 1. **用户选错主表怎么办?** * *对策? ?Step 2 界面增加显眼?**Tip**:“主表通常是包含‘入院日期’或‘诊断信息’的表格”? 2. **时间格式乱七八糟怎么办?** * *对策? 后端在解析时间列时,必须使用强力?Parser(支?2023/1/1, 2023-01-01, 44927 等格式)。如果解析失败,归为“时间无效”,不进行匹配