488 lines
13 KiB
Markdown
488 lines
13 KiB
Markdown
# 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' && (
|
||
<div onClick={() => {
|
||
loadWorkflow(contextMenu.file.path)
|
||
.then(() => alert(`✅ 已导入工作流`))
|
||
.catch((error) => alert(`❌ 导入失败`))
|
||
}}>
|
||
📂 导入工作流
|
||
</div>
|
||
)}
|
||
```
|
||
|
||
#### 使用流程
|
||
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
|
||
// 点击标题进入编辑模式
|
||
<h3 onClick={() => {
|
||
setIsEditingLabel(true)
|
||
setTempLabel(node.data?.label || node.data?.meta?.display_name)
|
||
}}>
|
||
{node.data?.label || node.data?.meta?.display_name}
|
||
</h3>
|
||
|
||
// 编辑时显示输入框
|
||
{isEditingLabel && (
|
||
<input
|
||
value={tempLabel}
|
||
onKeyDown={(e) => {
|
||
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
|
||
**向后兼容**: ✅ 是
|
||
**需要数据库更新**: ❌ 否
|