基于Flowable、React与bpmn-js的企业级流程引擎系统构建
技术选型的考量与架构设计
在企业内部系统开发中,流程审批功能普遍存在,从基础报销到复杂项目评审,均依赖于工作流机制。传统OA系统虽能快速落地,但灵活性差,业务变更常需外部厂商支持,成本高且响应慢。为此,我们选择一套自研方案:以 Flowable 作为核心流程引擎,React 构建前端界面,搭配 bpmn-js 实现专业流程图可视化。
后端采用 Flowable,其为 Activiti 的活跃分支,具备轻量嵌入特性,与 Spring Boot 集成无缝。它提供标准 REST 接口,支持多数据源配置,表结构清晰(如 ACT_RE_PROCDEF 存储流程定义,ACT_RU_TASK 管理运行时任务),便于调试和扩展。相比 Camunda 等更重型框架,Flowable 在中小型项目中更具性价比。
前端基于 React,利用组件化思想将流程列表、任务看板、表单等模块解耦,提升可维护性。结合 Ant Design 及其 ProTable、ProForm 等高级组件,可快速搭建符合企业规范的 UI,减少样式开发负担。
流程图交互层由 bpmn-js 实现。该库遵循 BPMN 2.0 标准,是业界主流的图形建模工具。虽然学习曲线稍陡,但其开放的插件机制允许自定义工具栏、属性面板、节点样式甚至新增图形类型。尽管存在若干 React 封装版本,但直接集成原生 bpmn-js 能获得更高的控制自由度与性能表现。
整体架构呈现"三层分离":流程引擎负责逻辑执行,前端专注用户体验,可视化层独立处理图形交互。三者通过标准化的 REST API 协同工作,形成一个可扩展、易维护的企业级流程平台。
环境初始化与项目搭建
以下步骤可帮助你快速建立最小可运行原型。
后端:Spring Boot + Flowable 初始化
使用 IntelliJ IDEA 或 Spring Initializr 创建项目,添加以下依赖:
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.8.0</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.4</version>
</dependency>
在 application.yml 中配置数据库连接并禁用自动初始化:
spring:
datasource:
url: jdbc:mysql://localhost:3306/workflow_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
flowable:
async-executor-activate: false
database-schema-update: false
rest-api-enabled: false
启动应用后,若设置 database-schema-update: true,Flowable 将自动创建约 60 张核心表。建议首次启动后改为 false,避免后续误操作。检查数据库可见如下分类表结构:
ACT_RE_*:流程资源定义ACT_RU_*:运行时实例与任务ACT_HI_*:历史记录ACT_GE_*:通用元数据
前端:React + Vite 项目搭建
使用 Vite 快速初始化项目:
npm create vite@latest workflow-ui --template react
cd workflow-ui
npm install
npm install antd @ant-design/pro-components bpmn-js
在 main.jsx 中引入 Ant Design 全局样式:
import 'antd/dist/antd.css';
// ... 其他导入
运行 npm run dev 启动本地服务,确认前后端环境已就绪。
API 接口设计与通信实现
前后端分离的核心在于接口契约的清晰定义。典型接口可分为四类:
- 流程定义管理(发布、查询、删除)
- 流程实例启动与终止
- 任务分配、签收与完成
- 历史数据查询与统计
示例:流程模型管理接口控制器(部分代码)
@RestController
@RequestMapping("/api/process-model")
public class ProcessModelController {
@Autowired
private RepositoryService repositoryService;
@GetMapping("/list")
public ResponseEntity<List<ProcessDefinitionDto>> listDefinitions() {
List<ProcessDefinition> defs = repositoryService.createProcessDefinitionQuery()
.orderByProcessDefinitionKey().asc()
.list();
return ResponseEntity.ok(defs.stream()
.map(this::toDto)
.collect(Collectors.toList()));
}
@PostMapping("/deploy")
public ResponseEntity<String> deploy(@RequestBody DeployRequest request) {
Deployment deployment = repositoryService.createDeployment()
.name(request.getName())
.addInputStream(request.getFileName(), new ByteArrayInputStream(request.getContent()))
.deploy();
return ResponseEntity.ok(deployment.getId());
}
}
前端通过 Axios 调用上述接口,获取流程列表用于渲染流程图或任务池,并在用户操作时触发对应流程事件。
