Go to file
dengqichen ab88ff72f2 提交
2025-10-13 23:01:56 +08:00
.idea 提交 2025-10-13 14:04:05 +08:00
backend 提交 2025-10-13 23:01:56 +08:00
docs 提交 2025-10-13 14:04:05 +08:00
frontend 提交 2025-10-13 16:25:13 +08:00
.gitignore 提交 2025-10-13 16:25:13 +08:00
LICENSE 提交 2025-10-13 14:04:05 +08:00
PLUGIN_IMPLEMENTATION.md 提交 2025-10-13 23:01:56 +08:00
README.md 提交 2025-10-13 14:04:05 +08:00
WARP.md 提交 2025-10-13 14:04:05 +08:00

工作流平台技术文档

项目: 基于 Flowable 的可视化工作流平台
版本: v1.0
更新日期: 2025-01-12


📚 文档目录

核心设计文档

文档 说明 关键内容
01-架构总览 系统整体架构设计 技术选型、系统架构、MVP范围、开发计划
02-后端技术设计 后端详细实现 节点注册、表达式引擎、BPMN转换、REST API
03-前端技术设计 前端详细实现 ReactFlow画布、字段映射选择器、状态管理
04-数据模型设计 数据库设计 业务表结构、Flowable表说明、索引优化
05-开发规范 代码和协作规范 命名规范、Git工作流、测试要求

🎯 快速导航

我想了解...

整体架构

  • 👉 先看 01-架构总览
  • 了解技术选型、系统架构、核心数据流

后端开发

前端开发

数据库设计

编码规范

  • 👉05-开发规范
  • 如何命名?如何提交代码?如何写测试?

🔑 核心设计要点

1. 为什么选择 Flowable

✅ 开源版功能完整(不需要购买企业版)
✅ 内置审批能力User Task
✅ Spring Boot 集成简单
✅ 国内资料多,社区活跃
✅ 支持 BPMN 2.0 标准

vs Camunda:
- Flowable 表单引擎更强
- Flowable 开源版更完整
- Camunda 性能略优但差距不大

vs Conductor:
- Conductor 没有审批能力
- Conductor 更轻量但功能少
- 如果不需要审批Conductor 是更好选择

2. 核心技术难点与解决方案

难点1前端如何知道上游节点输出了什么

解决方案:使用静态 outputSchemaJSON Schema

// 每个节点类型定义输出结构
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

// 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表达式解析性能

解决方案

// 1. 使用 JUEL 而不是完整的 JavaScript性能更好
// 2. 表达式编译结果缓存
private final Map<String, ValueExpression> 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. 工作流编辑器

  • 从左侧拖拽节点到画布
  • 节点之间连线
  • 删除节点和连线
  • 保存工作流

2. 节点配置面板

  • 动态表单(根据节点类型生成)
  • 字段映射选择器TreeSelect 展示上游节点输出)
  • 表达式输入框

3. 节点类型5种

  • HTTP Request
  • Send Email
  • Set Variable
  • Condition (IF/ELSE)
  • Approval (审批)

4. 工作流执行

  • 手动触发执行
  • 查看执行日志
  • 查看节点输入/输出

5. 审批功能

  • 待审批任务列表
  • 审批表单
  • 批准/拒绝

不做的功能(第二期)

  • 定时触发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

ReactFlow

表达式引擎


常见问题

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. 前端自动显示
@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