热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

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

      

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

 

      

Java代码  收藏代码
  1. /** 
  2.      * 获取下一个用户任务用户组信息  
  3.      * @param String taskId     任务Id信息  
  4.      * @return  下一个用户任务用户组信息  
  5.      * @throws Exception 
  6.      */  
  7.     public Set 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 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 outTransitions = activityImpl.getOutgoingTransitions();    
  76.                 List 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.     }  

推荐阅读
  • 本文详细探讨了JDBC(Java数据库连接)的内部机制,重点分析其作为服务提供者接口(SPI)框架的应用。通过类图和代码示例,展示了JDBC如何注册驱动程序、建立数据库连接以及执行SQL查询的过程。 ... [详细]
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 本文深入探讨了 Java 中的 Serializable 接口,解释了其实现机制、用途及注意事项,帮助开发者更好地理解和使用序列化功能。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • andr ... [详细]
  • 使用GDI的一些AIP函数我们可以轻易的绘制出简 ... [详细]
  • 本文详细介绍了 Java 中的 org.apache.hadoop.registry.client.impl.zk.ZKPathDumper 类,提供了丰富的代码示例和使用指南。通过这些示例,读者可以更好地理解如何在实际项目中利用 ZKPathDumper 类进行注册表树的转储操作。 ... [详细]
  • 采用IKE方式建立IPsec安全隧道
    一、【组网和实验环境】按如上的接口ip先作配置,再作ipsec的相关配置,配置文本见文章最后本文实验采用的交换机是H3C模拟器,下载地址如 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 扫描线三巨头 hdu1928hdu 1255  hdu 1542 [POJ 1151]
    学习链接:http:blog.csdn.netlwt36articledetails48908031学习扫描线主要学习的是一种扫描的思想,后期可以求解很 ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 在 Flutter 开发过程中,开发者经常会遇到 Widget 构造函数中的可选参数 Key。对于初学者来说,理解 Key 的作用和使用场景可能是一个挑战。本文将详细探讨 Key 的概念及其应用场景,并通过实例帮助你更好地掌握这一重要工具。 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 本文介绍了Android开发中Intent的基本概念及其在不同Activity之间的数据传递方式,详细展示了如何通过Intent实现Activity间的跳转和数据传输。 ... [详细]
author-avatar
mobiledu2502897083
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有