# Vue Flow 工作流设计器

基于 **Vue 3** + **TypeScript** + **@vue-flow/core** 构建的现代化工作流设计器，完全符合后端数据模型规范。

## 🎯 核心特性

### 1. 数据模型完全对齐
- ✅ 前后端类型定义100%一致（符合 `docs/04-数据模型设计.md`）
- ✅ 节点类型元数据驱动动态表单
- ✅ 字段映射自动生成 `${...}` 表达式
- ✅ 支持三种表达式命名空间：`nodes`, `workflow`, `env`

### 2. 智能字段映射
- 从上游节点的 `outputSchema` 自动构建字段树
- 最多展开3层（可配置）
- 点击选择字段，自动生成完整表达式
- 示例：`${nodes.n1.output.body.email}`

### 3. 动态表单生成
根据 `NodeTypeMetadata.fields` 自动渲染表单控件：
- `text` → Input
- `textarea` → TextArea
- `number` → InputNumber
- `select` → Select
- `boolean` → Switch
- `code` → CodeEditor (TextArea with monospace)
- `key_value` → KeyValue Editor

### 4. 表达式模式切换
- `supportsExpression=true` 的字段显示 🔧 按钮
- 点击切换：静态值 ↔ 表达式
- 表达式模式下使用单行输入（`${...}` 格式）

### 5. 撤销/重做
- 基于历史快照
- 最多保留50条记录
- 支持快捷键（Ctrl+Z / Ctrl+Shift+Z）

## 📂 目录结构

```
vue-flow-design/
├── components/
│   ├── NodePalette.vue          # 左侧节点面板（拖拽式）
│   ├── FieldMappingSelector.vue # 字段映射选择器（弹窗）
│   ├── NodeConfigPanel.vue      # 右侧配置面板（抽屉）
│   └── BaseNode.vue             # 通用节点组件
│
├── stores/
│   └── useWorkflowStore.ts      # Pinia Store（状态管理）
│
├── utils/
│   ├── fieldTree.ts             # 字段树构建工具
│   └── expression.ts            # 表达式解析/生成工具
│
├── mock/
│   ├── nodeTypes.ts             # Mock 节点类型数据
│   └── workflows.ts             # Mock 工作流数据
│
├── index.vue                    # 主组件入口
├── ARCHITECTURE.md              # 架构设计文档
└── README.md                    # 本文档
```

## 🚀 快速开始

### 1. 启动开发服务器

```bash
cd apps/web-antd
pnpm dev
```

访问：`http://localhost:5173/workflow/vue-flow-design`

### 2. 基本操作

#### 添加节点
1. 从左侧节点面板拖拽节点类型到画布
2. 节点自动生成唯一 ID（如 `n1`, `n2`）
3. 点击节点打开右侧配置面板

#### 连接节点
1. 从节点右侧连接点拖拽到目标节点左侧
2. 自动创建边（edge）
3. 可选：设置边的条件表达式

#### 配置节点
1. 点击节点打开配置面板
2. 填写字段（根据节点类型动态生成）
3. 使用字段选择器：
   - 点击 📋 图标
   - 选择上游节点
   - 选择字段路径
   - 自动生成表达式

#### 保存工作流
- 点击顶部工具栏"保存"按钮
- 生成符合 `WorkflowDefinition` 的 JSON
- 可导出到文件或提交到后端API

### 3. 示例工作流

加载示例：顶部工具栏 → 更多 → 加载示例

**示例场景：HTTP→审批→邮件**

```typescript
{
  id: 'wf_001',
  name: 'HTTP→审批→邮件',
  schemaVersion: '1.0',
  nodes: [
    {
      id: 'n1',
      type: 'http_request',
      name: 'Get User',
      config: {
        url: 'https://api.example.com/users/1',
        method: 'GET'
      }
    },
    {
      id: 'n2',
      type: 'approval',
      name: '审批',
      config: {
        assignee: '${workflow.input.approver}',
        title: '用户信息审批'
      }
    },
    {
      id: 'n3',
      type: 'send_mail',
      name: '通知',
      config: {
        to: '${nodes.n1.output.body.email}',
        subject: '审批已通过',
        content: 'Hello ${nodes.n1.output.body.name}'
      }
    }
  ],
  edges: [
    { source: 'n1', target: 'n2' },
    { 
      source: 'n2', 
      target: 'n3',
      condition: '${nodes.n2.output.approved} == true'
    }
  ]
}
```

## 🔧 高级用法

### 1. 自定义节点类型

在 `mock/nodeTypes.ts` 中添加：

