297 lines
6.5 KiB
Markdown
297 lines
6.5 KiB
Markdown
# 函数节点嵌套 - 快速开始指南
|
||
|
||
## 🎯 5分钟快速上手
|
||
|
||
### 第1步: 创建一个函数
|
||
|
||
1. 在画布上设计任何工作流(建议包含 InputNode 和 OutputNode)
|
||
2. 在画布**空白处右键** → 选择 **"保存为函数"**
|
||
3. 输入函数名(英文,如: `my_first_function`)
|
||
4. 输入显示名(中文,如: `我的第一个函数`)
|
||
5. 点击确认 ✅
|
||
|
||
**完成!函数已保存到 `cloud/custom_nodes/functions/` 目录**
|
||
|
||
---
|
||
|
||
### 第2步: 使用函数节点
|
||
|
||
1. 在 NodePalette(左侧)中找到刚创建的函数节点
|
||
2. 拖拽到新的或现有的工作流中
|
||
3. 连接输入/输出端口
|
||
4. **本步完成**
|
||
|
||
---
|
||
|
||
### 第3步: 进入函数编辑
|
||
|
||
1. **双击**函数节点
|
||
2. 画布自动显示函数内部的工作流
|
||
3. 顶部会出现面包屑导航: **主工作流 / my_first_function (L1)**
|
||
4. 可以编辑、删除或添加节点
|
||
|
||
**你现在在函数内部!** 🎉
|
||
|
||
---
|
||
|
||
### 第4步: 返回主工作流
|
||
|
||
**3种方式选一种**:
|
||
|
||
#### 方式A: 点击面包屑的"返回"按钮
|
||
```
|
||
[← 返回] 主工作流 / my_first_function (L1)
|
||
```
|
||
|
||
#### 方式B: 点击面包屑的"主工作流"链接
|
||
```
|
||
[← 返回] [主工作流] / my_first_function (L1)
|
||
↑ 点击这里
|
||
```
|
||
|
||
#### 方式C: 按Ctrl+Z返回(如果实现了快捷键)
|
||
- 需要自定义扩展
|
||
|
||
---
|
||
|
||
### ✅ 就这么简单!
|
||
|
||
你现在已经掌握了函数嵌套的基本用法。
|
||
|
||
---
|
||
|
||
## 🚀 高级用法: 多层嵌套
|
||
|
||
### 场景: 函数套函数
|
||
|
||
```
|
||
主工作流
|
||
├─ InputNode (x1)
|
||
├─ 函数节点 A
|
||
│ ├─ InputNode
|
||
│ ├─ 函数节点 B ← 可以在这里再嵌套!
|
||
│ │ ├─ InputNode
|
||
│ │ ├─ 处理逻辑
|
||
│ │ └─ OutputNode
|
||
│ └─ OutputNode
|
||
└─ OutputNode
|
||
```
|
||
|
||
### 操作步骤
|
||
|
||
1. 进入函数A(双击)
|
||
2. 在函数A内创建一个函数B节点(拖拽)
|
||
3. 双击函数B节点进入
|
||
4. 面包屑显示: **主工作流 / 函数A / 函数B (L2)**
|
||
5. 编辑完成后,使用面包屑返回或跳转
|
||
|
||
### 支持的最大层级
|
||
|
||
- 理论无限制 (取决于内存和性能)
|
||
- 建议不超过 **5层** 以保证良好的用户体验
|
||
|
||
---
|
||
|
||
## 📋 命名规范
|
||
|
||
### 函数名称 (function_name)
|
||
|
||
- ✅ 使用英文字母、数字、下划线
|
||
- ✅ 以字母或下划线开头
|
||
- ❌ 不能有空格、中文、特殊符号
|
||
|
||
**示例**:
|
||
```
|
||
good_names: ✅
|
||
- extract_data
|
||
- process_csv_v2
|
||
- _private_function
|
||
- Transform123
|
||
|
||
bad_names: ❌
|
||
- Extract Data (有空格)
|
||
- 提取数据 (中文)
|
||
- function-name (有横杠)
|
||
- 123function (数字开头)
|
||
```
|
||
|
||
### 显示名称 (display_name)
|
||
|
||
- 可以使用中文、英文、特殊符号
|
||
- 在 NodePalette 中显示
|
||
- 在面包屑导航中显示
|
||
|
||
**示例**:
|
||
```
|
||
✅ 提取数据
|
||
✅ Extract Data
|
||
✅ 数据 → 转换 v2.0
|
||
✅ [高级] 复杂处理
|
||
```
|
||
|
||
---
|
||
|
||
## 🔍 常见问题
|
||
|
||
### Q1: 双击函数节点没有反应
|
||
|
||
**检查清单**:
|
||
- [ ] 确认是函数节点(不是 InputNode/OutputNode)
|
||
- [ ] 打开浏览器控制台查看错误
|
||
- [ ] 确认后端服务运行: `curl http://127.0.0.1:8000/api/functions/list`
|
||
- [ ] 检查网络连接
|
||
|
||
**解决方案**:
|
||
```javascript
|
||
// 在浏览器控制台执行
|
||
fetch('http://127.0.0.1:8000/api/functions/list')
|
||
.then(r => r.json())
|
||
.then(d => console.log(d))
|
||
```
|
||
|
||
### Q2: 保存函数时提示"函数名称无效"
|
||
|
||
**原因**: 函数名称不符合命名规范
|
||
|
||
**正确做法**:
|
||
- ✅ 只用英文字母、数字、下划线
|
||
- ✅ 以字母或下划线开头
|
||
- ✅ 不含空格或特殊符号
|
||
|
||
**错误做法**:
|
||
- ❌ 中文名称
|
||
- ❌ 包含空格
|
||
- ❌ 包含横杠或其他符号
|
||
|
||
### Q3: 面包屑导航不显示
|
||
|
||
**原因**:
|
||
- 尚未进入任何函数 (functionStack 为空)
|
||
- 或者 BreadcrumbNav 组件被隐藏
|
||
|
||
**解决方案**:
|
||
1. 双击函数节点进入
|
||
2. 如果还是不显示,打开浏览器开发者工具的"元素检查器"
|
||
3. 搜索 "BreadcrumbNav" 或检查 z-index
|
||
|
||
### Q4: 返回上一层时工作流数据丢失
|
||
|
||
**原因**:
|
||
- 进入函数时未正确保存上一层级的状态
|
||
- 浏览器 localStorage 被清空
|
||
|
||
**解决方案**:
|
||
1. 重新加载页面(会从 localStorage 恢复)
|
||
2. 检查浏览器控制台是否有错误
|
||
3. 确认 Workspace 中的 useStore 调用正确
|
||
|
||
### Q5: 能否在函数内直接编辑,然后自动保存?
|
||
|
||
**当前行为**:
|
||
- 编辑自动保存到 localStorage
|
||
- 但**不会更新** 函数定义文件 (`.json`)
|
||
|
||
**计划改进** (Phase 3):
|
||
- 添加"保存函数"按钮
|
||
- 自动检测函数内部工作流的变化
|
||
- 版本控制和历史记录
|
||
|
||
### Q6: 支持撤销/重做吗?
|
||
|
||
**当前**:
|
||
- 基本的 undo/redo (由 zustand store 提供)
|
||
- 在函数内编辑支持历史记录
|
||
|
||
**改进方向**:
|
||
- 函数版本控制
|
||
- 编辑历史跟踪
|
||
- 比较功能
|
||
|
||
---
|
||
|
||
## 💡 最佳实践
|
||
|
||
### ✅ DO (推荐)
|
||
|
||
1. **按功能划分函数**
|
||
- 每个函数执行单一功能
|
||
- 使用清晰的命名
|
||
|
||
2. **编写输入/输出节点**
|
||
- 明确定义函数的输入参数
|
||
- 明确定义输出数据
|
||
- 便于重用
|
||
|
||
3. **测试函数**
|
||
- 创建函数后先测试单独使用
|
||
- 确认输入/输出正确
|
||
|
||
4. **文档函数**
|
||
- 使用 `display_name` 和 `description` 记录用途
|
||
- 后续搜索和使用更方便
|
||
|
||
5. **保持层级深度**
|
||
- 不超过 3-5 层为佳
|
||
- 过深导致难以理解和维护
|
||
|
||
### ❌ DON'T (避免)
|
||
|
||
1. ❌ 创建无用的函数
|
||
- 只有一个节点的函数
|
||
- 从未使用过的函数
|
||
|
||
2. ❌ 过度嵌套
|
||
- 函数A包含函数B包含函数C包含函数D...
|
||
- 难以理解数据流
|
||
|
||
3. ❌ 混淆输入/输出
|
||
- 函数没有清晰的 InputNode/OutputNode
|
||
- 导致数据流不清楚
|
||
|
||
4. ❌ 频繁更改已发布的函数
|
||
- 可能破坏依赖该函数的工作流
|
||
- 建议版本管理 (v1, v2, ...)
|
||
|
||
5. ❌ 循环依赖
|
||
- 函数A包含函数B,函数B包含函数A
|
||
- 导致无限递归
|
||
|
||
---
|
||
|
||
## 🎓 学习路径
|
||
|
||
### 初级 (这节课)
|
||
- [x] 创建函数
|
||
- [x] 使用函数节点
|
||
- [x] 进入/退出函数
|
||
- [x] 面包屑导航
|
||
|
||
### 中级 (下一步)
|
||
- [ ] 函数参数验证
|
||
- [ ] 错误处理
|
||
- [ ] 函数文档生成
|
||
- [ ] 多版本管理
|
||
|
||
### 高级 (进阶)
|
||
- [ ] 函数库管理
|
||
- [ ] 函数搜索和发现
|
||
- [ ] 函数分享和导入
|
||
- [ ] 性能优化
|
||
|
||
---
|
||
|
||
## 📞 需要帮助?
|
||
|
||
1. **查看完整文档**: [FUNCTION_NESTING_IMPLEMENTATION.md](FUNCTION_NESTING_IMPLEMENTATION.md)
|
||
2. **检查示例函数**: `cloud/custom_nodes/functions/example_function.json`
|
||
3. **浏览器控制台**: 按 F12 查看错误和日志
|
||
4. **后端日志**: 检查 `server.log`
|
||
|
||
---
|
||
|
||
**祝你使用愉快!** 🎉
|
||
|
||
---
|
||
|
||
*版本: v1.0.0 | 最后更新: 2024-01-15*
|