activiti拿取 当前任务的下一个节点

本文介绍如何在工作流引擎中确定当前任务完成后下一任务的审核人信息,包括从流程实例获取所需节点数据,判断节点类型及处理排他网关逻辑。

  在实际的工作流业务开发中, 当用户完成当前用户任务时, 需要指定下一个用户任务的审核人。此时我们需要获取下一个节点的一些信息, 来确定下一个用户任务的审核人有哪些。

      

      在实际工作流程中, 当前用户任务后的节点可能为用户任务, 也可能为网关。如果下一个节点为网关我们需要判断流程线路。

 

      

Java代码  收藏代码
  1. /** 
  2.      * 获取下一个用户任务用户组信息  
  3.      * @param String taskId     任务Id信息  
  4.      * @return  下一个用户任务用户组信息  
  5.      * @throws Exception 
  6.      */  
  7.     public Set<Expression> getNextTaskGroup(String taskId) throws Exception {  
  8.           
  9.         ProcessDefinitionEntity processDefinitionEntity = null;  
  10.           
  11.         String id = null;  
  12.           
  13.         TaskDefinition task = null;  
  14.           
  15.         //获取流程实例Id信息   
  16.         String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId();  
  17.           
  18.         //获取流程发布Id信息   
  19.         String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId();  
  20.           
  21.         processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)  
  22.                 .getDeployedProcessDefinition(definitionId);  
  23.           
  24.         ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();  
  25.           
  26.         //当前流程节点Id信息   
  27.         String activitiId = execution.getActivityId();    
  28.           
  29.         //获取流程所有节点信息   
  30.         List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();   
  31.           
  32.         //遍历所有节点信息   
  33.         for(ActivityImpl activityImpl : activitiList){      
  34.             id = activityImpl.getId();     
  35.               
  36.             // 找到当前节点信息  
  37.             if (activitiId.equals(id)) {  
  38.                   
  39.                 //获取下一个节点信息   
  40.                 task = nextTaskDefinition(activityImpl, activityImpl.getId(), null, processInstanceId);  
  41.   
  42.                 break;  
  43.             }  
  44.         }  
  45.           
  46.         return task.getCandidateGroupIdExpressions();  
  47.     }  
  48.       
  49.     /**  
  50.      * 下一个任务节点信息,  
  51.      *  
  52.      * 如果下一个节点为用户任务则直接返回,  
  53.      *  
  54.      * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值,  
  55.      * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务信息  
  56.      * @param ActivityImpl activityImpl     流程节点信息  
  57.      * @param String activityId             当前流程节点Id信息  
  58.      * @param String elString               排他网关顺序流线段判断条件, 例如排他网关顺序留线段判断条件为${money>1000}, 若满足流程启动时设置variables中的money>1000, 则流程流向该顺序流信息  
  59.      * @param String processInstanceId      流程实例Id信息  
  60.      * @return  
  61.      */    
  62.     private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){   
  63.               
  64.         PvmActivity ac = null;  
  65.           
  66.         Object s = null;  
  67.           
  68.         //如果遍历节点为用户任务并且节点不是当前节点信息   
  69.             if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){    
  70.                 //获取该节点下一个节点信息   
  71.                 TaskDefinition taskDefinition = ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();    
  72.                 return taskDefinition;    
  73.             }else{    
  74.                 //获取节点所有流向线路信息   
  75.                 List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();    
  76.                 List<PvmTransition> outTransitionsTemp = null;    
  77.                 for(PvmTransition tr : outTransitions){      
  78.                     ac = tr.getDestination(); //获取线路的终点节点      
  79.                     //如果流向线路为排他网关   
  80.                     if("exclusiveGateway".equals(ac.getProperty("type"))){    
  81.                         outTransitionsTemp = ac.getOutgoingTransitions();  
  82.                           
  83.                         //如果网关路线判断条件为空信息   
  84.                         if(StrUtils.isEmpty(elString)) {  
  85.                             //获取流程启动时设置的网关判断条件信息   
  86.                             elString = getGatewayCondition(ac.getId(), processInstanceId);  
  87.                         }  
  88.                           
  89.                         //如果排他网关只有一条线路信息   
  90.                         if(outTransitionsTemp.size() == 1){    
  91.                             return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get(0).getDestination(), activityId, elString, processInstanceId);    
  92.                         }else if(outTransitionsTemp.size() > 1){  //如果排他网关有多条线路信息   
  93.                             for(PvmTransition tr1 : outTransitionsTemp){    
  94.                                 s = tr1.getProperty("conditionText");  //获取排他网关线路判断条件信息   
  95.                                 //判断el表达式是否成立   
  96.                                 if(isCondition(ac.getId(), StrUtils.trim(s.toString()), elString)){    
  97.                                     return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString, processInstanceId);    
  98.                                 }    
  99.                             }    
  100.                         }    
  101.                     }else if("userTask".equals(ac.getProperty("type"))){    
  102.                         return ((UserTaskActivityBehavior)((ActivityImpl)ac).getActivityBehavior()).getTaskDefinition();    
  103.                     }else{    
  104.                     }    
  105.                 }     
  106.             return null;    
  107.         }    
  108.     }  
  109.       
  110.     /** 
  111.      * 查询流程启动时设置排他网关判断条件信息  
  112.      * @param String gatewayId          排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息  
  113.      * @param String processInstanceId  流程实例Id信息  
  114.      * @return 
  115.      */  
  116.     public String getGatewayCondition(String gatewayId, String processInstanceId) {  
  117.         Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();  
  118.         return runtimeService.getVariable(execution.getId(), gatewayId).toString();  
  119.     }  
  120.       
  121.     /** 
  122.      * 根据key和value判断el表达式是否通过信息  
  123.      * @param String key    el表达式key信息  
  124.      * @param String el     el表达式信息  
  125.      * @param String value  el表达式传入值信息  
  126.      * @return 
  127.      */  
  128.     public boolean isCondition(String key, String el, String value) {  
  129.         ExpressionFactory factory = new ExpressionFactoryImpl();    
  130.         SimpleContext context = new SimpleContext();    
  131.         context.setVariable(key, factory.createValueExpression(value, String.class));    
  132.         ValueExpression e = factory.createValueExpression(context, el, boolean.class);    
  133.         return (Boolean) e.getValue(context);  
  134.     }  
