# 工作流平台技术文档 **项目**: 基于 Flowable 的可视化工作流平台 **版本**: v1.0 **更新日期**: 2025-01-12 --- ## 📚 文档目录 ### 核心设计文档 | 文档 | 说明 | 关键内容 | |------|------|----------| | [01-架构总览](./01-架构总览.md) | 系统整体架构设计 | 技术选型、系统架构、MVP范围、开发计划 | | [02-后端技术设计](./02-后端技术设计.md) | 后端详细实现 | 节点注册、表达式引擎、BPMN转换、REST API | | [03-前端技术设计](./03-前端技术设计.md) | 前端详细实现 | ReactFlow画布、字段映射选择器、状态管理 | | [04-数据模型设计](./04-数据模型设计.md) | 数据库设计 | 业务表结构、Flowable表说明、索引优化 | | [05-开发规范](./05-开发规范.md) | 代码和协作规范 | 命名规范、Git工作流、测试要求 | --- ## 🎯 快速导航 ### 我想了解... **整体架构** - 👉 先看 [01-架构总览](./01-架构总览.md) - 了解技术选型、系统架构、核心数据流 **后端开发** - 👉 看 [02-后端技术设计](./02-后端技术设计.md) - 节点如何注册?表达式如何解析?JSON如何转BPMN? **前端开发** - 👉 看 [03-前端技术设计](./03-前端技术设计.md) - ReactFlow如何使用?字段映射选择器如何实现? **数据库设计** - 👉 看 [04-数据模型设计](./04-数据模型设计.md) - 有哪些表?为什么用JSONB?如何优化查询? **编码规范** - 👉 看 [05-开发规范](./05-开发规范.md) - 如何命名?如何提交代码?如何写测试? --- ## 🔑 核心设计要点 ### 1. 为什么选择 Flowable? ``` ✅ 开源版功能完整(不需要购买企业版) ✅ 内置审批能力(User Task) ✅ Spring Boot 集成简单 ✅ 国内资料多,社区活跃 ✅ 支持 BPMN 2.0 标准 vs Camunda: - Flowable 表单引擎更强 - Flowable 开源版更完整 - Camunda 性能略优但差距不大 vs Conductor: - Conductor 没有审批能力 - Conductor 更轻量但功能少 - 如果不需要审批,Conductor 是更好选择 ``` ### 2. 核心技术难点与解决方案 #### 难点1:前端如何知道上游节点输出了什么? **解决方案**:使用静态 `outputSchema`(JSON Schema) ```typescript // 每个节点类型定义输出结构 const httpRequestMetadata = { id: 'http_request', outputSchema: { type: 'object', properties: { statusCode: { type: 'number' }, body: { type: 'object' }, headers: { type: 'object' }, }, }, }; // 前端根据 schema 构建字段树 // 用户可以选择: nodes.httpRequest.output.body.email ``` **优点**: - ✅ 快速,不需要执行节点 - ✅ 类型安全 - ✅ 支持自动补全 **缺点**: - ⚠️ 如果实际输出与 schema 不符,运行时才会发现 #### 难点2:如何实现字段映射选择器? **核心组件**:`FieldMappingSelector.tsx` ```tsx // 1. 计算上游节点 const upstreamNodes = edges .filter(edge => edge.target === currentNode.id) .map(edge => nodes.find(n => n.id === edge.source)); // 2. 根据 outputSchema 构建字段树 const fieldTree = upstreamNodes.map(node => ({ title: node.data.name, children: buildFieldTree(nodeType.outputSchema.properties, `nodes.${node.id}.output`) })); // 3. 用户选择字段,生成表达式 // 用户选择: nodes.httpRequest.output.body.email // 生成表达式: ${nodes.httpRequest.output.body.email} ``` #### 难点3:表达式解析性能 **解决方案**: ```java // 1. 使用 JUEL 而不是完整的 JavaScript(性能更好) // 2. 表达式编译结果缓存 private final Map expressionCache = new ConcurrentHashMap<>(); // 3. 快速路径:无表达式直接返回 if (!expression.contains("${")) { return expression; } ``` **性能测试结果**: - JUEL: ~50000 QPS - GraalVM JS: ~2000 QPS - 结论:使用 JUEL,性能足够 #### 难点4:工作流定义格式 **决策**:用户层面使用 JSON,内部转换为 BPMN XML ``` 前端 (JSON) ←→ 后端转换层 ←→ Flowable (BPMN XML) 理由: ✅ JSON 对前端友好 ✅ JSON 易于版本控制 ✅ BPMN 是 Flowable 原生格式 ✅ 分层清晰,职责明确 ``` --- ## 📊 技术架构图 ### 整体架构 ``` ┌─────────────────────────────────────────┐ │ 前端 (React + ReactFlow) │ │ - 可视化编辑器 │ │ - 节点配置面板 │ │ - 字段映射选择器 ⭐⭐⭐ │ └──────────────┬──────────────────────────┘ │ REST API ┌──────────────▼──────────────────────────┐ │ Spring Boot 应用 │ │ ┌────────────────────────────────────┐ │ │ │ REST API 层 │ │ │ └────────────────────────────────────┘ │ │ ┌────────────────────────────────────┐ │ │ │ 业务逻辑层 │ │ │ │ - NodeTypeRegistry (节点注册) │ │ │ │ - ExpressionEngine (表达式解析)⭐ │ │ │ │ - WorkflowConverter (JSON→BPMN)⭐ │ │ │ └────────────────────────────────────┘ │ │ ┌────────────────────────────────────┐ │ │ │ Flowable Engine │ │ │ │ - 流程执行 │ │ │ │ - 任务管理 │ │ │ │ - 历史记录 │ │ │ └────────────────────────────────────┘ │ └──────────────┬──────────────────────────┘ │ ┌──────────────▼──────────────────────────┐ │ PostgreSQL │ │ - 业务表 (workflow_definitions等) │ │ - Flowable表 (ACT_*) │ └─────────────────────────────────────────┘ ``` ### 核心数据流:工作流执行 ``` 1. 用户点击"执行" ↓ 2. 前端调用 POST /api/workflows/{id}/execute ↓ 3. 后端初始化执行上下文: { "workflow": { "input": {...} }, "nodes": {}, // 节点输出将保存在这里 "env": {...} } ↓ 4. Flowable 启动流程实例 ↓ 5. 按拓扑顺序执行节点: a. ExpressionEngine 解析表达式 b. 调用节点实现类执行 c. 保存输出到 nodes.{nodeId}.output ↓ 6. 节点间数据通过表达式传递: ${nodes.node1.output.body.email} ↓ 7. 遇到 User Task(审批)时暂停 ↓ 8. 审批完成后继续执行 ↓ 9. 流程结束 ``` --- ## 🚀 MVP 功能清单(第一期) ### 必须有的功能 **1. 工作流编辑器** - [x] 从左侧拖拽节点到画布 - [x] 节点之间连线 - [x] 删除节点和连线 - [x] 保存工作流 **2. 节点配置面板** - [x] 动态表单(根据节点类型生成) - [x] 字段映射选择器(TreeSelect 展示上游节点输出)⭐⭐⭐ - [x] 表达式输入框 **3. 节点类型(5种)** - [x] HTTP Request - [x] Send Email - [x] Set Variable - [x] Condition (IF/ELSE) - [x] Approval (审批) **4. 工作流执行** - [x] 手动触发执行 - [x] 查看执行日志 - [x] 查看节点输入/输出 **5. 审批功能** - [x] 待审批任务列表 - [x] 审批表单 - [x] 批准/拒绝 ### 不做的功能(第二期) - ❌ 定时触发(Cron) - ❌ Webhook 触发 - ❌ 循环节点(forEach) - ❌ 并行执行 - ❌ 工作流版本管理 - ❌ 权限管理(只做基础认证) - ❌ 监控大盘 --- ## 📅 开发计划(12周) ### Phase 1: 技术验证(Week 1-2) - Flowable PoC - 表达式引擎验证 - ReactFlow 画布验证 - 环境搭建 ### Phase 2: 后端核心(Week 3-4) - 节点类型注册系统 - 表达式引擎 - JSON → BPMN 转换器 - HTTP Request + Set Variable 节点 ### Phase 3: 前端核心(Week 5-6) - ReactFlow 画布 - 节点配置面板 - **字段映射选择器**(最核心) ### Phase 4: 执行引擎(Week 7-8) - 工作流执行 - 日志记录 - 错误处理 ### Phase 5: 审批功能(Week 9-10) - User Task 集成 - 审批表单 - 任务列表 ### Phase 6: 测试上线(Week 11-12) - 集成测试 - 性能测试 - 部署上线 --- ## 🎓 学习资源 ### Flowable - 官方文档: https://flowable.com/open-source/docs/ - GitHub: https://github.com/flowable/flowable-engine - 中文教程: https://www.cnblogs.com/catcher1994/tag/Flowable/ ### ReactFlow - 官方文档: https://reactflow.dev/ - 示例: https://reactflow.dev/examples ### 表达式引擎 - JUEL 文档: https://juel.sourceforge.net/guide/index.html - GraalVM JS: https://www.graalvm.org/javascript/ --- ## ❓ 常见问题 ### Q1: 为什么不直接使用 N8N? **A**: N8N 是 Node.js 技术栈,我们需要 Java 技术栈。另外,我们需要: - 与现有 Java 系统集成 - 自定义审批流程 - 完全掌控数据和安全 ### Q2: Flowable 学习曲线陡峭吗? **A**: 有一定学习曲线,但我们做了封装: - 用户不需要懂 BPMN(我们用 JSON) - 开发者只需要了解基础概念 - 提供完整的文档和示例 ### Q3: 性能够吗? **A**: 经过验证: - 表达式解析: 50000+ QPS - Flowable: 1000+ TPS - 前端画布: 支持 100+ 节点不卡顿 ### Q4: 如何扩展新的节点类型? **A**: 非常简单: 1. 创建节点实现类(实现 `WorkflowNode` 接口) 2. 添加 `@Component` 注解 3. 定义元数据(字段、输出结构) 4. Spring 启动时自动注册 5. 前端自动显示 ```java @Component public class MyCustomNode implements WorkflowNode { @Override public NodeTypeMetadata getMetadata() { // 定义元数据 } @Override public NodeExecutionResult execute(NodeInput input, NodeExecutionContext context) { // 执行逻辑 } } ``` --- ## 📞 联系方式 - **技术负责人**: [您的名字] - **Email**: [您的邮箱] - **文档更新**: 如有问题或建议,请提 Issue --- **最后更新**: 2025-01-12 **文档版本**: v1.0