activiti6 获取下一节点(持续更新)
这种方式是通过当前节点与当前节点之后的节点中间的连接对象(SequenceFlow 类)中的outgoingFlows属性 (标识输出的对象) , 之后对输出的对象进行判断 , 判断其是否是排他网关 (ExclusiveGateway) , 如果是排他网关 , 再通过自己程序的逻辑处理来判断下一节点是哪一个节点。
每行代码后面都有注释。
代码
* 获取下一UserTask任务节点
* task 当前任务task对象
* data 表单数据 (主要为了排他网关分支节点做判断用, 例如:请假2天需要提交至项目经理, 请假5天需要提交至部门经理)
*/
public UserTask getNextUserTaskNode(Task task,Map data) {
FlowElement resultTask = null;//定义返回值
BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());//通过流程定义ID取到bomnModel对象
FlowElement flowElement = bpmnModel.getProcesses().get(0).getFlowElement(task.getTaskDefinitionKey());//直接使用当前task的定义key去查找模型中的节点(当前任务节点)
UserTask nowUserTask = (UserTask)flowElement;//获取当前UserTask
List<SequenceFlow> nowOutgoingFlows = nowUserTask.getOutgoingFlows();//当前任务流向节点(SequenceFlow: 连接两个节点之间的线)
if(ToolUtil.isNotEmpty(nowOutgoingFlows) && nowOutgoingFlows.size() == 1 ) {
//如果只流向一个节点
FlowElement nextFlowElement = nowOutgoingFlows.get(0).getTargetFlowElement();//下一节点
if(UserTask.class.isInstance(nextFlowElement)) {
//判断节点是否是UserTask
resultTask = nextFlowElement;
}else if(ExclusiveGateway.class.isInstance(nextFlowElement)){
//判断是否是排他网关
ExclusiveGateway exclusiveGateway = (ExclusiveGateway)nextFlowElement;
List<SequenceFlow> exclusiveOutgoingFlows = exclusiveGateway.getOutgoingFlows();//排他网关流向节点
if(ToolUtil.isNotEmpty(exclusiveOutgoingFlows) && exclusiveOutgoingFlows.size() == 1 && (UserTask.class.isInstance(exclusiveOutgoingFlows.get(0).getTargetFlowElement())|| EndEvent.class.isInstance(exclusiveOutgoingFlows.get(0).getTargetFlowElement()))) {
//如果排他网关只有一条线路信息并且是UserTask节点
resultTask = exclusiveOutgoingFlows.get(0).getTargetFlowElement();
}else if(exclusiveOutgoingFlows.size() > 1) {
//如果排他网关有多条线路信息
for (SequenceFlow sequenceFlow : exclusiveOutgoingFlows) {
//通过流转网关ID和线路ID 获取分支对象(BranchCondition 自己对条件判断的封装)
BranchCondition branchCondition = branchConditionService.getOne(new QueryWrapper<BranchCondition>().eq("BRANCH_ID", exclusiveGateway.getId()).eq("SEQUENCEFLOW_ID", sequenceFlow.getId()).eq("PROCDEF_ID", task.getProcessDefinitionId()));
if(ToolUtil.isEmpty(branchCondition) || ToolUtil.isEmpty(branchCondition.getExitCondition())) {
continue;
}
ElData elData = disposeExitCondition(branchCondition.getExitCondition(),data);//这个方法是我通过规则和数据,来判断是否符合转入节点的条件
if(isCondition(elData.getEl(),elData.getElValueData())) {
//判断跳转条件是否成立
resultTask = sequenceFlow.getTargetFlowElement();//条件成立 返回节点对象
}
}
}
}
}
return resultTask;
}
解析EL表达式方法 isCondition
/**
* 通过el表达式 与 data集合 判断是否符合条件
* @param el
* @param data
* @return
*/
public boolean isCondition(String el,Map<String,String> data) {
ExpressionFactory expressionFactory = new ExpressionFactoryImpl();
SimpleContext simpleContext = new SimpleContext();
for (String dataKey : data.keySet()) {
simpleContext.setVariable(dataKey, expressionFactory.createValueExpression(data.get(dataKey), String.class));
}
ValueExpression e = expressionFactory.createValueExpression(simpleContext, el, boolean.class);
return (Boolean) e.getValue(simpleContext);
}
获取下一节点的方法有很多,但核心就是对bpmnModel对象和flowElement节点对象的操作。
大家还有什么问题可以写在评论,我会及时回复。有什么好的想法也可以写在评论区