From 2c7ed94161e0e5b0760b382b9856b723f4b62502 Mon Sep 17 00:00:00 2001 From: HaHafeng Date: Sun, 7 Dec 2025 17:40:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(dc/tool-c):=20=E5=AE=8C=E6=88=90=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E5=9F=BA=E7=A1=80=E6=A1=86=E6=9E=B6=EF=BC=88Day=204?= =?UTF-8?q?=20MVP=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 核心功能: - 新增Tool C主入口(index.tsx, 258行):状态管理+布局 - 新增Header组件(91行):顶栏+返回按钮+导出 - 新增Toolbar组件(104行):7个快捷按钮+搜索框 - 新增DataGrid组件(111行):AG Grid Community集成 - 新增Sidebar组件(149行):右侧栏骨架版 - 新增API封装(toolC.ts, 218行):8个API方法 - 新增类型定义(types/index.ts, 62行) AG Grid集成: - 安装ag-grid-community + ag-grid-react - Excel风格表格渲染 - 列排序、过滤、调整宽度 - 缺失值高亮显示(红色斜体) - 数值右对齐 - 自定义Emerald绿色主题(ag-grid-custom.css, 113行) - 虚拟滚动支持大数据 路由配置: - 更新dc/index.tsx:新增ToolCModule懒加载 - 更新Portal.tsx:Tool C状态改为ready - 路径:/data-cleaning/tool-c API封装(8个方法): - uploadFile(上传CSV/Excel) - getSession(获取Session元数据) - getPreviewData(获取预览数据) - updateHeartbeat(延长10分钟) - generateCode(生成代码,不执行) - executeCode(执行代码) - processMessage(生成+执行,一步到位)核心API - getChatHistory(对话历史) 文档更新: - 新增Day 4前端基础完成总结(213行) - 更新工具C当前状态文档 - 更新TODO清单(Day 1-4标记完成) - 更新系统总体设计文档 测试数据准备: - cqol-demo.csv(21列x313行真实医疗数据) - G鼓膜穿孔数据.xlsx(备用) Day 5待完成: - MessageItem组件(消息渲染) - CodeBlock组件(Prism.js代码高亮) - InputArea组件(输入框交互) - InsightsPanel组件(数据洞察) - 完善Sidebar(完整Chat交互) - 端到端测试 影响范围: - frontend-v2/src/modules/dc/pages/tool-c/*(新增11个文件) - frontend-v2/src/modules/dc/api/toolC.ts(新增) - frontend-v2/src/modules/dc/index.tsx(更新路由) - frontend-v2/src/modules/dc/pages/Portal.tsx(启用Tool C) - docs/03-业务模块/DC-数据清洗整理/*(文档更新) - package.json(新增依赖) Breaking Changes: 无 总代码行数:+1106行(前端基础框架) Refs: #Tool-C-Day4 --- .../00-系统当前状态与开发指南.md | 2 +- .../DC-数据清洗整理/00-工具C当前状态与开发指南.md | 155 +- .../DC-数据清洗整理/00-模块当前状态与开发指南.md | 44 +- .../04-开发计划/工具C_Day4-5前端开发计划.md | 1278 +++++++++++++++++ .../04-开发计划/工具C_MVP开发_TODO清单.md | 145 +- .../05-测试文档/03-测试数据/G鼓膜穿孔数据.xlsx | Bin 0 -> 15218 bytes .../05-测试文档/03-测试数据/cqol-demo.csv | 312 ++++ .../06-开发记录/2025-12-07_工具C_Day4前端基础完成.md | 212 +++ frontend-v2/package-lock.json | 10 + frontend-v2/package.json | 1 + frontend-v2/src/modules/dc/api/toolC.ts | 217 +++ frontend-v2/src/modules/dc/index.tsx | 18 +- frontend-v2/src/modules/dc/pages/Portal.tsx | 2 +- .../dc/pages/tool-c/components/DataGrid.tsx | 111 ++ .../dc/pages/tool-c/components/Header.tsx | 90 ++ .../dc/pages/tool-c/components/Sidebar.tsx | 148 ++ .../dc/pages/tool-c/components/Toolbar.tsx | 103 ++ .../tool-c/components/ag-grid-custom.css | 112 ++ .../src/modules/dc/pages/tool-c/index.tsx | 257 ++++ .../modules/dc/pages/tool-c/types/index.ts | 61 + 20 files changed, 3173 insertions(+), 105 deletions(-) create mode 100644 docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md create mode 100644 docs/03-业务模块/DC-数据清洗整理/05-测试文档/03-测试数据/G鼓膜穿孔数据.xlsx create mode 100644 docs/03-业务模块/DC-数据清洗整理/05-测试文档/03-测试数据/cqol-demo.csv create mode 100644 docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-07_工具C_Day4前端基础完成.md create mode 100644 frontend-v2/src/modules/dc/api/toolC.ts create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/components/DataGrid.tsx create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/components/Header.tsx create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/components/Sidebar.tsx create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/components/Toolbar.tsx create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/components/ag-grid-custom.css create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/index.tsx create mode 100644 frontend-v2/src/modules/dc/pages/tool-c/types/index.ts diff --git a/docs/00-系统总体设计/00-系统当前状态与开发指南.md b/docs/00-系统总体设计/00-系统当前状态与开发指南.md index 6f1b015c..4ffe4586 100644 --- a/docs/00-系统总体设计/00-系统当前状态与开发指南.md +++ b/docs/00-系统总体设计/00-系统当前状态与开发指南.md @@ -39,7 +39,7 @@ | **AIA** | AI智能问答 | 10+专业智能体(选题评价、PICO梳理等) | ⭐⭐⭐⭐ | ✅ 已完成 | P1 | | **PKB** | 个人知识库 | RAG问答、私人文献库 | ⭐⭐⭐ | ✅ 已完成 | P1 | | **ASL** | AI智能文献 | 文献筛选、Meta分析、证据图谱 | ⭐⭐⭐⭐⭐ | 🚧 **正在开发** | **P0** | -| **DC** | 数据清洗整理 | ETL + 医学NER(百万行级数据) | ⭐⭐⭐⭐⭐ | ✅ **Tool B MVP完成** | **P0** | +| **DC** | 数据清洗整理 | ETL + 医学NER(百万行级数据) | ⭐⭐⭐⭐⭐ | 🚧 **Tool B完成 + Tool C Day 4完成** | **P0** | | **SSA** | 智能统计分析 | 队列/预测模型/RCT分析 | ⭐⭐⭐⭐⭐ | 📋 规划中 | P2 | | **ST** | 统计分析工具 | 100+轻量化统计工具 | ⭐⭐⭐⭐ | 📋 规划中 | P2 | | **RVW** | 稿件审查系统 | 方法学评估、审稿流程 | ⭐⭐⭐⭐ | 📋 规划中 | P3 | diff --git a/docs/03-业务模块/DC-数据清洗整理/00-工具C当前状态与开发指南.md b/docs/03-业务模块/DC-数据清洗整理/00-工具C当前状态与开发指南.md index 68961db4..b5f3a9a1 100644 --- a/docs/03-业务模块/DC-数据清洗整理/00-工具C当前状态与开发指南.md +++ b/docs/03-业务模块/DC-数据清洗整理/00-工具C当前状态与开发指南.md @@ -1,8 +1,8 @@ # 工具C(Tool C)- 科研数据编辑器 - 当前状态与开发指南 > **最后更新**: 2025-12-07 -> **当前版本**: Day 3 MVP开发完成 -> **开发进度**: Python微服务 ✅ | Session管理 ✅ | AI代码生成 ✅ | 前端开发 ⏸️ +> **当前版本**: Day 4 前端基础框架完成 +> **开发进度**: Python微服务 ✅ | Session管理 ✅ | AI代码生成 ✅ | 前端基础 ✅ | AI面板 🚧 --- @@ -12,10 +12,10 @@ |------|------|---------|------| | **Python微服务** | 100% | ~430行 | ✅ Day 1完成(Day 3优化) | | **Node.js后端** | 85% | ~2650行 | ✅ Day 2-3完成 | -| **前端界面** | 0% | 0行 | ⏸️ 未开始 | +| **前端界面** | 40% | ~1088行 | 🚧 Day 4基础完成 | | **数据库Schema** | 100% | 2表 | ✅ Day 2-3完成 | -| **测试通过率** | 81.8% | 9/11场景 | ✅ MVP达标 | -| **总体进度** | **60%** | **~3080行** | ✅ **后端MVP完成** | +| **后端测试通过率** | 81.8% | 9/11场景 | ✅ MVP达标 | +| **总体进度** | **70%** | **~4168行** | 🚧 **Day 4完成,Day 5进行中** | --- @@ -237,6 +237,94 @@ backend/src/modules/dc/tool-c/ --- +### Day 4: 前端基础框架 ✅ + +#### 文件结构(新增) +``` +frontend-v2/src/modules/dc/pages/tool-c/ +├── index.tsx # 258行 ✅ 主入口 +├── components/ +│ ├── Header.tsx # 91行 ✅ 顶部栏 +│ ├── Toolbar.tsx # 104行 ✅ 工具栏 +│ ├── DataGrid.tsx # 111行 ✅ AG Grid表格 +│ ├── Sidebar.tsx # 149行 ✅ 右侧栏(简化版) +│ └── ag-grid-custom.css # 113行 ✅ 自定义样式 +├── types/ +│ └── index.ts # 62行 ✅ 类型定义 +api/ +└── toolC.ts # 218行 ✅ API封装(6个方法) + +总代码:~1106行 +``` + +#### 核心功能 + +**4.1 AG Grid集成** ✅ +- **组件**: DataGrid.tsx +- **版本**: AG Grid Community 31.0.0 +- **功能**: + - ✅ Excel风格表格渲染 + - ✅ 列排序、过滤、调整宽度 + - ✅ 缺失值高亮显示(红色) + - ✅ 数值右对齐 + - ✅ 斑马纹背景 + - ✅ 空状态提示 + - ⏸️ 单元格编辑(Day 6) + +**4.2 页面布局** ✅ +- **主入口**: index.tsx +- **布局**: 左右分栏(flex布局) + - 左侧:Toolbar + DataGrid(flex-1) + - 右侧:Sidebar(固定420px宽度) +- **特性**: + - ✅ 响应式高度(h-screen) + - ✅ 溢出滚动控制 + - ✅ Emerald绿色主题 + +**4.3 API封装** ✅ +- **文件**: api/toolC.ts +- **方法数**: 8个 + ```typescript + // Session管理 + uploadFile(file) + getSession(sessionId) + getPreviewData(sessionId) + updateHeartbeat(sessionId) + + // AI功能 + generateCode(sessionId, message) + executeCode(sessionId, code, messageId) + processMessage(sessionId, message) // ⭐ 核心API + getChatHistory(sessionId, limit) + ``` + +**4.4 路由集成** ✅ +- **路径**: `/data-cleaning/tool-c` +- **状态**: Portal已启用(status: 'ready') +- **懒加载**: 使用React.lazy() +- **测试**: Portal卡片可点击进入 + +#### Day 4完成状态 + +✅ **基础框架100%完成**: +- ✅ Header(返回按钮、文件名、导出) +- ✅ Toolbar(7个快捷按钮、搜索框) +- ✅ DataGrid(AG Grid完整集成) +- ✅ Sidebar(骨架版本,待Day 5完善) +- ✅ API封装(8个方法) +- ✅ 路由配置(Portal → Tool C) + +⏸️ **待Day 5完成**: +- ⏸️ MessageItem组件(消息渲染) +- ⏸️ CodeBlock组件(代码高亮) +- ⏸️ InputArea组件(输入框) +- ⏸️ InsightsPanel组件(数据洞察) +- ⏸️ 文件上传完整流程 +- ⏸️ AI对话完整交互 +- ⏸️ 端到端测试 + +--- + ### Day 2: Session管理 + 数据处理 ✅ #### 文件结构(新增) @@ -670,19 +758,26 @@ backend/src/modules/dc/tool-c/ ### 前端 ``` -frontend-v2/src/modules/dc/tool-c/ -├── pages/ -│ └── ToolCEditor.tsx # 主编辑器页面 ⏸️ +frontend-v2/src/modules/dc/pages/tool-c/ +├── index.tsx # 258行 ✅ Day 4(主入口+状态管理) ├── components/ -│ ├── DataGrid.tsx # AG Grid表格 ⏸️ -│ ├── AICopilot.tsx # AI助手 ⏸️ -│ ├── FileUpload.tsx # 文件上传 ⏸️ -│ └── CodeBlock.tsx # 代码块 ⏸️ +│ ├── Header.tsx # 91行 ✅ Day 4(顶部栏) +│ ├── Toolbar.tsx # 104行 ✅ Day 4(7个快捷按钮) +│ ├── DataGrid.tsx # 111行 ✅ Day 4(AG Grid表格) +│ ├── Sidebar.tsx # 149行 ✅ Day 4(骨架版) +│ ├── ag-grid-custom.css # 113行 ✅ Day 4(Emerald主题) +│ ├── MessageItem.tsx # ⏸️ Day 5(消息渲染) +│ ├── CodeBlock.tsx # ⏸️ Day 5(代码高亮) +│ ├── InputArea.tsx # ⏸️ Day 5(输入框) +│ └── InsightsPanel.tsx # ⏸️ Day 5(数据洞察) ├── hooks/ -│ ├── useSession.ts # Session Hook ⏸️ -│ └── useAI.ts # AI Hook ⏸️ -└── types/ - └── index.ts # 类型定义 ⏸️ +│ └── useToolC.ts # ⏸️ Day 5(核心Hook,可选) +├── types/ +│ └── index.ts # 62行 ✅ Day 4(类型定义) +└── (API封装在 ../../api/toolC.ts) # 218行 ✅ Day 4(8个方法) + +✅ Day 4完成:~1106行 +⏸️ Day 5待完成:~400-600行(Chat组件) ``` --- @@ -795,23 +890,29 @@ curl -X POST http://localhost:3000/api/v1/dc/tool-c/test/execute \ | 2025-12-06 | Day 1完成 | [2025-12-06_工具C_Day1开发完成总结.md](./06-开发记录/2025-12-06_工具C_Day1开发完成总结.md) | | 2025-12-06 | Day 2完成 | [2025-12-06_工具C_Day2开发完成总结.md](./06-开发记录/2025-12-06_工具C_Day2开发完成总结.md) | | 2025-12-07 | Day 3完成 | [2025-12-06_工具C_Day3开发完成总结.md](./06-开发记录/2025-12-06_工具C_Day3开发完成总结.md) ✅ **后端MVP完成** | +| 2025-12-07 | Day 4完成 | 前端基础框架完成 ✅ **AG Grid集成** | --- ## 🎯 下一步行动 -### 立即执行(Day 2) -1. [ ] 创建 `dc_tool_c_sessions` 数据库表 -2. [ ] 实现 `SessionService.ts` -3. [ ] 实现 `DataProcessService.ts` -4. [ ] 集成OSS存储服务 -5. [ ] 创建 `SessionController.ts` +### 立即执行(Day 5)🚀 +1. [ ] 创建MessageItem组件(消息渲染) +2. [ ] 创建CodeBlock组件(Prism.js代码高亮) +3. [ ] 创建InputArea组件(输入框交互) +4. [ ] 创建InsightsPanel组件(数据洞察) +5. [ ] 完善Sidebar组件(完整Chat交互) +6. [ ] 实现文件上传完整流程 +7. [ ] 集成所有API +8. [ ] 端到端测试(上传→AI对话→执行→更新表格) -### 本周目标(Week 1) -- [ ] 完成Session管理和数据处理 -- [ ] 完成AI代码生成服务 -- [ ] 完成后端所有API端点 -- [ ] 通过Postman测试所有API +### 本周目标(Week 2) +- [x] 完成Session管理和数据处理 ✅ +- [x] 完成AI代码生成服务 ✅ +- [x] 完成后端所有API端点 ✅ +- [x] 完成前端基础框架 ✅ +- [ ] 完成AI Chat面板 🚧 +- [ ] 端到端流程测试通过 ⏸️ --- diff --git a/docs/03-业务模块/DC-数据清洗整理/00-模块当前状态与开发指南.md b/docs/03-业务模块/DC-数据清洗整理/00-模块当前状态与开发指南.md index f2a8bcf2..ba21e32f 100644 --- a/docs/03-业务模块/DC-数据清洗整理/00-模块当前状态与开发指南.md +++ b/docs/03-业务模块/DC-数据清洗整理/00-模块当前状态与开发指南.md @@ -54,21 +54,22 @@ DC数据清洗整理模块提供4个智能工具,帮助研究人员清洗、整理、提取医疗数据。 ### 当前状态 -- **开发阶段**:🎉 Tool B MVP完成 + 🚀 Tool C Day 1完成 +- **开发阶段**:🎉 Tool B MVP完成 + 🚀 Tool C Day 4完成(后端+前端基础) - **已完成功能**: - ✅ Portal:智能数据清洗工作台(2025-12-02) - ✅ Tool B 后端:病历结构化机器人(2025-11-28重建完成) - ✅ Tool B 前端:5步工作流完整实现(2025-12-03) - ✅ Tool B API对接:6个端点全部集成(2025-12-03) - ✅ Tool C Python微服务:代码执行引擎(2025-12-06,Day 1) - - ✅ Tool C Node.js后端:Python服务集成(2025-12-06,Day 1) + - ✅ Tool C Node.js后端:完整实现(2025-12-06-07,Day 1-3) + - ✅ Tool C 前端基础:AG Grid + 布局框架(2025-12-07,Day 4) - **开发中功能**: - - 🟡 Tool C:科研数据编辑器(15%完成,MVP Day 1/15) + - 🟡 Tool C:科研数据编辑器(70%完成,MVP Day 4/15) - ✅ Python微服务扩展(AST检查 + Pandas执行) - - ✅ Node.js后端集成(PythonExecutorService) - - ⏸️ Session管理(Day 2) - - ⏸️ AI代码生成(Day 3-5) - - ⏸️ 前端开发(Day 6-10) + - ✅ Node.js后端完整(Session + AI代码生成) + - ✅ 前端基础框架(AG Grid + Header + Toolbar) + - 🚧 AI Chat面板(Day 5进行中) + - ⏸️ 端到端测试(Day 5下午) - **未开发功能**: - ❌ Tool A:医疗数据超级合并器 - **模型支持**:DeepSeek-V3 + Qwen-Max 双模型交叉验证(已验证可用) @@ -104,13 +105,40 @@ DC数据清洗整理模块提供4个智能工具,帮助研究人员清洗、 - Excel导出功能可用 **Tool C - 科研数据编辑器**: -- ✅ 2025-12-06:**Day 1完成** 🚀 +- ✅ 2025-12-06:**Day 1完成** - Python微服务 🚀 - Python微服务扩展(dc_executor.py,427行) - AST静态代码检查(危险模块拦截) - Pandas沙箱执行(30秒超时保护) - FastAPI新增2个端点(/api/dc/validate, /api/dc/execute) - Node.js后端集成(PythonExecutorService,177行) - 测试控制器和路由(3个测试端点) + - 测试通过率:100% + +- ✅ 2025-12-06:**Day 2完成** - Session管理 ✅ + - SessionService.ts(383行)+ DataProcessService.ts(303行) + - SessionController.ts(300行) + - 数据库表:dc_tool_c_sessions(12字段) + - 6个Session API端点 + - OSS存储集成(零落盘) + - 测试通过率:100% (7/7) + +- ✅ 2025-12-07:**Day 3完成** - AI代码生成 ✅ + - AICodeService.ts(550行)+ AIController.ts(257行) + - 数据库表:dc_tool_c_ai_history(14字段) + - 10个Few-shot示例(Level 1-4) + - 自我修正机制(最多3次重试) + - 4个AI API端点 + - 测试通过率:81.8% (9/11场景) + +- ✅ 2025-12-07:**Day 4完成** - 前端基础框架 ✅ + - index.tsx(258行)- 主入口+状态管理 + - Header.tsx(91行)+ Toolbar.tsx(104行) + - DataGrid.tsx(111行)- AG Grid Community集成 + - Sidebar.tsx(149行)- 骨架版 + - API封装toolC.ts(218行,8个方法) + - AG Grid自定义样式(Emerald绿色主题) + - 路由配置 + Portal启用 + - 总代码:~1106行 - 功能验证100%通过 --- diff --git a/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md new file mode 100644 index 00000000..459e165f --- /dev/null +++ b/docs/03-业务模块/DC-数据清洗整理/04-开发计划/工具C_Day4-5前端开发计划.md @@ -0,0 +1,1278 @@ +# 工具C Day 4-5 前端开发计划(最终版) + +> **制定日期**: 2025-12-07 +> **开发目标**: Tool C前端MVP - AI驱动的科研数据编辑器 +> **预计工时**: 12-16小时(Day 4: 6-8h, Day 5: 6-8h) +> **核心目标**: 端到端AI数据清洗流程可用 + +--- + +## 🎯 核心决策 + +| 决策项 | 最终方案 | 理由 | +|--------|---------|------| +| **表格组件** | **AG Grid Community** | 用户强烈要求,Excel级体验 | +| **开发优先级** | **AI核心功能优先** | 先验证后端,UI细节后续优化 | +| **UI风格** | **严格还原原型V6** | Emerald绿色主题,符合Tool C定位 | +| **测试数据** | **真实医疗数据** | cqol-demo.csv (21列x300+行) | +| **Day 4-5目标** | **AI核心功能可用** | 上传→AI对话→执行→更新表格 | +| **代码风格** | **同Tool B标准** | TypeScript + Tailwind + Lucide | + +--- + +## 📦 技术栈 + +### 核心依赖 +```json +{ + "ag-grid-community": "^31.0.0", // 表格核心 + "ag-grid-react": "^31.0.0", // React集成 + "react": "^18.2.0", + "react-router-dom": "^6.x", + "lucide-react": "^0.x", // 图标库 + "axios": "^1.x" // HTTP客户端 +} +``` + +### 技术选型 +- **React 18**: Hooks + TypeScript +- **Tailwind CSS**: 原子化CSS +- **AG Grid Community**: 开源版,功能足够MVP +- **Prism.js**: 代码语法高亮 +- **React Markdown**: Markdown渲染(AI回复) + +--- + +## 📐 页面布局设计 + +``` +┌────────────────────────────────────────────────────────────┐ +│ Header (h-14) │ +│ [🟢 科研数据编辑器] lung_cancer.csv [撤销/重做] [导出] │ +└────────────────────────────────────────────────────────────┘ +┌──────────────────────────┬─────────────────────────────────┐ +│ Left Panel (flex-1) │ Right Sidebar (w-[420px]) │ +│ │ │ +│ ┌──────────────────────┐ │ ┌───────────────────────────┐ │ +│ │ Toolbar (h-16) │ │ │ Tab: [Chat] [Insights] │ │ +│ │ 7个快捷按钮 + 搜索 │ │ └───────────────────────────┘ │ +│ └──────────────────────┘ │ │ +│ │ ┌───────────────────────────┐ │ +│ ┌──────────────────────┐ │ │ Chat Messages Area │ │ +│ │ │ │ │ - 用户消息 │ │ +│ │ AG Grid Table │ │ │ - AI消息(含代码块) │ │ +│ │ (Excel风格) │ │ │ - 系统消息 │ │ +│ │ │ │ │ │ │ +│ │ 21列 x 300+行 │ │ └───────────────────────────┘ │ +│ │ │ │ │ +│ │ 支持: │ │ ┌───────────────────────────┐ │ +│ │ - 列排序 │ │ │ Input + Send Button │ │ +│ │ - 列宽调整 │ │ └───────────────────────────┘ │ +│ │ - 单元格编辑(后期) │ │ │ +│ │ - 选择高亮 │ │ │ +│ └──────────────────────┘ │ │ +└──────────────────────────┴─────────────────────────────────┘ +``` + +--- + +## 🗂️ 文件结构规划 + +``` +frontend-v2/src/modules/dc/pages/tool-c/ +├── index.tsx # 主入口(状态管理+布局) +├── components/ +│ ├── Header.tsx # 顶部栏 +│ ├── Toolbar.tsx # 工具栏(7个按钮) +│ ├── DataGrid.tsx # AG Grid表格(核心) +│ ├── Sidebar.tsx # 右侧栏容器 +│ ├── ChatPanel.tsx # Chat面板 +│ ├── InsightsPanel.tsx # Insights面板 +│ ├── MessageList.tsx # 消息列表 +│ ├── MessageItem.tsx # 单条消息 +│ ├── CodeBlock.tsx # 代码块渲染 +│ └── InputArea.tsx # 输入框 +├── hooks/ +│ ├── useToolC.ts # 核心状态管理Hook +│ ├── useSession.ts # Session管理 +│ ├── useChat.ts # AI对话逻辑 +│ └── useDataGrid.ts # 表格数据管理 +└── types/ + └── index.ts # TypeScript类型定义 + +frontend-v2/src/modules/dc/api/ +└── toolC.ts # API封装(6个方法) +``` + +--- + +## ⏱️ Day 4 开发计划(6-8小时) + +### 阶段1:项目初始化(1小时) + +#### 1.1 安装依赖 +```bash +cd frontend-v2 +npm install ag-grid-community ag-grid-react +npm install prismjs @types/prismjs +npm install react-markdown +``` + +#### 1.2 创建文件结构 +```bash +mkdir -p src/modules/dc/pages/tool-c/{components,hooks,types} +touch src/modules/dc/pages/tool-c/index.tsx +# ... 创建其他文件 +``` + +#### 1.3 更新路由配置 +```typescript +// src/App.tsx 或路由配置文件 +} /> +``` + +#### 1.4 更新Portal页面 +```typescript +// src/modules/dc/pages/Portal.tsx +// 将Tool C的status从'disabled'改为'ready' +{ + id: 'tool-c', + title: '科研数据编辑器', + status: 'ready', // ⭐ 修改这里 + route: '/data-cleaning/tool-c' +} +``` + +**交付物**: +- ✅ 依赖安装完成 +- ✅ 文件结构创建 +- ✅ Portal可点击进入Tool C + +--- + +### 阶段2:页面框架搭建(2小时) + +#### 2.1 创建主入口 (index.tsx) +```typescript +import { useState } from 'react'; +import Header from './components/Header'; +import Toolbar from './components/Toolbar'; +import DataGrid from './components/DataGrid'; +import Sidebar from './components/Sidebar'; + +interface ToolCState { + sessionId: string | null; + fileName: string; + data: any[]; + columns: any[]; + messages: any[]; + isLoading: boolean; +} + +const ToolC = () => { + const [state, setState] = useState({ + sessionId: null, + fileName: 'cqol-demo.csv', + data: [], + columns: [], + messages: [], + isLoading: false, + }); + + return ( +
+
+
+
+ +
+ +
+
+ +
+
+ ); +}; + +export default ToolC; +``` + +#### 2.2 创建Header组件 +```typescript +// components/Header.tsx +import { Table2, Undo2, Redo2, Download, ArrowLeft } from 'lucide-react'; +import { useNavigate } from 'react-router-dom'; + +interface HeaderProps { + fileName: string; + onUndo?: () => void; + onRedo?: () => void; + onExport?: () => void; +} + +const Header: React.FC = ({ fileName, onUndo, onRedo, onExport }) => { + const navigate = useNavigate(); + + return ( +
+
+ +
+
+ +
+ + 科研数据编辑器 + + Pro + + +
+ {fileName} +
+
+
+ + +
+ +
+
+ ); +}; + +export default Header; +``` + +#### 2.3 创建Toolbar组件 +```typescript +// components/Toolbar.tsx +import { Calculator, CalendarClock, ArrowLeftRight, FileSearch, Wand2, Filter, Search } from 'lucide-react'; + +const ToolbarButton = ({ icon: Icon, label, colorClass }: any) => ( + +); + +const Toolbar = () => { + return ( +
+ + + +
+ + +
+ +
+
+ + +
+
+ ); +}; + +export default Toolbar; +``` + +**交付物**: +- ✅ Header完成(带返回按钮) +- ✅ Toolbar完成(7个按钮) +- ✅ 基础布局可见 + +--- + +### 阶段3:AG Grid集成(3-4小时) + +#### 3.1 创建DataGrid组件 +```typescript +// components/DataGrid.tsx +import { AgGridReact } from 'ag-grid-react'; +import { ColDef } from 'ag-grid-community'; +import 'ag-grid-community/styles/ag-grid.css'; +import 'ag-grid-community/styles/ag-theme-alpine.css'; +import { useMemo } from 'react'; + +interface DataGridProps { + data: any[]; + columns: Array<{ id: string; name: string; type?: string }>; + onCellValueChanged?: (params: any) => void; +} + +const DataGrid: React.FC = ({ data, columns, onCellValueChanged }) => { + // 将列定义转换为AG Grid格式 + const columnDefs: ColDef[] = useMemo(() => { + return columns.map(col => ({ + field: col.id, + headerName: col.name, + sortable: true, + filter: true, + resizable: true, + editable: false, // MVP阶段暂不支持编辑 + width: 120, + minWidth: 80, + // 根据类型设置样式 + cellClass: (params) => { + if (params.value === null || params.value === undefined || params.value === '') { + return 'bg-red-50 text-red-400 italic'; + } + return ''; + }, + })); + }, [columns]); + + // 默认列配置 + const defaultColDef: ColDef = { + flex: 0, + sortable: true, + filter: true, + resizable: true, + }; + + // 如果没有数据,显示空状态 + if (data.length === 0) { + return ( +
+
+

暂无数据

+

请在右侧AI助手中上传文件

+
+
+ ); + } + + return ( +
+
+ +
+
+ ); +}; + +export default DataGrid; +``` + +#### 3.2 自定义AG Grid样式 +```css +/* 在全局CSS或组件内添加 */ +.ag-theme-alpine { + --ag-header-background-color: #f8fafc; + --ag-header-foreground-color: #475569; + --ag-border-color: #e2e8f0; + --ag-row-hover-color: #f0fdf4; + --ag-selected-row-background-color: #d1fae5; + --ag-font-family: inherit; + --ag-font-size: 13px; +} + +.ag-theme-alpine .ag-header-cell { + font-weight: 600; +} + +.ag-theme-alpine .ag-cell { + display: flex; + align-items: center; +} +``` + +#### 3.3 测试数据加载 +```typescript +// 临时测试:在index.tsx中硬编码测试数据 +const mockData = [ + { id: 'P001', age: 27, sex: '女', bmi: 23.1, smoke: '否' }, + { id: 'P002', age: 24, sex: '男', bmi: 16.7, smoke: '是' }, + { id: 'P003', age: null, sex: '男', bmi: null, smoke: '是' }, +]; + +const mockColumns = [ + { id: 'id', name: '病人ID', type: 'text' }, + { id: 'age', name: '年龄', type: 'number' }, + { id: 'sex', name: '性别', type: 'category' }, + { id: 'bmi', name: 'BMI', type: 'number' }, + { id: 'smoke', name: '吸烟史', type: 'category' }, +]; +``` + +**交付物**: +- ✅ AG Grid成功渲染 +- ✅ 缺失值高亮显示 +- ✅ 列排序/过滤可用 +- ✅ 列宽可调整 + +--- + +## ⏱️ Day 5 开发计划(6-8小时) + +### 阶段4:AI Chat面板(3小时) + +#### 4.1 创建Sidebar组件 +```typescript +// components/Sidebar.tsx +import { useState } from 'react'; +import { MessageSquare, Lightbulb, X } from 'lucide-react'; +import ChatPanel from './ChatPanel'; +import InsightsPanel from './InsightsPanel'; + +interface SidebarProps { + isOpen: boolean; + onClose: () => void; + messages: any[]; + onSendMessage: (message: string) => void; + dataStats?: any; +} + +const Sidebar: React.FC = ({ isOpen, onClose, messages, onSendMessage, dataStats }) => { + const [activeTab, setActiveTab] = useState<'chat' | 'insights'>('chat'); + + if (!isOpen) return null; + + return ( +
+ {/* Tab Header */} +
+
+ + +
+ +
+ + {/* Tab Content */} +
+ {activeTab === 'chat' ? ( + + ) : ( + + )} +
+
+ ); +}; + +export default Sidebar; +``` + +#### 4.2 创建ChatPanel组件 +```typescript +// components/ChatPanel.tsx +import { useRef, useEffect } from 'react'; +import MessageItem from './MessageItem'; +import InputArea from './InputArea'; + +interface ChatPanelProps { + messages: any[]; + onSendMessage: (message: string) => void; + isLoading?: boolean; +} + +const ChatPanel: React.FC = ({ messages, onSendMessage, isLoading }) => { + const messagesEndRef = useRef(null); + + const scrollToBottom = () => { + messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' }); + }; + + useEffect(() => { + scrollToBottom(); + }, [messages]); + + return ( +
+ {/* Messages Area */} +
+ {messages.length === 0 && ( +
+

👋 您好!我是您的AI数据分析师

+

试试说:"把年龄大于60的标记为老年组"

+
+ )} + {messages.map((msg) => ( + + ))} + {isLoading && ( +
+
+ AI正在思考... +
+ )} +
+
+ + {/* Input Area */} + +
+ ); +}; + +export default ChatPanel; +``` + +#### 4.3 创建MessageItem组件 +```typescript +// components/MessageItem.tsx +import { User, Bot, CheckCircle2, XCircle, Play } from 'lucide-react'; +import CodeBlock from './CodeBlock'; + +interface MessageItemProps { + message: { + id: string; + role: 'user' | 'assistant' | 'system'; + content: string; + code?: { + content: string; + status: 'pending' | 'running' | 'success' | 'error'; + }; + onExecute?: () => void; + }; +} + +const MessageItem: React.FC = ({ message }) => { + const { role, content, code } = message; + + // 系统消息 + if (role === 'system') { + return ( +
+
+ {content} +
+
+ ); + } + + // 用户消息 + if (role === 'user') { + return ( +
+
+ {content} +
+
+ +
+
+ ); + } + + // AI消息 + return ( +
+
+ +
+
+
+ {content} +
+ {code && ( +
+ +
+ +
+
+ )} +
+
+ ); +}; + +export default MessageItem; +``` + +#### 4.4 创建CodeBlock组件 +```typescript +// components/CodeBlock.tsx +import { Copy, Check } from 'lucide-react'; +import { useState } from 'react'; +import Prism from 'prismjs'; +import 'prismjs/themes/prism-tomorrow.css'; +import 'prismjs/components/prism-python'; + +interface CodeBlockProps { + code: string; + language?: string; +} + +const CodeBlock: React.FC = ({ code, language = 'python' }) => { + const [copied, setCopied] = useState(false); + + const handleCopy = () => { + navigator.clipboard.writeText(code); + setCopied(true); + setTimeout(() => setCopied(false), 2000); + }; + + const highlightedCode = Prism.highlight( + code, + Prism.languages[language] || Prism.languages.python, + language + ); + + return ( +
+
+ {language} + +
+
+        
+      
+
+ ); +}; + +export default CodeBlock; +``` + +#### 4.5 创建InputArea组件 +```typescript +// components/InputArea.tsx +import { Send } from 'lucide-react'; +import { useState, KeyboardEvent } from 'react'; + +interface InputAreaProps { + onSend: (message: string) => void; + disabled?: boolean; +} + +const InputArea: React.FC = ({ onSend, disabled }) => { + const [input, setInput] = useState(''); + + const handleSend = () => { + if (!input.trim() || disabled) return; + onSend(input); + setInput(''); + }; + + const handleKeyDown = (e: KeyboardEvent) => { + if (e.key === 'Enter' && !e.shiftKey) { + e.preventDefault(); + handleSend(); + } + }; + + return ( +
+
+