以前写过一篇文章activiti根据当前节点获取下一个节点信息,当时的需求只是需要获取下一个节点而已,并没有要求获得什么类型的节点,所以下一个节点可能是任何节点,在最近的项目中的需求是根据当前的节点获取下一个UseTask节点,为当前审批人选择下一个审批人提示,所以前面的文章所给出的信心就不能够实现当前功能。
所以本文所述为获取下一个任务节点。根据上一篇文章,可以获取到下一个节点的信息,如果我们获取到的节点是Exclusive Gateway,那么再根据这个节点再往下查询直到下一个节点是useTask为止,那么遇到GateWay就需要根据条件对流程进行判断,获取el表达式,再根据条件得到流程走的是哪一条线。
一、测试流程图:
流程图中最重要的是需要设置gateWay的Id值–这个Id值与gatway流出的flow的el表达式的key要对应(不然程序在执行中会出错)。
下面就是具体的执行程序:
/** * 获取下一个用户任务信息 * @param String taskId 任务Id信息 * @return 下一个用户任务用户组信息 * @throws Exception */ public TaskDefinition
getNextTaskInfo(String taskId)
throws Exception { ProcessDefinitionEntity processDefinitionEntity =
null; String id =
null; TaskDefinition task =
null; String processInstanceId = taskService.createTaskQuery().taskId(taskId).singleResult().getProcessInstanceId(); String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) .getDeployedProcessDefinition(definitionId); ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); String activitiId = execution.getActivityId(); List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();
for(ActivityImpl activityImpl : activitiList){ id = activityImpl.getId();
if (activitiId.equals(id)) {task = nextTaskDefinition(activityImpl, activityImpl.getId(),
null, processInstanceId);
break;}}
return task; }
/** * 下一个任务节点信息, * * 如果下一个节点为用户任务则直接返回, * * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值, * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务* @param ActivityImpl activityImpl 流程节点信息 * @param String activityId 当前流程节点Id信息 * @param String elString 排他网关顺序流线段判断条件* @param String processInstanceId 流程实例Id信息 * @return */ private TaskDefinition
nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){ PvmActivity ac =
null;Object s =
null;
if (
"userTask".equals(activityImpl.getProperty(
"type")) && !activityId.equals(activityImpl.getId())) {TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
return taskDefinition;}
else {List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();List<PvmTransition> outTransitionsTemp =
null;
for (PvmTransition tr : outTransitions) {ac = tr.getDestination();
if (
"exclusiveGateway".equals(ac.getProperty(
"type"))) {outTransitionsTemp = ac.getOutgoingTransitions();
if (StringUtils.isEmpty(elString)) {elString = getGatewayCondition(ac.getId(), processInstanceId);}
if (outTransitionsTemp.size() ==
1) {
return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(
0).getDestination(), activityId,elString, processInstanceId);}
else if (outTransitionsTemp.size() >
1) {
for (PvmTransition tr1 : outTransitionsTemp) {s = tr1.getProperty(
"conditionText");
if (isCondition(ac.getId(), StringUtils.trim(s.toString()), elString)) {
return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,processInstanceId);}}}}
else if (
"userTask".equals(ac.getProperty(
"type"))) {
return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();}
else {}}
return null;}}
/** * 查询流程启动时设置排他网关判断条件信息 * @param String gatewayId 排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息 * @param String processInstanceId 流程实例Id信息 * @return */ public String
getGatewayCondition(String gatewayId, String processInstanceId) { Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();Object object= runtimeService.getVariable(execution.getId(), gatewayId);
return object==
null?
"":object.toString(); }
/** * 根据key和value判断el表达式是否通过信息 * @param String key el表达式key信息 * @param String el el表达式信息 * @param String value el表达式传入值信息 * @return */ public boolean isCondition(String key, String el, String value) { ExpressionFactory factory =
new ExpressionFactoryImpl(); SimpleContext context =
new SimpleContext(); context.setVariable(key, factory.createValueExpression(value, String.class)); ValueExpression e = factory.createValueExpression(context, el,
boolean.class);
return (Boolean) e.getValue(context); }
单元测试:
@Testpublic void nextTaskInfo()
throws Exception{ActivitiNextTask task =
new ActivitiNextTask();String processInstanceId =
"387905";TaskDefinition nextTaskGroup = task.getNextTaskInfo(processInstanceId);System.out.println(nextTaskGroup.getKey());}
通过测试能够正确的根据条件获取下一个usetask节点信息。
那么又存在另一种情况,如果流程中存在连续多个GateWay,那么上述的程序获取下一个节点就不正确了,所以需要在上述的程序上在进行修改。
二、流程图二
在费用报销申请后面有两个GateWay,当流程到达费用报销申请时需要判断下一步是审批还是审批(部门经理)对于第二个GateWay需要修改的是:
然后再对上述的代码进行修改:
private TaskService taskService = ProcessEngines.getDefaultProcessEngine().getTaskService() ;
private RuntimeService runtimeService = ProcessEngines.getDefaultProcessEngine().getRuntimeService();
private RepositoryService repositoryService = ProcessEngines.getDefaultProcessEngine().getRepositoryService();
/** * 获取下一个用户任务信息 * @param String taskId 任务Id信息 * @return 下一个用户任务用户组信息 * @throws Exception */ public TaskDefinition
getNextTaskInfo(String processInstanceId)
throws Exception { ProcessDefinitionEntity processDefinitionEntity =
null; String id =
null; TaskDefinition task =
null; String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult().getProcessDefinitionId(); processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) .getDeployedProcessDefinition(definitionId); ExecutionEntity execution = (ExecutionEntity) runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); String activitiId = execution.getActivityId(); List<ActivityImpl> activitiList = processDefinitionEntity.getActivities();
for(ActivityImpl activityImpl : activitiList){ id = activityImpl.getId();
if (activitiId.equals(id)) {task = nextTaskDefinition(activityImpl, activityImpl.getId(),
null, processInstanceId);
break;}}
return task; }
/** * 下一个任务节点信息, * * 如果下一个节点为用户任务则直接返回, * * 如果下一个节点为排他网关, 获取排他网关Id信息, 根据排他网关Id信息和execution获取流程实例排他网关Id为key的变量值, * 根据变量值分别执行排他网关后线路中的el表达式, 并找到el表达式通过的线路后的用户任务* @param ActivityImpl activityImpl 流程节点信息 * @param String activityId 当前流程节点Id信息 * @param String elString 排他网关顺序流线段判断条件* @param String processInstanceId 流程实例Id信息 * @return */ private TaskDefinition
nextTaskDefinition(ActivityImpl activityImpl, String activityId, String elString, String processInstanceId){ PvmActivity ac =
null;Object s =
null;
if (
"userTask".equals(activityImpl.getProperty(
"type")) && !activityId.equals(activityImpl.getId())) {TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior()).getTaskDefinition();
return taskDefinition;}
else if(
"exclusiveGateway".equals(activityImpl.getProperty(
"type"))){List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();
elString = getGatewayCondition(activityImpl.getId(), processInstanceId);
if (outTransitions.size() ==
1) {
return nextTaskDefinition((ActivityImpl) outTransitions.get(
0).getDestination(), activityId,elString, processInstanceId);}
else if (outTransitions.size() >
1) {
for (PvmTransition tr1 : outTransitions) {s = tr1.getProperty(
"conditionText");
if (isCondition(activityImpl.getId(), StringUtils.trim(s.toString()), elString)) {
return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,processInstanceId);}}}}
else {List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions();List<PvmTransition> outTransitionsTemp =
null;
for (PvmTransition tr : outTransitions) {ac = tr.getDestination();
if (
"exclusiveGateway".equals(ac.getProperty(
"type"))) {outTransitionsTemp = ac.getOutgoingTransitions();
if (StringUtils.isEmpty(elString)) {elString = getGatewayCondition(ac.getId(), processInstanceId);}
if (outTransitionsTemp.size() ==
1) {
return nextTaskDefinition((ActivityImpl) outTransitionsTemp.get(
0).getDestination(), activityId,elString, processInstanceId);}
else if (outTransitionsTemp.size() >
1) {
for (PvmTransition tr1 : outTransitionsTemp) {s = tr1.getProperty(
"conditionText");
if (isCondition(ac.getId(), StringUtils.trim(s.toString()), elString)) {
return nextTaskDefinition((ActivityImpl) tr1.getDestination(), activityId, elString,processInstanceId);}}}}
else if (
"userTask".equals(ac.getProperty(
"type"))) {
return ((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior()).getTaskDefinition();}
else {}}
return null;}
return null;}
/** * 查询流程启动时设置排他网关判断条件信息 * @param String gatewayId 排他网关Id信息, 流程启动时设置网关路线判断条件key为网关Id信息 * @param String processInstanceId 流程实例Id信息 * @return */ public String
getGatewayCondition(String gatewayId, String processInstanceId) { Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult();Object object= runtimeService.getVariable(execution.getId(), gatewayId);
return object==
null?
"":object.toString(); }
/** * 根据key和value判断el表达式是否通过信息 * @param String key el表达式key信息 * @param String el el表达式信息 * @param String value el表达式传入值信息 * @return */ public boolean isCondition(String key, String el, String value) { ExpressionFactory factory =
new ExpressionFactoryImpl(); SimpleContext context =
new SimpleContext(); context.setVariable(key, factory.createValueExpression(value, String.class)); ValueExpression e = factory.createValueExpression(context, el,
boolean.class);
return (Boolean) e.getValue(context); }
编写测试用例:
@Testpublic void startProcessInstance(){String processDefinitionKey =
"exclusiveGateWay";Map<String, Object> param =
new HashMap<>();param.put(
"creditor",
"group");param.put(
"subCreditor",
"a");processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey,param);}
按照上述的测试用例流程到达-费用报销申请,下一步应该是审批【部门经理】
@Testpublic void nextTaskInfo()
throws Exception{ActivitiNextTask task =
new ActivitiNextTask();String processInstanceId =
"387905";TaskDefinition nextTaskGroup = task.getNextTaskInfo(processInstanceId);System.out.println(nextTaskGroup.getNameExpression().getExpressionText());}
总结
以上是生活随笔为你收集整理的activiti根据当前节点获取下一个UseTask节点的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。