<think>好的,用户想了解如何在Activiti获取一个任务节点。首先,我需要回忆一下Activiti的工作流程机制。Activiti是基于BPMN 2.0规范的流程引擎,流程定义中的每个节点都有对应的XML描述。获取一个任务节点通常需要分析流程定义的结构,找到当前任务节点的后续节点。 首先,用户可能需要通过当前任务实例获取流程实例ID,然后通过RuntimeService或RepositoryService查询流程定义信息。流程定义中的节点信息可以通过BpmnModel来获取,里面包含了所有的流程元素。 接下来,要考虑不同类型的节点,比如用户任务、排他网关、并行网关等,处理方式可能不同。例如,排他网关需要根据条件判断后续流向,而并行网关可能会有多个分支。因此,需要遍历当前节点的流出连线(SequenceFlow),并根据条件评估确定下一个节点。 然后,用户可能需要具体的代码示例。比如,如何通过TaskService获取当前任务,再通过RepositoryService获取BpmnModel,然后找到当前节点的出口,判断下一个节点。这里需要处理条件表达式,尤其是排他网关的情况,可能需要使用ExpressionManager来解析条件。 还要注意,有些情况下下一个任务节点可能不止一个,比如并行网关后的多个用户任务,这时候需要返回所有可能的节点。此外,自定义扩展属性可能会影响节点行为,需要参考引用中的CustomBpmnJsonConverter相关内容,不过用户的问题主要集中在获取一个节点,可能暂时不需要处理自定义属性。 用户提供的引用中提到使用RuntimeService启动流程实例,这可能与获取一个节点无关,但引用[2]和[3]涉及任务节点属性和扩展,可能需要考虑节点的assignee或自定义属性,但核心还是流程结构的解析。 最后,需要验证代码示例的正确性,确保使用了正确的API,比如通过Execution获取当前活动ID,再查找BpmnModel中的元素。同时,处理条件表达式时要注意变量的作用域,可能需要从流程变量中获取数据来评估条件。 总结步骤:获取当前任务→流程实例→流程定义→Bpmn模型→当前活动节点→流出连线→评估条件→确定下一个节点。需要考虑各种网关的情况,并提供相应的处理逻辑。</think>在Activiti获取一个任务节点需要结合流程定义解析和运行时状态分析,以下是具体实现方法及示例代码: ### 一、基础方法实现步骤 1. **获取当前任务信息** ```java Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult(); String processInstanceId = currentTask.getProcessInstanceId(); ``` 2. **获取BPMN模型对象** ```java RepositoryService repositoryService = processEngine.getRepositoryService(); BpmnModel bpmnModel = repositoryService.getBpmnModel(currentTask.getProcessDefinitionId()); ``` 3. **定位当前流程节点** ```java Process process = bpmnModel.getMainProcess(); FlowNode currentFlowNode = (FlowNode) process.getFlowElement(currentTask.getTaskDefinitionKey()); ``` 4. **分析后续节点** ```java List<SequenceFlow> outgoingFlows = currentFlowNode.getOutgoingFlows(); List<FlowNode> nextNodes = new ArrayList<>(); for (SequenceFlow flow : outgoingFlows) { if (isConditionSatisfied(flow, runtimeService.getVariables(processInstanceId))) { nextNodes.add((FlowNode) process.getFlowElement(flow.getTargetRef())); } } ``` ### 二、完整示例代码 ```java public List<String> getNextTaskNodes(String taskId) { // 获取服务实例 TaskService taskService = processEngine.getTaskService(); RuntimeService runtimeService = processEngine.getRuntimeService(); RepositoryService repositoryService = processEngine.getRepositoryService(); // 获取当前任务 Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult(); BpmnModel bpmnModel = repositoryService.getBpmnModel(currentTask.getProcessDefinitionId()); // 获取当前节点 Process process = bpmnModel.getMainProcess(); FlowNode currentFlowNode = (FlowNode) process.getFlowElement(currentTask.getTaskDefinitionKey()); // 收集后续节点 List<String> nextTaskNodes = new ArrayList<>(); for (SequenceFlow flow : currentFlowNode.getOutgoingFlows()) { if (evaluateFlowCondition(flow, runtimeService.getVariables(currentTask.getProcessInstanceId()))) { FlowElement targetElement = process.getFlowElement(flow.getTargetRef()); if (targetElement instanceof UserTask) { nextTaskNodes.add(targetElement.getName()); } } } return nextTaskNodes; } private boolean evaluateFlowCondition(SequenceFlow flow, Map<String, Object> variables) { if (flow.getConditionExpression() == null) return true; Expression expression = processEngine.getProcessEngineConfiguration() .getExpressionManager() .createExpression(flow.getConditionExpression().getText()); return (Boolean) expression.getValue(variables); } ``` ### 三、特殊场景处理 1. **网关处理逻辑** - 排他网关:需评估条件表达式 - 并行网关:返回所有分支任务节点 - 包容网关:同时满足条件的路径 2. **多实例任务处理** ```java if (currentFlowNode instanceof UserTask) { MultiInstanceLoopCharacteristics multiInstance = ((UserTask) currentFlowNode).getLoopCharacteristics(); if (multiInstance != null && multiInstance.isSequential()) { // 处理多实例任务逻辑 } } ``` ### 四、注意事项 1. 需要处理异步任务时,建议结合`RuntimeService.getActiveActivityIds()`方法[^2] 2. 使用历史服务查询时可结合`HistoryService.createHistoricActivityInstanceQuery()` 3. 自定义扩展属性需通过`BpmnModel.getExtensions(elementId)`获取[^3]
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值