最近在做 Workforce Hub 的审批模块时,一个需求让我头疼了好几天——请假审批流程。
说白了就是一个"员工提交 → 主管审批 → 人事复核"的流程,听着挺简单的对吧?但架不住产品经理(也就是我自己)要求多:不同假期类型走不同审批链、三天以内免人事复核、超时自动提醒、驳回原因必填……
如果全用 if-else 硬编码状态机,写到后面我估计连自己都看不懂了。
后来硬着头皮引入了 Flowable,踩了不少坑,但也确实解决了问题。今天就来聊聊这个过程。
一、为什么需要工作流引擎?——几个 if-else 引发的惨案
其实一开始我没想用工作流引擎。请假审批嘛,不就是改个状态:
// 我一开始天真的想法
if (leave.getStatus() == PENDING) {
leave.setStatus(approved ? APPROVED : REJECTED);
leaveMapper.updateById(leave);
}
这代码跑了一周没问题。直到需求变成了这样:
- 年假:员工 → 主管 → 人事
- 事假:员工 → 主管
- 病假:员工 → 主管 → 人事(附诊断证明)
- 三天以内:跳过人事复核
- 主管超过 24 小时未审批 → 自动提醒
- 驳回后允许重新提交
血泪教训:当审批链开始分叉、节点开始有动态条件时,纯写 if-else 的代码复杂度是指数级增长的。更别提后续还要支持审批历史追溯、流程可视化这些需求。
这时候工作流引擎的价值就体现出来了——它把"流程怎么走"从业务代码里抽离出来,变成可配置的 BPMN 流程图。
二、为什么选 Flowable?——一个不太成熟的选择
市面上 Java 生态的工作流引擎主要有三个:Activiti、Flowable、Camunda。
为了做出选择,我对比了一下:
| 特性 | Activiti 7 | Flowable 6.x | Camunda 7 |
|---|---|---|---|
| Spring Boot 整合 | ✅ 原生 | ✅ 自动配置 | ✅ 社区支持 |
| BPMN 2.0 支持 | ✅ | ✅ 完整 | ✅ 完整 |
| 文档质量 | 一般 | 较好 | 较好 |
| 学习曲线 | 中等 | 中等 | 陡峭 |
| 决策表 (DMN) | ❌ | ✅ | ✅ |
| 中文社区 | 较少 | 有一些 | 更少 |
说实话,选 Flowable 很大程度上是因为它是 Activiti 原班人马出来做的——Activiti 5 的核心团队不满 Alfresco 的方向,出来另起炉灶。而且 Spring Boot 官方有 starter 支持,对咱们这种"能用就行"的学生项目来说最友好。
当然 Camunda 在企业级领域确实更强,但学习曲线太陡了。大三学生搞个课程项目,Flowable 够用了。
我的理解:Flowable 本质上就是把 BPMN 2.0(业务流程建模标注)这个标准规范用 Java 实现了一遍,然后包装成了 Spring Boot 能直接用的组件。
三、流程设计实例——请假审批的 BPMN 之旅
下面是我给 Workforce Hub 设计的请假审批流程:
(流程图)
整个流程分为三步:
第一步:AI 预审。这个比较特别——员工提交请假后,先不直接发给主管,而是过一个 AI 校验节点。比如检查剩余年假天数够不够、有没有重叠的请假记录、病假有没有附诊断证明。不符合规则的直接驳回并告诉原因,不用等主管手动发现。
这个设计思路来自我们项目的核心创新点——“Agent 深度嵌入业务链路”。AI 不只是聊天机器人,它实实在在地参与到了审批流程里。
第二步:部门主管审批。AI 校验通过后,流程到达主管节点。主管可以看到请假详情和 AI 预审结果,然后审批。
第三步:人事复核。如果请假天数超过 3 天,流程自动进入人事复核节点。不到 3 天的直接归档。
审批通过后,自动触发四个服务任务:考勤重算、余额扣减、站内通知、日历同步。
四、Flowable 与 Spring Boot 的整合——到底写了多少代码?
引入 Flowable 其实不复杂,加个依赖就行:
<!-- pom.xml -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.8.0</version>
</dependency>
启动 Spring Boot 后,Flowable 会自动创建 70+ 张表来管理流程定义、实例、任务、历史记录。小发现:这些表名都以 ACT_ 开头,跟 Activiti 一样的命名约定——毕竟同根同源。
核心代码其实就几个接口:
// 1. 启动一个请假流程
@PostMapping("/leave/submit")
public Result submitLeave(@RequestBody LeaveRequest req) {
// 构建流程变量
Map<String, Object> vars = new HashMap<>();
vars.put("leaveType", req.getLeaveType());
vars.put("leaveDays", req.getLeaveDays());
vars.put("applicantId", SecurityUtils.getCurrentUserId());
// 启动流程 - processDefinitionKey 对应 BPMN 文件的 process id
ProcessInstance pi = runtimeService
.startProcessInstanceByKey("leave-approval", vars);
return Result.ok(pi.getId());
}
// 2. 查询待办任务
@GetMapping("/tasks/todo")
public Result getTodoTasks() {
List<Task> tasks = taskService.createTaskQuery()
.taskAssignee(SecurityUtils.getCurrentUserId())
.list();
return Result.ok(tasks);
}
// 3. 审批任务
@PostMapping("/tasks/{taskId}/complete")
public Result completeTask(@PathVariable String taskId,
@RequestBody ApprovalDto dto) {
Map<String, Object> vars = new HashMap<>();
vars.put("approved", dto.isApproved());
vars.put("comment", dto.getComment());
taskService.complete(taskId, vars);
return Result.ok();
}
踩坑经历:一开始我直接用 taskService.complete() 就完了,没传流程变量——结果下个节点根本不知道这个任务是"通过"还是"驳回",网关判断直接报错。花了一个下午才明白流程变量是 BPMN 里网关判断的依据。
五、AI Agent 怎么嵌入工作流?——这个比较有意思
传统工作流引擎的节点是固定的——用户任务、服务任务、网关。但我们在 Flowable 的基础上做了一个扩展:自定义任务类型——AI 审核节点。
实现方式是在 BPMN 流程里定义一个 Service Task,通过 JavaDelegate 调用 AI Agent:
@Component("aiLeaveChecker")
public class AILeaveCheckerDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
// 获取流程变量
String applicantId = (String) execution.getVariable("applicantId");
int leaveDays = (int) execution.getVariable("leaveDays");
String leaveType = (String) execution.getVariable("leaveType");
// 调用 AI Agent 校验规则
AILeaveCheckResult result = aiAgentService.checkLeaveRules(
applicantId, leaveType, leaveDays);
// 将校验结果写入流程变量,供网关判断
execution.setVariable("aiCheckPassed", result.isPassed());
execution.setVariable("aiCheckReason", result.getReason());
}
}
然后在 BPMN 里这样引用:
<serviceTask id="aiCheck" name="AI预审"
flowable:delegateExpression="${aiLeaveChecker}"/>
网关会根据 aiCheckPassed 变量自动路由到"主管审批"或"驳回"分支——全程不需要写 if-else。
说实话,这个设计一开始我心里也没底——把 AI 的判断直接作为流程的路由依据,万一 AI 判断错了呢?后来加了一个兜底:AI 校验不通过的情况下,员工可以走"人工申诉"通道,绕过 AI 节点直接到主管。
六、流程可视化——调试利器
Flowable 自带了一个流程设计器和监控面板,开发阶段可以直接看到流程跑到哪了:
http://localhost:8080/flowable-ui
当然生产环境一般不会开这个面板。我们项目里自己画了一个轻量的流程跟踪页面,让用户能看到自己提交的请假当前在哪个环节、谁在审批、预计多久能完成。
总结
我的收获:
- 工作流引擎的核心价值是"流程与代码解耦"——不是让代码变少,而是让流程变可维护
- Flowable 学习曲线有,但不高——看懂 BPMN 2.0 的基本元素(开始/结束/任务/网关/连线)就够用了
- AI + 工作流是个有意思的组合——Agent 从"工具"变成了"流程参与者"
给初学者的建议:别一上来就想着画特别复杂的流程图。先从一个"开始 → 一人审批 → 结束"的极简流程开始,跑通了再加网关、加服务任务。
下一步:审批流程做完后,下一步就是把 AI 知识库接进来——员工在申请请假时可以直接 @AI 问"我还有几天年假",这个后面单独写一篇。
技术栈:Java 17 + Spring Boot 3.x + Flowable 6.8 + MyBatis-Plus + MySQL 8.4
环境信息:macOS + IntelliJ IDEA + Docker Compose(本机开发)
更新日期:2026年5月
默认评论
Halo系统提供的评论