在企业日常运营中,审批流程无处不在。想象一下这样的场景:员工提交请假申请后,需要经过直属主管、部门经理、人事部门三级审批。传统方式下,员工需要打印纸质申请表,逐个找领导签字,不仅效率低下,还容易出现申请表丢失、审批进度不透明等问题。
我曾经参与过一个客户项目,他们使用邮件+Excel的方式管理采购审批流程。经常出现审批人漏看邮件、审批意见混乱的情况,平均每个采购申请需要5-7天才能完成审批。引入工作流引擎后,审批时间缩短到1-2天,效率提升明显。
Activiti7作为轻量级工作流引擎,完美解决了这些问题。它提供:
我推荐使用以下环境配置,经过多个项目验证稳定性较好:
xml复制<!-- pom.xml关键依赖 -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Activiti7默认会创建28张表,主要分为以下几类:
在application.yml中添加配置:
yaml复制spring:
datasource:
url: jdbc:mysql://localhost:3306/activiti_db?useSSL=false
username: root
password: 123456
activiti:
database-schema-update: true # 自动更新表结构
history-level: full # 记录完整历史
Activiti Modeler是官方提供的Web版设计器,但集成过程有些"坑"需要注意:
activiti-webapp-explorer2中的静态资源:
editor-app目录modeler.html文件resources/static目录下设计器默认是英文界面,汉化需要三个步骤:
stencilset.json到static目录zh-CN.json语言包editor-app/app.js中的语言设置:javascript复制if("zh-CN" == navigator.language){
$translateProvider.preferredLanguage('zh-CN');
}else{
$translateProvider.preferredLanguage('en');
}
java复制@Controller
@RequestMapping("/model")
public class ModelController {
@Autowired
private RepositoryService repositoryService;
@GetMapping("/create")
public void createModel(HttpServletRequest request,
HttpServletResponse response) throws IOException {
Model model = repositoryService.newModel();
// 设置模型基本信息...
repositoryService.saveModel(model);
// 初始化模型JSON结构
ObjectNode editorNode = JsonNodeFactory.instance.objectNode();
// 构建默认元素...
// 重定向到设计器页面
response.sendRedirect(request.getContextPath() +
"/modeler.html?modelId=" + model.getId());
}
}
访问/model/create即可跳转到设计器界面,这里有个小技巧:可以在URL中添加&readOnly=true参数来限制编辑权限。
设计一个完整的请假流程需要以下元素:

Activiti支持三种分配方式:
xml复制<userTask id="leaderAudit" name="主管审批" activiti:assignee="zhangsan"/>
xml复制<userTask id="hrAudit" name="人事审批"
activiti:assignee="${applyUserId}"/>
java复制taskService.addCandidateUser(taskId, "lisi");
变量可以在流程中传递和使用:
java复制// 启动流程时设置变量
runtimeService.startProcessInstanceByKey(
"leaveProcess",
variables.put("days", 5)
);
// 审批时更新变量
taskService.complete(taskId,
variables.put("approval", true));
在网关条件中使用变量:
xml复制<sequenceFlow id="flow1" sourceRef="gateway" targetRef="managerAudit">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${days > 3}]]>
</conditionExpression>
</sequenceFlow>
设计好的模型需要部署才能运行:
java复制// 将模型转换为部署资源
Model model = repositoryService.getModel(modelId);
byte[] bpmnBytes = repositoryService.getModelEditorSource(modelId);
// 创建部署
Deployment deployment = repositoryService.createDeployment()
.name(model.getName())
.addBytes(model.getKey() + ".bpmn20.xml", bpmnBytes)
.deploy();
java复制// 根据流程定义Key启动
ProcessInstance instance = runtimeService
.startProcessInstanceByKey("leaveProcess");
// 查询待办任务
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee("zhangsan")
.list();
java复制// 普通通过
taskService.complete(taskId);
// 带审批意见
taskService.complete(taskId,
variables.put("comment", "同意"));
可能原因及解决:
stencilset.json路径检查要点:
排查步骤:
ACT_RU_TASK表中任务是否存在ACT_HI_TASKINST对于高并发场景:
yaml复制spring:
activiti:
async-executor-activate: true
sql复制DELETE FROM ACT_HI_TASKINST WHERE END_TIME_ < DATE_SUB(NOW(), INTERVAL 3 MONTH);
推荐做法:
java复制@Component
public class MyEventListener implements ExecutionListener {
@Override
public void notify(DelegateExecution execution) {
// 流程事件处理逻辑
}
}
除了官方Modeler,还可以考虑:
在最近的一个项目中,我们将Activiti7与Vue前端深度整合,实现了这样的效果:审批人直接在业务系统中完成任务审批,无需跳转到独立的工作流页面,用户体验大幅提升。关键是在后端封装了统一的REST API,前端通过WebSocket实时接收任务通知。