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
就这么简单,三步就完事
代码
实现代码也比较简单,短短几行即可
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);
}