在Spring Boot框架中整合Flowable工作流引擎,可以通过以下代码实现通过流程实例ID获取持久化表单数据和检查流程实例审批状态的功能。代码分为Controller
层和Service
层,并引用Flowable核心API实现。
📋 一、Controller层实现
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/flow")
public class FlowController {
@Autowired
private FlowService flowService;
// 获取持久化表单数据
@GetMapping("/form-data/{processInstanceId}")
public ResponseEntity<Map<String, Object>> getFormData(
@PathVariable String processInstanceId) {
Map<String, Object> formData = flowService.getFormDataByProcessInstanceId(processInstanceId);
return ResponseEntity.ok(formData);
}
// 检查流程审批状态
@GetMapping("/status/{processInstanceId}")
public ResponseEntity<String> checkProcessStatus(
@PathVariable String processInstanceId) {
String status = flowService.checkProcessStatus(processInstanceId);
return ResponseEntity.ok(status);
}
}
⚙️ 二、Service层实现
import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricVariableInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class FlowService {
@Autowired
private HistoryService historyService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
/**
* 通过流程实例ID获取所有持久化表单数据
* @param processInstanceId 流程实例ID
* @return Map<字段名, 字段值>
*/
public Map<String, Object> getFormDataByProcessInstanceId(String processInstanceId) {
Map<String, Object> formData = new HashMap<>();
// 1. 从历史变量表获取表单数据
List<HistoricVariableInstance> variables = historyService
.createHistoricVariableInstanceQuery()
.processInstanceId(processInstanceId)
.list();
variables.forEach(var ->
formData.put(var.getVariableName(), var.getValue())
);
return formData;
}
/**
* 检查流程实例审批状态
* @param processInstanceId 流程实例ID
* @return 状态描述(进行中/已结束/被拒绝)
*/
public String checkProcessStatus(String processInstanceId) {
// 1. 检查是否存在运行时任务(未结束)
Task activeTask = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.active()
.singleResult();
if (activeTask != null) {
return "审批中(当前节点:" + activeTask.getName() + ")";
}
// 2. 检查历史流程状态
HistoricProcessInstance historicInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (historicInstance != null) {
// 根据业务变量判断审批结果
Boolean approved = (Boolean) runtimeService.getVariable(
historicInstance.getId(), "approved"
);
return approved ? "审批通过" : "审批被拒绝";
}
return "流程实例不存在";
}
}
🔧 三、关键实现说明
-
表单数据获取原理
- 表单数据以流程变量形式存储在
ACT_HI_VARINST
表,通过HistoryService
查询历史变量实例。 - 支持动态表单和外置表单,无需区分类型(数据统一转为流程变量)。
- 表单数据以流程变量形式存储在
-
审批状态判断逻辑
- 运行时状态:通过
TaskService
查询未完成任务,存在任务即表示审批中。 - 结束状态:通过
HistoricProcessInstance
获取结束时间,结合业务变量(如approved
)判断最终结果。
- 运行时状态:通过
-
业务集成建议
- 在提交表单时,建议将审批状态(如
approvalStatus
)同步到业务表,避免频繁查询Flowable:// 业务实体示例 public class TravelApplication { private String id; private String approvalStatus; // 状态值:1=待提交, 2=审批中, 3=通过, 4=拒绝 }
- 在提交表单时,建议将审批状态(如
📊 四、接口测试示例
-
获取表单数据
GET /flow/form-data/32567
响应结果:
{ "days": 3, "reason": "项目紧急加班", "startTime": "2025-08-10" }
-
检查审批状态
GET /flow/status/32567
响应结果:
- 若在审批中 →
"审批中(当前节点:部门经理审批)"
- 若已结束 →
"审批通过"
- 若在审批中 →
⚠️ 五、注意事项
-
性能优化
- 历史变量查询可能数据量大,建议添加分页参数(如
.listPage(0, 100)
)。 - 高频调用的状态检查接口可改用业务表状态字段(减少Flowable查询)。
- 历史变量查询可能数据量大,建议添加分页参数(如
-
异常处理
- 需捕获
FlowableObjectNotFoundException
,避免无效ID导致服务崩溃:try { runtimeService.getVariable(processInstanceId, "approved"); } catch (FlowableObjectNotFoundException e) { log.error("流程实例不存在: {}", processInstanceId); }
- 需捕获
-
状态扩展建议
- 复杂状态(如会签通过率)可通过监听器更新业务表:
// 会签通过率计算(参考) float rate = nrOfCompletedInstances / nrOfInstances; if (rate > 0.5) runtimeService.setVariable("isPassed", true);
- 复杂状态(如会签通过率)可通过监听器更新业务表:
以上代码基于Flowable 6.7.2 和 Spring Boot 3.x 实现