# TraceStudio v0.2.2 功能更新 ## 🎉 本次更新概览 本次更新主要完善了多用户系统的细节功能,增强了拖拽交互,添加了节点编辑和持久化功能。 **更新日期**: 2026-01-07 **版本**: v0.2.2 **类型**: 功能增强 --- ## ✨ 新增功能 ### 1. 动态用户列表 ⭐⭐⭐ #### 功能描述 用户下拉框现在从后端API动态获取真实用户列表,不再使用写死的4个用户。 #### 技术实现 - **组件**: [web/src/components/HeaderBar.tsx](../web/src/components/HeaderBar.tsx) - **API**: `GET /api/users/list` - **Fallback**: 如果API失败,降级使用默认用户列表 `['guest', 'admin', 'dev', 'test']` #### 使用方式 ```typescript // 组件挂载时自动获取用户列表 React.useEffect(() => { const fetchUsers = async () => { const response = await fetch('/api/users/list') const data = await response.json() setUserList(data.users) // 更新用户列表 } fetchUsers() }, []) ``` #### 效果展示 ``` 用户下拉框显示: ┌────────────────────┐ │ 👤 guest ▼ │ ├────────────────────┤ │ ✓ guest │ │ admin │ │ dev │ │ analyst │ ← 新用户动态显示 │ researcher │ └────────────────────┘ ``` --- ### 2. 工作流右键导入 ⭐⭐ #### 功能描述 在文件浏览器中右键点击 `.utrace` 文件,新增"📂 导入工作流"选项,快速加载工作流。 #### 技术实现 - **组件**: [web/src/components/FileExplorer.tsx](../web/src/components/FileExplorer.tsx) - **触发**: 右键菜单 → 点击"📂 导入工作流" - **效果**: 调用 `loadWorkflow(file.path)` 加载到画布 #### 代码示例 ```typescript {contextMenu.file.extension === '.utrace' && (
{ loadWorkflow(contextMenu.file.path) .then(() => alert(`✅ 已导入工作流`)) .catch((error) => alert(`❌ 导入失败`)) }}> 📂 导入工作流
)} ``` #### 使用流程 1. 在文件浏览器导航到工作流目录 2. 右键点击 `.utrace` 文件 3. 选择"📂 导入工作流" 4. 工作流自动加载到画布 --- ### 3. 节点标题可编辑 ⭐⭐⭐ #### 功能描述 在属性面板(Inspector)中,节点标题现在可以点击编辑,自定义节点名称。 #### 技术实现 - **组件**: [web/src/components/Inspector.tsx](../web/src/components/Inspector.tsx) - **状态**: `isEditingLabel`, `tempLabel` - **保存**: Enter 确认,Escape 取消 #### 编辑流程 ``` 1. 点击节点标题 → 进入编辑模式 ┌────────────────────────┐ │ 📥 [CSV 数据加载器___] │ ← 输入框 └────────────────────────┘ 2. 输入新标题 → 按 Enter 确认 ┌────────────────────────┐ │ 📥 销售数据加载器 │ ← 已更新 └────────────────────────┘ ``` #### 代码关键点 ```typescript // 点击标题进入编辑模式

{ setIsEditingLabel(true) setTempLabel(node.data?.label || node.data?.meta?.display_name) }}> {node.data?.label || node.data?.meta?.display_name}

