以前寫過一篇文章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节点的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。