```typescript
{
  id: 'my_custom_node',
  name: 'myCustomNode',
  displayName: 'My Custom Node',
  category: 'transform',
  icon: 'ThunderboltOutlined',
  description: '自定义节点说明',
  fields: [
    {
      name: 'input',
      label: 'Input',
      type: 'text',
      required: true,
      supportsFieldMapping: true,  // 显示字段选择器
      supportsExpression: true,    // 支持表达式
    }
  ],
  outputSchema: {
    type: 'object',
    properties: {
      result: { type: 'string', description: '处理结果' }
    }
  }
}
```

### 2. 表达式使用规范

#### 节点数据引用
```javascript
${nodes.n1.output.body.email}       // 引用节点n1的输出
${nodes.n2.output.statusCode}       // 引用HTTP状态码
```

#### 工作流数据引用
```javascript
${workflow.input.userId}            // 工作流输入参数
${workflow.variables.env}           // 工作流变量
```

#### 环境变量引用
```javascript
${env.API_KEY}                      // 环境变量
${env.DATABASE_URL}
```

### 3. 条件表达式

边的条件表达式示例：

```javascript
${nodes.n1.output.statusCode} == 200
${nodes.n2.output.approved} == true
${nodes.n3.output.count} > 0
```

### 4. 扩展字段类型

如需支持新的表单字段类型，在 `NodeConfigPanel.vue` 的 `renderFormItem` 方法中添加：

```typescript
case 'rich_text':
  return <RichTextEditor v-model:value={formData.value[field.name]} />
```

## 📊 数据流

```
┌─────────────────┐
│  NodeTypeMetadata  │  ← 后端 GET /api/node-types
│  (节点类型元数据)  │
└─────────┬─────────┘
          │
          ↓
┌─────────────────┐
│  NodePalette    │  → 用户拖拽节点到画布
│  (节点面板)     │
└─────────┬─────────┘
          │
          ↓
┌─────────────────┐
│  WorkflowStore  │  ← 状态管理（Pinia）
│  (工作流状态)   │
└─────────┬─────────┘
          │
          ↓
┌─────────────────┐
│  NodeConfigPanel│  → 用户配置节点
│  (配置面板)     │
└─────────┬─────────┘
          │
          ↓
┌─────────────────┐
│ FieldMappingSelector│ → 选择字段生成表达式
│ (字段选择器)    │
└─────────┬─────────┘
          │
          ↓
┌─────────────────┐
│WorkflowDefinition│ → 后端 POST /api/workflows
│  (工作流定义)   │
└─────────────────┘
```

## 🎨 样式定制

### 节点颜色

在 `BaseNode.vue` 中修改 `categoryColor` 计算属性：

```typescript
const colorMap: Record<string, string> = {
  api: '#1890ff',        // 蓝色
  database: '#52c41a',   // 绿色
  logic: '#faad14',      // 黄色
  notification: '#f5222d', // 红色
  transform: '#722ed1',  // 紫色
}
```

### 画布背景

在 `index.vue` 中修改 `<Background>` 组件：

```vue
<Background 
  pattern-color="#aaa" 
  :gap="16"
  variant="dots"  <!-- lines | dots | cross -->
/>
```

## 🐛 调试技巧

### 1. 查看工作流定义

点击工具栏"更多" → "预览定义"，查看生成的 JSON。

### 2. 控制台日志

Store 中所有关键操作都有日志输出：

```typescript
console.log('添加节点:', nodeId)
console.log('保存工作流:', definition)
```

### 3. Vue DevTools

安装 [Vue DevTools](https://devtools.vuejs.org/)，查看 Pinia Store 状态。

## 📝 后续开发建议

### 优先级 P0（必须）
- [ ] 连接后端真实 API（替换 Mock 数据）
- [ ] 表单验证（基于 `required` 字段）
- [ ] 错误提示优化

### 优先级 P1（重要）
- [ ] 键盘快捷键（Ctrl+S 保存、Ctrl+Z 撤销）
- [ ] 节点搜索/过滤
- [ ] 批量操作（多选节点、批量删除）
- [ ] 工作流版本管理

### 优先级 P2（优化）
- [ ] 代码编辑器增强（Monaco Editor）
- [ ] 性能优化（虚拟滚动、懒加载）
- [ ] 主题切换（深色模式）
- [ ] 国际化（i18n）

## 🤝 贡献指南

### 提交规范

```bash
feat: 新增字段映射选择器
fix: 修复节点拖拽位置偏移
refactor: 重构表达式解析逻辑
docs: 更新 README
```

### 开发流程

1. 创建功能分支：`git checkout -b feature/xxx`
2. 开发 + 测试
3. 提交代码：`git commit -m "feat: xxx"`
4. 推送分支：`git push origin feature/xxx`
5. 创建 Pull Request

## 📄 许可证

MIT License

---

**作者**: AI Assistant  
**更新时间**: 2025-10-13  
**版本**: 1.0.0  