// 编辑时显示输入框 {isEditingLabel && ( { if (e.key === 'Enter') { updateNodeData(node.id, { label: tempLabel }) setIsEditingLabel(false) } }} /> )} ``` --- ### 4. 节点数据保存 ⭐⭐ #### 功能描述 属性面板新增 "💾 保存" 按钮,可将节点配置保存到服务器。 #### 技术实现 - **组件**: [web/src/components/Inspector.tsx](../web/src/components/Inspector.tsx) - **API**: `POST /api/nodes/save` - **数据**: 发送 `nodeId` 和 `nodeData` #### UI 位置 ``` ┌─────────────────────────┐ │ 数据预览 │ ├─────────────────────────┤ │ [▶ 运行预览] [💾] │ ← 新增保存按钮 └─────────────────────────┘ ``` #### 请求示例 ```typescript await fetch('/api/nodes/save', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ nodeId: node.id, nodeData: node.data }) }) ``` #### 应用场景 - 保存常用节点配置模板 - 协作编辑中的配置同步 - 节点配置版本控制 --- ### 5. 拖拽上传文件 ⭐⭐⭐ #### 功能描述 从 Windows 文件管理器直接拖拽文件到应用的文件浏览器,自动触发上传。 #### 技术实现 - **组件**: [web/src/components/FileExplorer.tsx](../web/src/components/FileExplorer.tsx) - **事件**: `onDrop`, `onDragOver` - **API**: `POST /api/files/upload` #### 实现细节 ```typescript const handleDrop = async (e: React.DragEvent) => { e.preventDefault() const files = e.dataTransfer.files // 批量上传拖入的文件 for (let i = 0; i < files.length; i++) { await uploadFile(files[i], currentPath, currentUser) } loadFiles() // 刷新文件列表 alert(`✅ 已上传 ${files.length} 个文件`) } ``` #### 使用方式 1. 打开 Windows 文件管理器 2. 选择要上传的文件 3. 拖拽到应用的文件浏览器区域 4. 文件自动上传并显示 #### 支持特性 - ✅ 单文件拖拽 - ✅ 多文件批量拖拽 - ✅ 自动刷新文件列表 - ✅ 上传进度提示 --- ### 6. 拖拽下载文件 ⭐⭐ #### 功能描述 从应用的文件浏览器拖拽文件到 Windows 文件管理器,触发下载。 #### 技术实现 - **组件**: [web/src/components/FileExplorer.tsx](../web/src/components/FileExplorer.tsx) - **事件**: `onDragStart` - **机制**: 使用 `DownloadURL` 数据类型 #### 代码关键点 ```typescript const handleFileDragStart = (e: React.DragEvent, file: FileInfo) => { if (file.type === 'folder') return // 文件夹不支持拖拽下载 const downloadUrl = getDownloadUrl(file.path) e.dataTransfer.setData( 'DownloadURL', `application/octet-stream:${file.name}:${window.location.origin}${downloadUrl}` ) e.dataTransfer.effectAllowed = 'copy' } ``` #### 使用方式 1. 在应用文件浏览器中找到目标文件 2. 按住鼠标左键拖拽文件 3. 拖到 Windows 文件管理器或桌面 4. 文件自动下载到目标位置 #### 限制说明 - ⚠️ **仅支持文件**,文件夹不支持拖拽下载 - ⚠️ **浏览器兼容性**:Chrome, Edge 完全支持;Firefox 部分支持 --- ### 7. 拖拽导入工作流 ⭐⭐⭐ #### 功能描述 从文件浏览器拖拽 `.utrace` 文件到画布,自动加载工作流。 #### 技术实现 - **组件**: [web/src/components/Workspace.tsx](../web/src/components/Workspace.tsx) - **检测**: 识别文件扩展名 `.utrace` - **操作**: 调用 `loadWorkflow()` 加载 #### 代码逻辑 ```typescript const onDrop = useCallback((event: React.DragEvent) => { const filePath = event.dataTransfer.getData('application/x-file-path') if (filePath.endsWith('.utrace')) { // 拖入工作流文件 - 加载工作流 const loadWorkflow = useStore.getState().loadWorkflow loadWorkflow(filePath) .then(() => alert('✅ 已导入工作流')) .catch((error) => alert('❌ 导入失败')) } else if (filePath.endsWith('.csv')) { // 拖入CSV文件 - 创建节点 createCSVNode(filePath, position) } }, []) ``` #### 使用场景 ``` 场景 1: 快速加载工作流 ┌────────────────┐ ┌──────────────┐ │ 📁 文件浏览器 │ 拖拽→ │ 🖼️ 画布 │ │ └ 分析.utrace │ │ (加载工作流) │ └────────────────┘ └──────────────┘ 场景 2: 混合拖拽 - 拖拽 .utrace → 加载工作流 - 拖拽 .csv → 创建 CSV 节点 - 拖拽普通节点 → 添加到画布 ``` #### 交互优势 - ✅ 无需右键菜单,直接拖拽 - ✅ 统一的拖拽交互逻辑 - ✅ 支持多种文件类型识别 --- ## 🔧 技术细节 ### 拖拽数据传递机制 #### 1. 文件路径传递 ```typescript // 设置数据 e.dataTransfer.setData('application/x-file-path', file.path) // 读取数据 const filePath = e.dataTransfer.getData('application/x-file-path') ``` #### 2. 文件下载 ```typescript // 设置下载URL e.dataTransfer.setData( 'DownloadURL', `${mimeType}:${fileName}:${downloadUrl}` ) ``` #### 3. 原生文件上传 ```typescript // 读取拖入的文件 const files = e.dataTransfer.files for (let file of files) { await uploadFile(file, path, username) } ``` ### 状态管理优化 #### 节点标题状态 ```typescript // 局部状态管理 const [isEditingLabel, setIsEditingLabel] = useState(false) const [tempLabel, setTempLabel] = useState('') // 保存到全局状态 updateNodeData(nodeId, { label: newLabel }) ``` #### 用户列表状态 ```typescript // 默认值 + API更新 const [userList, setUserList] = useState(['guest', 'admin', 'dev', 'test']) // 组件挂载时更新 useEffect(() => { fetchUsers().then(users => setUserList(users)) }, []) ``` --- ## 📊 功能对比表 | 功能 | v0.2.1 | v0.2.2 | |------|--------|--------| | 用户列表 | ❌ 写死4个用户 | ✅ 动态从API获取 | | 工作流导入 | ✅ 双击加载 | ✅ 右键菜单 + 拖拽加载 | | 节点标题 | ❌ 只读 | ✅ 可点击编辑 | | 节点保存 | ❌ 无 | ✅ API持久化 | | 文件上传 | ✅ 点击上传按钮 | ✅ 拖拽 + 按钮 | | 文件下载 | ✅ 右键菜单 | ✅ 右键 + 拖拽 | | 拖拽到画布 | ✅ CSV文件 | ✅ CSV + 工作流 | --- ## 🎯 使用示例 ### 完整工作流:从文件到节点 #### 场景:分析销售数据 ``` 步骤 1: 上传数据文件 - 从Windows拖拽 sales_2026.csv 到文件浏览器 - ✅ 文件自动上传到 users/analyst/data/ 步骤 2: 创建分析节点 - 拖拽 sales_2026.csv 到画布 - ✅ 自动创建 CSV Loader 节点,路径已填充 步骤 3: 编辑节点标题 - 点击节点标题"CSV 数据加载器" - 输入"2026年销售数据",按 Enter - ✅ 节点标题已更新 步骤 4: 保存节点配置 - 点击属性面板的 💾 按钮 - ✅ 节点配置保存到服务器 步骤 5: 保存工作流 - 点击顶部的 💾 按钮 - ✅ 工作流保存为 .utrace 文件 步骤 6: 下次使用 - 拖拽 .utrace 文件到画布 - ✅ 完整工作流自动加载 ``` --- ## 🐛 已知问题 ### 1. 文件拖拽下载的浏览器兼容性 - **问题**: Firefox 浏览器不完全支持 `DownloadURL` - **影响**: 拖拽到桌面可能无法下载 - **解决方案**: 使用右键菜单的"下载"选项 ### 2. 节点保存API未实现 - **问题**: 后端 `POST /api/nodes/save` 接口暂未实现 - **影响**: 点击保存按钮会显示错误 - **临时方案**: 功能已就绪,等待后端实现 - **文档**: 参见 [BACKEND_API_REQUIREMENTS.md](BACKEND_API_REQUIREMENTS.md) ### 3. 用户列表API未实现 - **问题**: 后端 `GET /api/users/list` 接口暂未实现 - **影响**: 降级使用默认4个用户 - **临时方案**: 功能正常,但用户列表不完整 - **文档**: 参见 [BACKEND_API_REQUIREMENTS.md](BACKEND_API_REQUIREMENTS.md) --- ## 🔮 后续计划 ### 短期(v0.2.3) - [ ] 实现后端用户列表API - [ ] 实现后端节点保存API - [ ] 添加拖拽上传进度条 - [ ] 优化大文件拖拽性能 ### 中期(v0.3.0) - [ ] 节点模板系统 - [ ] 批量节点操作 - [ ] 工作流版本管理 - [ ] 用户协作功能 ### 长期(v0.4.0) - [ ] 在线预览大文件(CSV, JSON) - [ ] 文件搜索和过滤 - [ ] 云端同步 - [ ] 工作流市场 --- ## 📝 升级指南 ### 从 v0.2.1 升级到 v0.2.2 #### 前端升级 ```bash cd web git pull npm install # 如有新依赖 npm run dev ``` #### 后端准备 1. 阅读 [BACKEND_API_REQUIREMENTS.md](BACKEND_API_REQUIREMENTS.md) 2. 实现 `GET /api/users/list` 接口(推荐) 3. 实现 `POST /api/nodes/save` 接口(可选) #### 数据迁移 无需数据迁移,完全向后兼容。 --- ## 🙏 贡献者 - **前端开发**: GitHub Copilot - **API设计**: 开发团队 - **文档撰写**: AI Assistant - **测试**: 用户社区 --- ## 📧 反馈与支持 - **GitHub Issues**: [提交问题](https://github.com/your-repo/issues) - **功能请求**: [提交想法](https://github.com/your-repo/discussions) - **文档改进**: 欢迎提交 PR --- **版本**: v0.2.2 **发布日期**: 2026-01-07 **向后兼容**: ✅ 是 **需要数据库更新**: ❌ 否