flowable工作流引擎如何判断流程实例的所有任务是否运行完成
在Flowable工作流引擎中,判断流程实例的所有任务是否运行完成,主要可以通过查询流程实例的历史状态或者监听流程执行过程中的相关事件来实现。以下是几种具体的方法:
1. 查询历史流程实例状态
通过Flowable的HistoryService
,可以查询流程实例的历史信息,从而判断流程是否已经完成。流程实例完成通常意味着所有任务都已经成功执行完毕,并且没有未完成的任务或等待的边界事件。
实现步骤:
- 获取
HistoryService
实例。 - 使用
createHistoricProcessInstanceQuery()
方法创建历史流程实例查询。 - 通过
.processInstanceId(processInstanceId)
方法指定要查询的流程实例ID。 - 调用
.singleResult()
方法获取查询结果。 - 检查查询结果中的
endTime
属性或endActivityId
属性。如果endTime
不为空,或者endActivityId
指向了结束节点,则可以认为流程实例已经完成。
示例代码(假设processInstanceId
是已知的流程实例ID):
HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
if (historicProcessInstance != null && historicProcessInstance.getEndTime() != null) {
System.out.println("流程实例已结束");
} else {
System.out.println("流程实例未结束或不存在");
}
// 或者检查结束节点是否有数据
if (historicProcessInstance != null && historicProcessInstance.getEndActivityId() != null) {
System.out.println("流程实例已结束");
} else {
System.out.println("流程实例未结束或不存在");
}
public Map<String, Object> queryDetailProcess(String procInsId, String deployId) {
Map<String, Object> map = new HashMap<>();
if (StringUtils.isNotBlank(procInsId)) {
List<HistoricTaskInstance> taskInstanceList = historyService.createHistoricTaskInstanceQuery()
.processInstanceId(procInsId)
.orderByHistoricTaskInstanceStartTime().desc()
.list();
List<Comment> commentList = taskService.getProcessInstanceComments(procInsId);
List<WfTaskVo> taskVoList = new ArrayList<>(taskInstanceList.size());
taskInstanceList.forEach(taskInstance -> {
WfTaskVo taskVo = new WfTaskVo();
taskVo.setProcDefId(taskInstance.getProcessDefinitionId());
taskVo.setTaskId(taskInstance.getId());
taskVo.setTaskDefKey(taskInstance.getTaskDefinitionKey());
taskVo.setTaskName(taskInstance.getName());
taskVo.setCreateTime(taskInstance.getStartTime());
taskVo.setFinishTime(taskInstance.getEndTime());
if (StringUtils.isNotBlank(taskInstance.getAssignee())) {
Long userId = Long.parseLong(taskInstance.getAssignee());
String nickName = userService.selectNickNameById(userId);
taskVo.setAssigneeId(userId);
taskVo.setAssigneeName(nickName);
}
// 展示审批人员
List<HistoricIdentityLink> linksForTask = historyService.getHistoricIdentityLinksForTask(taskInstance.getId());
StringBuilder stringBuilder = new StringBuilder();
for (HistoricIdentityLink identityLink : linksForTask) {
if ("candidate".equals(identityLink.getType())) {
if (StringUtils.isNotBlank(identityLink.getUserId())) {
Long userId = Long.parseLong(identityLink.getUserId());
String nickName = userService.selectNickNameById(userId);
stringBuilder.append(nickName).append(",");
}
if (StringUtils.isNotBlank(identityLink.getGroupId())) {
if (identityLink.getGroupId().startsWith(TaskConstants.ROLE_GROUP_PREFIX)) {
Long roleId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.ROLE_GROUP_PREFIX));
SysRole role = roleService.selectRoleById(roleId);
stringBuilder.append(role.getRoleName()).append(",");
} else if (identityLink.getGroupId().startsWith(TaskConstants.DEPT_GROUP_PREFIX)) {
Long deptId = Long.parseLong(StringUtils.stripStart(identityLink.getGroupId(), TaskConstants.DEPT_GROUP_PREFIX));
SysDept dept = deptService.selectDeptById(deptId);
stringBuilder.append(dept.getDeptName()).append(",");
}
}
}
}
if (StringUtils.isNotBlank(stringBuilder)) {
taskVo.setCandidate(stringBuilder.substring(0, stringBuilder.length() - 1));
}
if (ObjectUtil.isNotNull(taskInstance.getDurationInMillis())) {
taskVo.setDuration(DateUtil.formatBetween(taskInstance.getDurationInMillis(), BetweenFormatter.Level.SECOND));
}
// 获取意见评论内容
if (CollUtil.isNotEmpty(commentList)) {
List<Comment> comments = new ArrayList<>();
// commentList.stream().filter(comment -> taskInstance.getId().equals(comment.getTaskId())).collect(Collectors.toList());
for (Comment comment : commentList) {
if (comment.getTaskId().equals(taskInstance.getId())) {
comments.add(comment);
// taskVo.setComment(WfCommentDto.builder().type(comment.getType()).comment(comment.getFullMessage()).build());
}
}
taskVo.setCommentList(comments);
}
taskVoList.add(taskVo);
});
map.put("flowList", taskVoList);
// // 查询当前任务是否完成
// List<Task> taskList = taskService.createTaskQuery().processInstanceId(procInsId).list();
// if (CollectionUtils.isNotEmpty(taskList)) {
// map.put("finished", true);
// } else {
// map.put("finished", false);
// }
}
// 第一次申请获取初始化表单
if (StringUtils.isNotBlank(deployId)) {
WfFormVo formVo = deployFormService.selectDeployFormByDeployId(deployId);
if (Objects.isNull(formVo)) {
throw new ServiceException("请先配置流程表单");
}
map.put("formData", JsonUtils.parseObject(formVo.getContent(), Map.class));
}
return map;
}
2. 监听流程执行事件
Flowable引擎在流程执行过程中会触发一系列事件,如任务创建、任务完成、流程实例开始、流程实例完成等。通过监听这些事件,可以在流程实例完成时得到通知。
实现步骤:
- 了解Flowable中的事件类型,特别是与流程实例和任务完成相关的事件,如
PROCESS_COMPLETED
、ACTIVITY_COMPLETED
等。 - 注册事件监听器,在监听器中实现自定义逻辑以响应特定事件。
- 当
PROCESS_COMPLETED
事件被触发时,表明流程实例已经成功完成。
注意:PROCESS_COMPLETED
事件是流程实例级别的,它会在整个流程实例完成时被触发,而不仅仅是某个任务。如果你需要更细粒度的控制,比如监听特定任务的完成,可以监听ACTIVITY_COMPLETED
事件,但这需要你自己在逻辑中判断所有任务是否都已完成。
3. 注意事项
- 在实际应用中,可能需要根据具体的业务逻辑来判断流程是否完成。例如,某些流程可能包含可选的任务或循环的任务,这些都需要在判断逻辑中考虑进去。
- Flowable的版本更新可能会带来API的变更或新功能的增加,因此建议查阅最新的官方文档以获取最准确的信息。
综上所述,通过查询历史流程实例状态或监听流程执行事件,可以有效地判断Flowable工作流引擎中的流程实例是否已经完成。