禅与计算机程序设计艺术Java 核心技术Java

Activiti7轻松预判下一用户节点

2022-11-08  本文已影响0人  pq217

前言

在Activiti使用过程中,有时候需要提前判断下一个用户节点,以获取其相关设置

事情麻烦点在如果出现分支需要结合变量去判断分支的具体走向,而且下一个节点可能是一个网关节点、服务节点等

难点

不可能直接走Activiti的complete方法,因为我们的诉求是预判,但这个方法里必然包含了判断分支走向的代码

于是就开始调试complete,返现关键代码:ConditionUtil.hasTrueCondition

public static boolean hasTrueCondition(SequenceFlow sequenceFlow, DelegateExecution execution)

其中SequenceFlow就是Activiti中的线 ,DelegateExecution继承了VariableScope,就是Activiti存放变量的抽象

经过分析,发现这个工具方法就是根据线的表达式结合变量判断条件是否成立

思路

解决了唯一的难点,思路就很清晰了

  1. 获取当前节点的外连线(包含一根多根情况)
  2. 使用当前变量,循环判断查找条件成立的线
  3. 如果这跟线连得是用户节点,直接返回,否则把这个节点当做当前节点,递归调用1

就这么简单,三步就完事

代码

实现代码也比较简单,短短几行即可

public UserTask nextUserTask(BpmnModel bpmnModel, FlowNode currentFlowNode, Map<String, Object> variables) {
    // 准备上下文,这一步少了会报错
    if (Context.getProcessEngineConfiguration()==null) {
        Context.setProcessEngineConfiguration(processEngineConfiguration);
    }
    // 设置变量
    ExecutionEntityImpl execution = new ExecutionEntityImpl();
    variables.forEach(execution::setTransientVariable);
    // 获取外连线
    List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows();
    // 循环外连线
    for (SequenceFlow outgoingFlow : outgoingFlows) {
        // 如果条件不成立,直接过滤
        if (!ConditionUtil.hasTrueCondition(outgoingFlow, execution)) {
            continue;
        }
        // 如果条件成立
        // 获取指向节点
        FlowNode target = (FlowNode) bpmnModel.getMainProcess().getFlowElement(outgoingFlow.getTargetRef());
        // 如果是用户节点直接返回
        if (target instanceof UserTask) {
            return (UserTask) target;
        } else {
            // 否则把该节点视为当前节点,递归
            return nextUserTask(bpmnModel, target, variables);
        }
    }
    return null;
}

一个预判下一用户节点的工具就写完了,测试一下基本好用~

为方便使用可以重载一下

/**
 * 预判下一用户节点
 * @param processDefinitionId 设计id
 * @param currentFlowNodeId   当前节点id
 * @param variables           变量
 * @return 没有返回null
 */
public UserTask nextUserTask(String processDefinitionId, String currentFlowNodeId, Map<String, Object> variables) {
    // 获取设计
    BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
    // 当前节点
    FlowNode currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentFlowNodeId);
    return nextUserTask(bpmnModel, currentFlowNode, variables);
}
上一篇下一篇

猜你喜欢

热点阅读