下面代码是该监听器是对每个到达结束事件后执行的。
原本的流程定义是如果其中任意某个节点进行了驳回,则直接结束流程。
所以在每个节点的驳回对应的排他网关都设置了EndEvent
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.FlowNode;
import org.flowable.common.engine.api.delegate.event.FlowableEvent;
import org.flowable.common.engine.api.delegate.event.FlowableEventListener;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.event.impl.FlowableEntityEventImpl;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @description 全局监听器,判断流程是不是运行到了最后一个EndEvent
* @since 2024/1/15
*/
@Slf4j
@Component
public class ProcessEndListener implements FlowableEventListener {
@Override
public void onEvent(FlowableEvent event) {
log.info("ProcessEndListener:{}", JSON.toJSONString(event.getType()));
TaskService taskService = SpringUtil.getBean(TaskService.class);
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
FlowableEntityEventImpl flowableEntityEvent = ((FlowableEntityEventImpl) event);
ProcessInstance pi = (ProcessInstance) flowableEntityEvent.getEntity();
List<Task> tasks = taskService.createTaskQuery().active().processInstanceId(pi.getId()).list();
Task t = tasks.get(0);
String bizKey = pi.getBusinessKey();
log.info("ProcessEndListener#bizKey:{}", bizKey);
String procDefId = pi.getProcessDefinitionId();
List<Execution> exes = runtimeService.createExecutionQuery().processInstanceId(pi.getProcessInstanceId()).processDefinitionId(procDefId).executionId(t.getExecutionId()).list();
String curActId = exes.get(0).getActivityId();//获得当前执行器的活动ID
BpmnModel bm = ProcessDefinitionUtil.getBpmnModel(t.getProcessDefinitionId());
FlowNode flowNode = (FlowNode) bm.getFlowElement(curActId);//获得当前节点
if (flowNode instanceof EndEvent) {//判断当前节点是否为结束事件
if (flowNode.getId().equals("end")) {//end是自定义的EndEvent节点的ID
//todo 通知回调
log.info("当前节点是结束节点:{}!!", JSON.toJSONString(flowNode));
}
}
}
@Override
public boolean isFailOnException() {
return false;
}
@Override
public boolean isFireOnTransactionLifecycleEvent() {
return false;
}
@Override
public String getOnTransaction() {
return null;
}
}
百度关于该问题答案出来的几乎清一色全是同一个答案,给了三种方法,但是每个方法的代码都有他自定义的部分,是不完整的东西。
下面是网上找的东西,里面的flowableService是这个比玩意自定义的。
下面这段代码是被转载多次的代码, 它监听的是指向结束事件的上一个节点。
也就是他的当前节点可能是最后一岗。
然后最后一岗—>EndEvent
@Component
public class ProcessEndListener implements FlowableEventListener {
@Autowired
FlowableService flowableService;
@Override
public void onEvent(FlowableEvent event) {
// 当前节点任务实体,
TaskEntity taskEntity = (TaskEntity) ((FlowableEntityEventImpl) event).getEntity();
String taskId = taskEntity.getId();
String curActId = flowableService.getNodeId(taskId);
String procDefId = ProcUtils.getProcessDefinitionByTaskId(taskEntity.getId()).getId();
Process process = ProcessDefinitionUtil.getProcess(procDefId);
//遍历整个process,找到endEventId是什么,与当前taskId作对比
List<FlowElement> flowElements = (List<FlowElement>) process.getFlowElements();
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof SequenceFlow) {
SequenceFlow flow = (SequenceFlow) flowElement;
FlowElement sourceFlowElement = flow.getSourceFlowElement();
FlowElement targetFlowElement = flow.getTargetFlowElement();
//如果当前边的下一个节点是endEvent,那么获取当前边
if(targetFlowElement instanceof EndEvent && sourceFlowElement.getId().equals(curActId))
{
System.out.println("下一个是结束节点!!");
}
}
}
}
@Override
public boolean isFailOnException() {
return false;
}
@Override
public boolean isFireOnTransactionLifecycleEvent() {
return false;
}
@Override
public String getOnTransaction() {
return null;
}
}
用我上面的代码实现示例这个b的代码
@Override
public void onEvent(FlowableEvent event) {
log.info("ProcessEndListener:{}", JSON.toJSONString(event.getType()));
TaskService taskService = SpringUtil.getBean(TaskService.class);
RuntimeService runtimeService = SpringUtil.getBean(RuntimeService.class);
FlowableEntityEventImpl flowableEntityEvent = ((FlowableEntityEventImpl) event);
ProcessInstance pi = (ProcessInstance) flowableEntityEvent.getEntity();
List<Task> tasks = taskService.createTaskQuery().active().processInstanceId(pi.getId()).list();
Task t = tasks.get(0);
String bizKey = pi.getBusinessKey();
log.info("ProcessEndListener#bizKey:{}", bizKey);
String procDefId = pi.getProcessDefinitionId();
List<Execution> exes = runtimeService.createExecutionQuery().processInstanceId(pi.getProcessInstanceId()).processDefinitionId(procDefId).executionId(t.getExecutionId()).list();
String curActId = exes.get(0).getActivityId();
BpmnModel bm = ProcessDefinitionUtil.getBpmnModel(t.getProcessDefinitionId());
FlowNode flowNode = (FlowNode) bm.getFlowElement(curActId);//如果当前节点是最后一岗
List<SequenceFlow> outFlows = flowNode.getOutgoingFlows(); //此处需要获取他的下一个节点是否为EndEvent
for (SequenceFlow sequenceFlow : outFlows) { //遍历outFlows
sequenceFlow.getTargetFlowElement();//用该flow节点与EndEvent进行对比判断,也就是当前节点的下一个节点和EndEvent判断是否一致,是则说明当前节点就是最后一岗,且它的下一个节点就是结束事件
}
}