工作流引擎Activiti中獲取下一分支節點

Aaron莫言發表於2020-11-09
/** 
     * 根據例項編號查詢下一個任務節點 
     * @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));  

在這裡插入程式碼片/**
	 * 查詢流程當前節點的下一步節點。用於流程提示時的提示。
	 * 
	 * @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);
			}
		}
	}

相關文章