企业级应用开发中,工作流引擎是核心组件之一。Activiti作为轻量级的BPMN 2.0流程引擎,与Ruoyi这一基于Spring Boot的快速开发框架结合,能够为企业提供完整的流程管理解决方案。我在多个项目中实践过这种集成方案,发现它特别适合需要快速实现业务流程自动化的场景。
Ruoyi框架本身提供了完善的权限管理和代码生成功能,而Activiti则专注于流程定义、执行和监控。两者结合后,开发者可以专注于业务逻辑的实现,无需重复造轮子。这种组合尤其适合OA系统、ERP系统等需要复杂审批流的应用。
从技术架构来看,Ruoyi采用前后端分离设计,Activiti则提供REST API和Java API两种集成方式。我们选择的是Spring Boot Starter方式,这种集成方案最稳定,也最容易维护。在实际项目中,这种架构支撑过日均上万流程实例的运行,表现非常可靠。
在开始集成前,需要确保开发环境满足以下要求:
我推荐使用IntelliJ IDEA作为开发IDE,它的Spring Boot支持最好。数据库方面,除了MySQL,这套方案也支持Oracle、PostgreSQL等主流数据库,只需要调整对应的JDBC驱动即可。
首先从Ruoyi官方Git仓库克隆项目:
bash复制git clone https://gitee.com/y_project/RuoYi-Vue.git
建议使用3.5.0版本,这个版本与Activiti 6.0的兼容性最好。项目导入IDE后,先确保基础功能能正常运行。特别要注意application-druid.yml中的数据库配置,需要加上nullCatalogMeansCurrent=true参数,这是Activiti表结构初始化必需的。
在Ruoyi根目录下新建ruoyi-activiti模块,这个模块将包含所有Activiti相关的代码。我建议采用以下结构:
code复制ruoyi-activiti
├── src/main/java
│ └── com.ruoyi.activiti
│ ├── config # 配置类
│ ├── controller # 控制器
│ ├── modeler # 模型设计器相关
│ └── service # 服务层
└── src/main/resources
└── processes # 流程定义文件
在父pom.xml中定义Activiti版本属性:
xml复制<properties>
<activiti.version>6.0.0</activiti.version>
</properties>
ruoyi-activiti模块的pom.xml需要添加以下核心依赖:
xml复制<dependencies>
<!-- Activiti核心 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-rest-api</artifactId>
<version>${activiti.version}</version>
<exclusions>
<exclusion>
<artifactId>mybatis</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- 模型设计器依赖 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>6.0.0</version>
</dependency>
<!-- Ruoyi模块依赖 -->
<dependency>
<groupId>com.ruoyi</groupId>
<artifactId>ruoyi-framework</artifactId>
</dependency>
</dependencies>
在ruoyi-admin的application.yml中添加Activiti配置:
yaml复制activiti:
check-process-definitions: false
db-identity-used: false
history-level: audit
async-executor-activate: true
数据库连接字符串需要添加参数:
yaml复制url: jdbc:mysql://localhost:3306/ruoyi?useUnicode=true&characterEncoding=utf8&nullCatalogMeansCurrent=true
在前端项目中创建activiti模块,主要包含以下文件:
code复制src/views/activiti
├── definition # 流程定义管理
├── modeler # 模型设计器
└── task # 任务管理
对应的API请求封装在src/api/activiti目录下。我建议采用axios拦截器统一处理Activiti的REST API调用,这样可以实现统一的错误处理和权限校验。
Activiti Modeler的集成是关键难点。需要将以下资源文件复制到项目中:
在vue组件中通过window.open打开设计器:
javascript复制designModeler(modelId) {
const url = `${process.env.VUE_APP_BASE_API}/modeler.html?modelId=${modelId}`
window.open(url, '_blank')
}
使用Element UI实现流程定义列表页面,核心功能包括:
关键代码片段:
javascript复制<el-table :data="definitionList">
<el-table-column prop="name" label="流程名称"></el-table-column>
<el-table-column prop="version" label="版本"></el-table-column>
<el-table-column label="操作">
<template #default="scope">
<el-button @click="showDiagram(scope.row)">查看流程图</el-button>
</template>
</el-table-column>
</el-table>
如果启动时出现表不存在错误,检查以下几点:
设计器界面空白通常是由于:
部署流程时出错,可以检查:
通过实现ActivityBehavior接口,可以自定义节点逻辑:
java复制public class CustomUserTaskBehavior implements ActivityBehavior {
@Override
public void execute(DelegateExecution execution) {
// 自定义业务逻辑
System.out.println("处理用户任务: " + execution.getCurrentActivityId());
}
}
Ruoyi的表单生成器可以与Activiti完美结合。在流程定义中配置表单属性:
xml复制<userTask id="task1" name="审批任务">
<extensionElements>
<activiti:formProperty id="approveResult"
name="审批结果" type="enum" required="true"/>
</extensionElements>
</userTask>
对于高并发场景,建议:
在application.yml中添加配置:
yaml复制activiti:
async-executor-activate: true
async-executor-thread-pool-size: 10
在SecurityConfig中配置放行规则:
java复制@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/modeler/**").permitAll()
.antMatchers("/activiti-rest/**").authenticated();
}
将Activiti用户组与Ruoyi角色系统集成:
java复制@Override
public List<Group> findGroupsByUser(String userId) {
List<SysRole> roles = roleService.selectRolesByUserId(userId);
return roles.stream()
.map(role -> new GroupEntity(role.getRoleKey()))
.collect(Collectors.toList());
}
典型的三级审批流程实现:
流程定义关键节点:
xml复制<process id="leaveProcess" name="请假流程">
<startEvent id="start"/>
<userTask id="deptApprove" name="部门审批"/>
<userTask id="hrRecord" name="人事备案"/>
<endEvent id="end"/>
<sequenceFlow sourceRef="start" targetRef="deptApprove"/>
<sequenceFlow sourceRef="deptApprove" targetRef="hrRecord"/>
<sequenceFlow sourceRef="hrRecord" targetRef="end"/>
</process>
带条件分支的复杂流程:
对应的网关配置:
xml复制<exclusiveGateway id="decisionGateway"/>
<sequenceFlow sourceRef="decisionGateway" targetRef="directorApprove">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${amount < 5000}]]>
</conditionExpression>
</sequenceFlow>
使用Activiti的REST API获取运行时数据:
javascript复制fetch('/activiti-rest/runtime/tasks')
.then(res => res.json())
.then(data => {
this.taskList = data.data
})
通过HistoryService获取流程历史:
java复制HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
List<HistoricProcessInstance> instances = query.finished().list();
集成Spring Boot Actuator监控端点:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics,activiti
经过多个项目的实践验证,我总结了以下经验:
对于流程变量,建议使用明确的命名规范:
java复制execution.setVariable("leave_startDate", startDate);
数据库表维护方面,重点关注ACT_RU_*运行时表和ACT_HI_*历史表。定期执行如下SQL优化:
sql复制OPTIMIZE TABLE ACT_HI_TASKINST, ACT_HI_PROCINST;