Summary: - Implement DC module Portal page with 3 tool cards - Create ToolCard component with decorative background and hover animations - Implement TaskList component with table layout and progress bars - Implement AssetLibrary component with tab switching and file cards - Complete database verification (4 tables confirmed) - Complete backend API verification (6 endpoints ready) - Optimize UI to match prototype design (V2.html) Frontend Components (~715 lines): - components/ToolCard.tsx - Tool cards with animations - components/TaskList.tsx - Recent tasks table view - components/AssetLibrary.tsx - Data asset library with tabs - hooks/useRecentTasks.ts - Task state management - hooks/useAssets.ts - Asset state management - pages/Portal.tsx - Main portal page - types/portal.ts - TypeScript type definitions Backend Verification: - Backend API: 1495 lines code verified - Database: dc_schema with 4 tables verified - API endpoints: 6 endpoints tested (templates API works) Documentation: - Database verification report - Backend API test report - Phase 1 completion summary - UI optimization report - Development task checklist - Development plan for Tool B Status: Phase 1 completed (100%), ready for browser testing Next: Phase 2 - Tool B Step 1 and 2 development
176 lines
8.1 KiB
Markdown
176 lines
8.1 KiB
Markdown
# **技术设计文档:工具 C \- 科研数据编辑器 (The Research Editor)**
|
||
|
||
| 文档类型 | Technical Design Document (TDD) |
|
||
| :---- | :---- |
|
||
| **对应 PRD** | **PRD\_工具C\_科研数据编辑器\_V2.1.md** |
|
||
| **版本** | **V2.1** (新增 Pivot 算法与 Web Worker 架构) |
|
||
| **状态** | Final Draft |
|
||
| **核心目标** | 构建一个高性能的 Web 端数据编辑器,支持 5 万行级数据的实时清洗、变量加工(含长宽转换)与逻辑治理,提供“零延迟”操作体验。 |
|
||
|
||
## **1\. 总体架构设计 (Architecture Overview)**
|
||
|
||
为了满足 **PRD V2.1** 中“即时反馈”、“撤销重做”以及复杂的“长宽转换”需求,工具 C 采用 **"Local-First" (本地优先)** 架构。
|
||
|
||
核心策略:
|
||
|
||
1. **数据驻留:** 数据加载后主要存储在浏览器的 **IndexedDB (Dexie.js)** 和 **内存 (Zustand)** 中。
|
||
2. **计算下放:** 复杂的计算逻辑(如 Pivot、公式解析)下放至 **Web Worker**,避免阻塞 UI 主线程。
|
||
|
||
### **1.1 系统架构图**
|
||
|
||
graph TD
|
||
subgraph Browser\_Layer \[浏览器端 (React SPA)\]
|
||
UI\_Shell\[UI 壳层: 扁平化 Toolbar \+ 智能 Sidebar\]
|
||
|
||
subgraph Core\_Engine \[核心引擎\]
|
||
GridComponent\[AG Grid (视图层)\]
|
||
StateManager\[Zustand Store (状态层)\]
|
||
|
||
subgraph Worker\_Thread \[Web Worker 线程\]
|
||
ComputeEngine\[计算引擎 (Math.js / Pivot Alg)\]
|
||
StatEngine\[统计引擎 (直方图/频次)\]
|
||
end
|
||
|
||
HistoryManager\[Immer Patches (撤销栈)\]
|
||
end
|
||
|
||
subgraph Local\_Storage \[持久化层\]
|
||
Dexie\[Dexie.js (IndexedDB Wrapper)\]
|
||
end
|
||
end
|
||
|
||
subgraph Server\_Layer \[服务端 (Node.js)\]
|
||
API\[Fastify API\]
|
||
S3\[对象存储 (MinIO/OSS)\]
|
||
end
|
||
|
||
User \--1.操作(如Pivot)--\> UI\_Shell
|
||
UI\_Shell \--2.发送消息(postMessage)--\> Worker\_Thread
|
||
Worker\_Thread \--3.计算结果--\> StateManager
|
||
StateManager \--4.更新视图--\> GridComponent
|
||
StateManager \--5.异步备份--\> Dexie
|
||
|
||
User \--6.保存/导出--\> API
|
||
|
||
## **2\. 技术选型 (Tech Stack)**
|
||
|
||
| 层级 | 技术组件 | 选型理由 |
|
||
| :---- | :---- | :---- |
|
||
| **表格核心** | **AG Grid Community** | 唯一能免费支持虚拟滚动、列拖拽、高性能渲染的 React 表格库。 |
|
||
| **本地数据库** | **Dexie.js (IndexedDB)** | 相比 localStorage (5MB限制),IndexedDB 容量大且异步,适合存储 5万+ 行的 JSON 数据集。 |
|
||
| **状态管理** | **Zustand \+ Immer** | Zustand 轻量高效;Immer 用于处理不可变数据结构,其 produce 和 patches 功能是实现 Undo/Redo 的核心。 |
|
||
| **计算引擎** | **Math.js \+ Web Worker** | 解决 JS 浮点数精度问题 (0.1+0.2\!=0.3);Web Worker 用于将 Pivot 等重计算移出主线程。 |
|
||
| **数据处理** | **Lodash** | 基础的数据操作(分组、过滤、深拷贝)。 |
|
||
| **可视化** | **Ant Design Charts** | 在智能侧边栏中绘制直方图 (Histogram) 和频次图 (Bar)。 |
|
||
|
||
## **3\. 核心模块详细设计**
|
||
|
||
### **3.1 核心计算引擎 (Compute Engine \- Web Worker)**
|
||
|
||
#### **A. 长宽转换 (Pivot / Reshaping Algorithm) \- V2.1 核心难点**
|
||
|
||
这是最复杂的计算任务,必须在 Web Worker 中执行,否则页面会卡死。
|
||
|
||
* **输入参数:**
|
||
* data: 原始对象数组 Row\[\]
|
||
* indexCol: 主键列名 (e.g., 'patient\_id') \- 确定“行”
|
||
* pivotKeyCol: 区分列名 (e.g., 'visit\_date') \- 确定“列后缀”
|
||
* valueCols: 值列名数组 (e.g., \['wbc', 'bmi'\]) \- 确定“填充值”
|
||
* **算法逻辑:**
|
||
1. **预检查 (Guard):** 计算 Unique(pivotKeyCol).length \* valueCols.length。如果生成的潜在列数 \> 1000,抛出错误“生成的列数过多,请先筛选数据”。
|
||
2. **分组 (Grouping):** 使用 \_.groupBy(data, indexCol) 按主键分组。
|
||
3. **转换 (Transformation):** 遍历每组数据:
|
||
* 创建一个新行对象,保留主键。
|
||
* 遍历该组的每一条记录,获取 pivotKeyCol 的值(例如 "2023-01-01")。
|
||
* 遍历 valueCols,将值映射为 ValueCol\_PivotKey (例如 "wbc\_2023-01-01")。
|
||
4. **Schema生成:** 动态生成新的 ColumnDefs。
|
||
* **输出:** { newRows, newColumnDefs }
|
||
|
||
#### **B. 公式变量 (Formula)**
|
||
|
||
* 使用 math.evaluate(formula, row)。
|
||
* **安全沙箱:** 限制公式中可访问的变量仅为当前行的数据,防止 XSS。
|
||
* **异常处理:** 处理除以零 (Infinity) 和非数字计算 (NaN) 的情况,统一返回 null 或错误标记。
|
||
|
||
### **3.2 智能侧边栏引擎 (Insight Engine)**
|
||
|
||
* **触发:** 监听 AG Grid 的 onColumnHeaderClicked 事件。
|
||
* **去抖 (Debounce):** 200ms 延迟计算,防止快速切换列时 UI 闪烁。
|
||
* **统计逻辑:**
|
||
* **数值列:** 计算 Min, Max, Mean, SD,并使用 Freedman-Diaconis 规则计算直方图的 Bins。
|
||
* **文本列:** 计算 Top 10 频率最高的词。
|
||
|
||
### **3.3 历史记录与撤销 (History Manager)**
|
||
|
||
* **Undo/Redo 策略:**
|
||
* **普通操作 (编辑/替换):** 记录 patches (Immer)。
|
||
* **结构性操作 (Pivot/拆分/生成新变量):** 由于表结构完全改变,记录 patches 成本过高且难以回滚。策略改为:**在执行此类操作前,强制保存一个全量快照 (Checkpoint)**。撤销时直接重载快照。
|
||
|
||
## **4\. 数据流与存储设计**
|
||
|
||
### **4.1 浏览器端存储 (Dexie Schema)**
|
||
|
||
用于暂存用户正在编辑的数据,实现“自动快照”和“崩溃恢复”。
|
||
|
||
const db \= new Dexie('ResearchEditorDB');
|
||
db.version(2).stores({
|
||
// 项目元数据
|
||
projects: '++id, name, lastModified, rowCount',
|
||
|
||
// 数据块 (Chunks): 将 5万行数据切分为多个 Chunk 存储,避免单次读写过大导致浏览器崩溃
|
||
dataChunks: '\[projectId+chunkIndex\], projectId',
|
||
|
||
// 操作历史 (用于恢复现场)
|
||
history: 'projectId, stack',
|
||
|
||
// 完整快照 (用于 Pivot 等大操作的回滚)
|
||
checkpoints: '++id, projectId, createdAt'
|
||
});
|
||
|
||
### **4.2 后端存储 (PostgreSQL \+ OSS)**
|
||
|
||
后端仅负责存储“已保存”的快照,不参与实时编辑。
|
||
|
||
model DatasetSnapshot {
|
||
id String @id @default(uuid())
|
||
taskId String // 关联任务
|
||
version Int // 版本号
|
||
|
||
// 存储为大的 JSON Blob,或者指向 OSS 文件路径 (推荐 OSS)
|
||
// 内容包含:rows\[\], columnDefs\[\], metadata
|
||
ossKey String
|
||
|
||
createdAt DateTime @default(now())
|
||
}
|
||
|
||
## **5\. API 接口定义**
|
||
|
||
* POST /api/editor/init: 初始化编辑器会话,从 OSS 加载原始文件(如果是从工具 A/B 流转过来的)。
|
||
* POST /api/editor/save: 保存当前快照。
|
||
* POST /api/editor/export: 请求后端生成 Excel/SPSS 文件。
|
||
* *Payload:* { rows: \[...\], format: 'spss' }
|
||
* *说明:* 如果数据量小,直接前端 SheetJS 生成;数据量大 (\>5MB) 发给后端生成。
|
||
|
||
## **6\. 性能准入与边界 (Performance Guardrails)**
|
||
|
||
| 数据量级 | 策略 |
|
||
| :---- | :---- |
|
||
| **\< 50,000 行** | **全量加载模式**。所有数据都在内存/IndexedDB,操作极快。 |
|
||
| **\> 50,000 行** | **降采样模式 (Downsampling)**。前端仅加载前 5 万行用于预览和规则制定。导出时,将清洗规则(Recipe)发送给后端,由后端 Worker 对全量数据进行批处理。 |
|
||
|
||
## **7\. 开发计划 (Milestones)**
|
||
|
||
1. **Week 1: 核心网格与存储**
|
||
* 搭建 React \+ AG Grid 环境。
|
||
* 实现 SheetJS 导入与 Dexie.js 持久化逻辑。
|
||
2. **Week 2: 扁平化工具栏与 Web Worker**
|
||
* 搭建 Web Worker 通信架构。
|
||
* 实现 Formula 计算和 Math.js 集成。
|
||
* 实现 Undo/Redo 栈(Immer)。
|
||
3. **Week 3: 复杂计算 (Pivot)**
|
||
* **重点攻坚:** 在 Web Worker 中实现 Pivot 算法。
|
||
* 实现 Pivot 的 UI 配置弹窗。
|
||
4. **Week 4: 智能侧边栏与导出**
|
||
* 开发直方图/频次图组件 (AntD Charts)。
|
||
* 实现分箱、映射、填补缺失值逻辑。
|
||
* 对接后端保存接口。 |