全局监听器可以对所有流程处理共同的业务时统一处理,如流程审批完成了要通知申请人,任务节点审批完成后通知下一节点审批人催促处理等。
@Configuration
@AllArgsConstructor
public class GlobalEventListenerConfig implements ApplicationListener<ContextRefreshedEvent> {
private final GlobalEventListener globalEventListener;
private final RuntimeService runtimeService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 流程创建、任务创建、任务完成、流程完成 基本上每个工作流方法都有对应的监听器
runtimeService.addEventListener(globalEventListener,
new FlowableEngineEventType[] {
FlowableEngineEventType.PROCESS_CREATED,
FlowableEngineEventType.TASK_CREATED,
FlowableEngineEventType.TASK_COMPLETED,
FlowableEngineEventType.PROCESS_COMPLETED});
}
}
@Test
void complete() {
Task task = taskService.createTaskQuery().processInstanceId("5005").singleResult();
// 参数传递到监听器中: 一般传待办列表需要保存的数据
Map<String, Object> variables = new HashMap<>();
variables.put("approveResut", "1");
variables.put("type", 1);
variables.put("comment", "同意");
variables.put("processNo", "P351573046235790");
variables.put("title", "xxx请假流程申请");
variables.put("assignee", "张三");
taskService.setVariables(task.getId(), variables);
taskService.complete(task.getId());
}
@Component
public class GlobalEventListener extends AbstractFlowableEngineEventListener {
@Autowired
private TaskService taskService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private RepositoryService repositoryService;
@Override
protected void processCompleted(FlowableEngineEntityEvent event) {
// 任务完成可以发送一封邮件通知流程申请人
super.processCompleted(event);
}
@Override
protected void taskCreated(FlowableEngineEntityEvent event) {
TaskEntity taskEntity = (TaskEntity)event.getEntity();
String taskId = taskEntity.getId();
String taskDefKey = taskEntity.getTaskDefinitionKey();
// 可以在执行taskService.complete(taskId)前通过设置局部变量setVariableLocal将参数从业务类中传递到监听器里面(建议用局部变量不建议使用全局变量)
// 常用来传参 审批结果、审批意见等字段
Map<String, Object> variables = taskEntity.getVariables();
String processDefinitionId = taskEntity.getProcessDefinitionId();
String executionId = taskEntity.getExecutionId();
String processInstanceId = taskEntity.getProcessInstanceId();
Execution execution = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
String parentId = execution.getParentId();
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
Process process = bpmnModel.getMainProcess();
String id = process.getId();
// 注意:这里taskDefKey如果在子流程里是拿不到值的
FlowElement flowElement = null;
FlowElementsContainer flowElementsContainer = process.getFlowElementsContainer(taskDefKey);
if (flowElementsContainer instanceof SubProcess) {
flowElement = flowElementsContainer.getFlowElement(taskDefKey);
} else {
flowElement = process.getFlowElement(taskDefKey);
}
// 节点信息描述:虽为信息描述,但可以看做是一个扩展字段,可以存一个json,即存一些配置信息
// 例如:可以存储当前节点是否允许撤回、是否允许退回等固定配置信息
String documentation = flowElement.getDocumentation();
if (flowElement instanceof UserTask) {
UserTask userTask = (UserTask)flowElement;
// 判断是否为会签节点
if (userTask.getBehavior() instanceof MultiInstanceActivityBehavior) {
// 会签节点
MultiInstanceActivityBehavior behavior = (MultiInstanceActivityBehavior)userTask.getBehavior();
// ${list}
String expressionText = behavior.getCollectionExpression().getExpressionText();
// item
String collectionElementVariable = behavior.getCollectionElementVariable();
// ${nrOfCompletedInstances/nrOfInstances > 0.5}
String completionCondition = behavior.getCompletionCondition();
System.out.println();
}
// 当前节点是否为会签节点
boolean isCounterSign = ((UserTask) flowElement).hasMultiInstanceLoopCharacteristics();
}
// 流程创建时调用
// 如果待办列表是查询自己的表而不是查工作流中的表可以在这里insert一条数据(wf_task_todo)
// 如果是会签节点,可以将每个会签任务单独开一张表来记录(wf_task_countersign)
// 甚至添加审批意见也可以封装到这里
// 这里的type可以对审批意见进行分类,比如,1:通过,2:不通过,3:撤回,4:退回,5:终止等
String type = Optional.ofNullable(variables.get("type")).orElse("1").toString();
String commment = Optional.ofNullable(variables.get("commment")).orElse("").toString();
String title = Optional.ofNullable(variables.get("title")).orElse("").toString();
String processNo = Optional.ofNullable(variables.get("processNo")).orElse("").toString();
taskService.addComment(taskId, processInstanceId, type, commment);
super.taskCreated(event);
}
@Override
protected void taskCompleted(FlowableEngineEntityEvent event) {
// 任务完成可以发送一封邮件给下一节点审批人,催促赶快审批
// 任务完成可以更新自己记录的待办表wf_task_todo中的办理状态(待办、已办)审批状态、审批意见、审批时间、
// 当前节点id,当前节点名称、上一条待办主键id等等
super.taskCompleted(event);
}
}
工作流中的节点上可以配置监听器,也可以通过代码添加全局监听器,注意:会先执行节点上的监听器再执行全局监听器。