`
CHEEN
  • 浏览: 135775 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

工作流引擎 Activiti 中获取下一节点

阅读更多
最近公司需要使用工作流引擎,选用了activiti。需求中提到的流程比较简单,也就3级审核,送审时需要选择下一节点的用户,所以必须在流程中需要获取当前节点的下一个节点。代码如下:
      
/**
	 * 根据实例编号查找下一个任务节点
	 * @param String procInstId :实例编号
	 * @return
	 */
	public TaskDefinition nextTaskDefinition(String procInstId){
		//流程标示
		String processDefinitionId = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInstId).singleResult().getProcessDefinitionId();
		
		ProcessDefinitionEntity def = (ProcessDefinitionEntity) ((RepositoryServiceImpl)repositoryService).getDeployedProcessDefinition(processDefinitionId);
		//执行实例
		ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(procInstId).singleResult();
		//当前实例的执行到哪个节点
		String activitiId = execution.getActivityId();
		//获得当前任务的所有节点
		List<ActivityImpl> activitiList = def.getActivities();
		String id = null;
		for(ActivityImpl activityImpl:activitiList){  
			id = activityImpl.getId(); 
			if(activitiId.equals(id)){
				System.out.println("当前任务:"+activityImpl.getProperty("name"));
				return nextTaskDefinition(activityImpl, activityImpl.getId(),"${iscorrect==1}");
//				System.out.println(taskDefinition.getCandidateGroupIdExpressions().toArray()[0]);
//				return taskDefinition;
			}
		}
		return null;
	}
	
	/**
	 * 下一个任务节点
	 * @param activityImpl
	 * @param activityId
	 * @param elString
	 * @return
	 */
	private TaskDefinition nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString){
			if("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())){
				TaskDefinition taskDefinition = ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition();
//				taskDefinition.getCandidateGroupIdExpressions().toArray();
				return taskDefinition;
			}else{
				List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
				List<PvmTransition> outTransitionsTemp = null;
				for(PvmTransition tr:outTransitions){  
					PvmActivity ac = tr.getDestination(); //获取线路的终点节点  
					if("exclusiveGateway".equals(ac.getProperty("type"))){
						outTransitionsTemp = ac.getOutgoingTransitions();
						if(outTransitionsTemp.size() == 1){
							return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get(0).getDestination(), activityId, elString);
						}else if(outTransitionsTemp.size() > 1){
							for(PvmTransition tr1 : outTransitionsTemp){
								Object s = tr1.getProperty("conditionText");
								if(elString.equals(StrUtils.trim(s.toString()))){
									return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString);
								}
							}
						}
					}else if("userTask".equals(ac.getProperty("type"))){
						return ((UserTaskActivityBehavior)((ActivityImpl)ac).getActivityBehavior()).getTaskDefinition();
					}else{
						logger.debug(ac.getProperty("type"));
					}
				} 
			return null;
		}
	}

思路是通过实例ID获取当前节点,然后查找当前节点后后面所有的活动,主要查找的活动是exclusiveGateway和userTask,如果exclusiveGateway中的条件符合${iscorrect==1}就直接查找exclusiveGateway后的活动,直到找到userTask为止。如果当前节点后的活动是userTask,说明这个userTask就是你想要的。


代码中${iscorrect==1}表达式是流程中定义,表示审核通过。当时对于在java中解析表达式遇到困难,所以使用字符串来比较,代码
if(elString.equals(StrUtils.trim(s.toString())))
就是用于判断表达式。后来发现可以通说juel来解析,以下是解析的代码:
ExpressionFactory factory = new ExpressionFactoryImpl();
		SimpleContext context = new SimpleContext();
		context.setVariable("count", factory.createValueExpression(10000, String.class));
		ValueExpression e = factory.createValueExpression(context, "${count>=1000}", boolean.class);
		System.out.println(e.getValue(context));
分享到:
评论
3 楼 sbwfgihc 2016-02-25  
like-echo 写道
查询下一步节点,更简单的实现方式。

/**
* 查询流程当前节点的下一步节点。用于流程提示时的提示。
* @param taskId
* @return
* @throws Exception
*/
public Map<String,  FlowNode> findNextTask(String taskId) throws Exception{
Map<String, org.activiti.bpmn.model.FlowNode> nodeMap = new HashMap<String, org.activiti.bpmn.model.FlowNode>();
ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);
//查询当前节点
HistoricTaskInstance histask = findHistricTaskById(taskId, processInstance.getProcessInstanceId());
//查询流程定义 。
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
List<org.activiti.bpmn.model.Process> listp = bpmnModel.getProcesses();
org.activiti.bpmn.model.Process process = listp.get(0);
//当前节点流定义
FlowNode sourceFlowElement = ( FlowNode) process.getFlowElement(histask.getTaskDefinitionKey());
// 找到当前任务的流程变量
List<HistoricVariableInstance> listVar=historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).list() ;
iteratorNextNodes(process, sourceFlowElement, nodeMap,listVar);
return nodeMap;
}


/**
* 查询流程当前节点的下一步节点。用于流程提示时的提示。
* @param process
* @param sourceFlowElement
* @param nodeMap
* @param listVar
* @throws Exception
*/
private void iteratorNextNodes(org.activiti.bpmn.model.Process process, FlowNode sourceFlowElement, Map<String,  FlowNode> nodeMap,List<HistoricVariableInstance> listVar)
throws Exception {
List<SequenceFlow> list = sourceFlowElement.getOutgoingFlows();
for (SequenceFlow sf : list) {
sourceFlowElement = ( FlowNode) process.getFlowElement( sf.getTargetRef());
if(StringUtils.isNotEmpty(sf.getConditionExpression() )){
    ExpressionFactory factory = new ExpressionFactoryImpl(); 
            SimpleContext context = new SimpleContext(); 
            for(HistoricVariableInstance var :listVar){
            context.setVariable(var.getVariableName(), factory.createValueExpression(var.getValue(), var.getValue().getClass()));
            }
            ValueExpression e = factory.createValueExpression(context, sf.getConditionExpression(), boolean.class); 
             if((Boolean)e.getValue(context)){
            nodeMap.put(sourceFlowElement.getId(), sourceFlowElement);
break;
             }
}
if (sourceFlowElement instanceof org.activiti.bpmn.model.UserTask) {
nodeMap.put(sourceFlowElement.getId(), sourceFlowElement);
break;
}else if (sourceFlowElement instanceof org.activiti.bpmn.model.ExclusiveGateway) {
iteratorNextNodes(process, sourceFlowElement, nodeMap,listVar);
}
}
}

  if((Boolean)e.getValue(context)){
            nodeMap.put(sourceFlowElement.getId(), sourceFlowElement);
上面e.getValue(context)这句话老是报错啊,
2 楼 like-echo 2015-03-16  
查询下一步节点,更简单的实现方式。

/**
* 查询流程当前节点的下一步节点。用于流程提示时的提示。
* @param taskId
* @return
* @throws Exception
*/
public Map<String,  FlowNode> findNextTask(String taskId) throws Exception{
Map<String, org.activiti.bpmn.model.FlowNode> nodeMap = new HashMap<String, org.activiti.bpmn.model.FlowNode>();
ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);
//查询当前节点
HistoricTaskInstance histask = findHistricTaskById(taskId, processInstance.getProcessInstanceId());
//查询流程定义 。
BpmnModel bpmnModel = repositoryService.getBpmnModel(processInstance.getProcessDefinitionId());
List<org.activiti.bpmn.model.Process> listp = bpmnModel.getProcesses();
org.activiti.bpmn.model.Process process = listp.get(0);
//当前节点流定义
FlowNode sourceFlowElement = ( FlowNode) process.getFlowElement(histask.getTaskDefinitionKey());
// 找到当前任务的流程变量
List<HistoricVariableInstance> listVar=historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).list() ;
iteratorNextNodes(process, sourceFlowElement, nodeMap,listVar);
return nodeMap;
}


/**
* 查询流程当前节点的下一步节点。用于流程提示时的提示。
* @param process
* @param sourceFlowElement
* @param nodeMap
* @param listVar
* @throws Exception
*/
private void iteratorNextNodes(org.activiti.bpmn.model.Process process, FlowNode sourceFlowElement, Map<String,  FlowNode> nodeMap,List<HistoricVariableInstance> listVar)
throws Exception {
List<SequenceFlow> list = sourceFlowElement.getOutgoingFlows();
for (SequenceFlow sf : list) {
sourceFlowElement = ( FlowNode) process.getFlowElement( sf.getTargetRef());
if(StringUtils.isNotEmpty(sf.getConditionExpression() )){
    ExpressionFactory factory = new ExpressionFactoryImpl(); 
            SimpleContext context = new SimpleContext(); 
            for(HistoricVariableInstance var :listVar){
            context.setVariable(var.getVariableName(), factory.createValueExpression(var.getValue(), var.getValue().getClass()));
            }
            ValueExpression e = factory.createValueExpression(context, sf.getConditionExpression(), boolean.class); 
             if((Boolean)e.getValue(context)){
            nodeMap.put(sourceFlowElement.getId(), sourceFlowElement);
break;
             }
}
if (sourceFlowElement instanceof org.activiti.bpmn.model.UserTask) {
nodeMap.put(sourceFlowElement.getId(), sourceFlowElement);
break;
}else if (sourceFlowElement instanceof org.activiti.bpmn.model.ExclusiveGateway) {
iteratorNextNodes(process, sourceFlowElement, nodeMap,listVar);
}
}
}
1 楼 philhong 2015-01-08  
很有用,谢谢

相关推荐

    ACTIVITI如何获取下一步节点

    在企业信息化建设中,流程引擎扮演着至关重要的角色,其中ACTIVITI是一个广泛应用的开源工作流引擎。本文将深入探讨如何在ACTIVITI中获取活动实例的下一步节点,以便于开发人员更好地理解和控制业务流程。 ACTIVITI...

    使用activiti工作流引擎显示流程图时高亮显示流程图中已执行节点和已执行路径方法源代码

    Activiti 是一个开源的工作流引擎,它基于 BPMN 2.0 标准,提供了一套完整的流程定义、执行和监控工具。本文将详细探讨如何在 Activiti 中实现流程图的高亮显示,特别是已执行的节点和已执行路径。 首先,理解 ...

    前后端分离项目中引入activiti工作流引擎步骤

    在这种模式下,引入工作流引擎如Activiti,可以为业务流程自动化提供强大的支持。Activiti是一款开源的工作流引擎,广泛应用于企业管理、审批流程等场景。下面我们将详细探讨在前后端分离项目中如何引入和配置...

    Activiti 学习笔记十:开始活动节点(判断流程是否结束及查询历史)

    Activiti 是一个开源的工作流引擎,它被广泛用于企业级应用中来管理业务流程。本学习笔记主要聚焦在开始活动节点以及如何判断流程是否结束,同时涵盖了查询历史流程实例的相关内容。 一、开始活动节点(Start Event...

    activiti5.22 实现撤回操作

    Activiti 是一个开源的工作流引擎,它提供了丰富的 API 和模型定义语言(BPMN 2.0)来设计、部署和执行业务流程。在 Activiti 5.22 版本中,我们可能需要在某些情况下撤销已经启动的流程实例,比如当发现某个任务...

    Activiti-5.4中实现会签

    在企业级应用中,流程管理是一个关键的环节,而Activiti是一个开源的工作流和业务流程管理系统,它提供了强大的流程建模、执行和监控能力。在 Activiti-5.4 版本中,会签(Concurrent Signatures)是流程设计中的一...

    activiti工作流流程跟踪图(图片(两种方式))

    Activiti是一款开源的工作流引擎,它为业务流程自动化提供了强大的支持。在开发和运维过程中,流程跟踪图是非常重要的工具,可以帮助我们理解流程的执行状态,定位问题,优化流程设计。本实例聚焦于如何生成和查看...

    工作流例子-activiti5

    Activiti 是一个开源的工作流引擎,它实现了业务流程模型与表示法(BPMN 2.0)标准,为开发者提供了一个强大而灵活的工具集来设计、运行和管理业务流程。 在“工作流例子-activiti5”中,我们将探讨如何使用 ...

    activiti工作流动态表单,外置表单,普通表单demo

    activiti三种表单的demo实现 运行方式: 1,修改连接的数据库 2,sql文件在resources\sql下 3,访问地址http://localhost:8080/activiti-demo/main/index

    Activiti5学习-在流程图中为带条件的顺序流添加提示信息

    在企业级应用开发中,流程自动化是一个至关重要的环节,而Activiti作为一个强大的工作流引擎,被广泛用于构建复杂的业务流程。本篇文章将聚焦于在Activiti5中如何为带条件的顺序流添加提示信息,以增强流程的可读性...

    activiti工作流流程跟踪图(网页布局)

    Activiti是一款开源的工作流引擎,它为业务流程自动化提供了强大的支持。在企业级应用中,Activiti被广泛用于实现复杂的业务流程管理。本实例聚焦于"activiti工作流流程跟踪图(网页布局)",旨在通过网页方式展示流程...

    activiti 工作流详细文档教程+eclipse安装activiti插件

    Activiti 是一个开源的工作流引擎,它被广泛用于企业级应用程序中来管理业务流程。这个教程包涵盖了如何使用Activiti工作流以及如何在Eclipse环境中安装Activiti Designer插件。 一、Activiti工作流简介 Activiti是...

    activiti工作流高亮图配置.zip

    Activiti是一款开源的工作流引擎,它为业务流程自动化提供了强大的支持。在开发过程中,流程图的高亮显示是非常重要的一个功能,它可以帮助开发者和业务人员更好地理解和跟踪流程的执行状态。下面将详细介绍如何配置...

    activiti流程图查看demo

    Activiti 是一个开源的工作流和业务自动化引擎,它支持企业级的业务流程管理(BPM)系统和模型驱动的应用程序。这个"activiti流程图查看demo"是一个示例项目,旨在帮助用户理解如何在Activiti中查看和操作流程图。在...

    Activiti工作流数据库表结构

    Activiti 是一个开源的工作流引擎,它用于自动化业务流程。在使用Activiti时,了解其数据库表结构至关重要,因为这些表存储了流程定义、运行时数据以及历史信息。以下是主要的Activiti数据库表及其功能的详细说明: ...

    Activiti6.0教程例子下载

    Activiti是一个开源的工作流引擎,它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度。 Activiti 作为一个遵从 Apache 许可的工作流和业务流程管理开源平台,其核心是基于 Java 的超快速、超...

    解决activiti生成的PNG乱码

    在IT行业中,Activiti是一款非常流行的开源工作流引擎,它被广泛用于企业的业务流程管理(BPM)系统中。在使用Activiti时,有时我们可能会遇到一个问题,即生成的PNG流程图出现乱码现象。这个问题涉及到图形渲染和...

    Activiti流程图部署及流程图部分操作.pdf

    Activiti 是一个开源的工作流和业务自动化引擎,它支持企业级的业务流程管理(BPM)和业务规则管理(BRM)。在这个主题中,我们主要关注如何在Activiti中进行流程图的部署以及如何操作流程图。 流程图的部署是...

Global site tag (gtag.js) - Google Analytics