package com.iailab.module.bpm.framework.flowable.core.listener; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.iailab.framework.common.util.number.NumberUtils; import com.iailab.module.bpm.enums.definition.BpmBoundaryEventType; import com.iailab.module.bpm.framework.flowable.core.enums.BpmnModelConstants; import com.iailab.module.bpm.framework.flowable.core.util.BpmnModelUtils; import com.iailab.module.bpm.service.definition.BpmModelService; import com.iailab.module.bpm.service.task.BpmTaskService; import com.google.common.collect.ImmutableSet; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.BoundaryEvent; import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.FlowElement; import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; import org.flowable.engine.delegate.event.AbstractFlowableEngineEventListener; import org.flowable.engine.delegate.event.FlowableActivityCancelledEvent; import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.job.api.Job; import org.flowable.task.api.Task; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.util.List; import java.util.Set; /** * 监听 {@link Task} 的开始与完成 * * @author jason */ @Component @Slf4j public class BpmTaskEventListener extends AbstractFlowableEngineEventListener { @Resource @Lazy // 延迟加载,避免循环依赖 private BpmModelService modelService; @Resource @Lazy // 解决循环依赖 private BpmTaskService taskService; public static final Set TASK_EVENTS = ImmutableSet.builder() .add(FlowableEngineEventType.TASK_CREATED) .add(FlowableEngineEventType.TASK_ASSIGNED) // .add(FlowableEngineEventType.TASK_COMPLETED) // 由于审批通过时,已经记录了 task 的 status 为通过,所以不需要监听了。 .add(FlowableEngineEventType.ACTIVITY_CANCELLED) .add(FlowableEngineEventType.TIMER_FIRED) // 监听审批超时 .build(); public BpmTaskEventListener() { super(TASK_EVENTS); } @Override protected void taskCreated(FlowableEngineEntityEvent event) { taskService.processTaskCreated((Task) event.getEntity()); } @Override protected void taskAssigned(FlowableEngineEntityEvent event) { taskService.processTaskAssigned((Task) event.getEntity()); } @Override protected void activityCancelled(FlowableActivityCancelledEvent event) { List activityList = taskService.getHistoricActivityListByExecutionId(event.getExecutionId()); if (CollUtil.isEmpty(activityList)) { log.error("[activityCancelled][使用 executionId({}) 查找不到对应的活动实例]", event.getExecutionId()); return; } // 遍历处理 activityList.forEach(activity -> { if (StrUtil.isEmpty(activity.getTaskId())) { return; } taskService.processTaskCanceled(activity.getTaskId()); }); } @Override @SuppressWarnings("PatternVariableCanBeUsed") protected void timerFired(FlowableEngineEntityEvent event) { // 1.1 只处理 BoundaryEvent 边界计时时间 String processDefinitionId = event.getProcessDefinitionId(); BpmnModel bpmnModel = modelService.getBpmnModelByDefinitionId(processDefinitionId); Job entity = (Job) event.getEntity(); FlowElement element = BpmnModelUtils.getFlowElementById(bpmnModel, entity.getElementId()); if (!(element instanceof BoundaryEvent)) { return; } // 1.2 判断是否为超时处理 BoundaryEvent boundaryEvent = (BoundaryEvent) element; String boundaryEventType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.BOUNDARY_EVENT_TYPE); BpmBoundaryEventType bpmTimerBoundaryEventType = BpmBoundaryEventType.typeOf(NumberUtils.parseInt(boundaryEventType)); if (ObjectUtil.notEqual(bpmTimerBoundaryEventType, BpmBoundaryEventType.USER_TASK_TIMEOUT)) { return; } // 2. 处理超时 String timeoutHandlerType = BpmnModelUtils.parseBoundaryEventExtensionElement(boundaryEvent, BpmnModelConstants.USER_TASK_TIMEOUT_HANDLER_TYPE); String taskKey = boundaryEvent.getAttachedToRefId(); taskService.processTaskTimeout(event.getProcessInstanceId(), taskKey, NumberUtils.parseInt(timeoutHandlerType)); } }