Camunda如何获取(预取)下一审批节点

        在实际业务使用过程中,存在需要当前审批人指定或可修改下一审批节点的审批人(单个或多个),这时候就先要获取到下一审批节点,然后在提交时给引擎传递相应的变量,达到用户指定下一节点审批人的目标。

         模型如下图所示 :      Camunda如何获取(预取)下一审批节点_第1张图片

        模型定义文件:



  
    
      Flow_1lqot0o
    
    
    
    
      Flow_18thiqs
    
    
    
      Flow_1lqot0o
      Flow_0yuchf0
    
    
      Flow_11k93to
      Flow_0qdzfen
      
        ${nrOfCompletedInstances==1}
      
    
    
    
      Flow_0qdzfen
      Flow_1xbjwul
    
    
      Flow_0yuchf0
      Flow_11k93to
      Flow_0njpgjv
    
    
      ${amount >= 1000}
    
    
    
      Flow_0uawe9o
      Flow_1xbjwul
      Flow_18thiqs
    
    
    
    
      Flow_0njpgjv
      Flow_0uawe9o
    
  
  
    
      
        
        
      
      
        
        
      
      
        
        
      
      
        
        
        
      
      
        
        
        
        
          
        
      
      
        
        
        
        
          
        
      
      
        
        
        
      
      
        
        
      
      
        
        
          
        
      
      
        
      
      
        
      
      
        
        
          
        
      
      
        
      
      
        
      
      
        
      
      
        
      
    
  

        发起流程:

@Test
	public void startProcess() {
		try {
			ProcessRequest processRequest = new ProcessRequest();
			processRequest.setProcessDefKey("Process_1fh6max");
			processRequest.setStarter("bx1");
			AuthenticationService authenticationService = new AuthenticationService();
			String engineName = processEngine.getName();
			UserAuthentication authentication = (UserAuthentication) authenticationService
					.createAuthenticate(engineName, "bx1", null, null);
			logger.info("authentication--------->" + authentication.getName());
			// Authentications.clearCurrent();
			identityService.setAuthenticatedUserId(authentication.getName());
			String processInstanceId = null;
			List resultList = new ArrayList();
			Map variables = new HashMap();
			List assigneeList = new ArrayList<>();
			assigneeList.add("bx2");
			assigneeList.add("bx3");
			variables.put("assigneeList", assigneeList);
			//variables.put("starter", processRequest.getStarter());
			variables.put("amount", 1100);
			ProcessInstance processInstance = null;

			ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
					.processDefinitionKey(processRequest.getProcessDefKey()).latestVersion().singleResult();
			if (pd == null) {
				throw new Exception("流程模型:" + processRequest.getProcessDefKey() + "不存在!");
			}
			if (pd != null && pd.isSuspended()) {
				throw new Exception("流程模型:" + processRequest.getProcessDefKey() + "已挂起,暂无法发起流程!");
			}
			// 流程初始化
			if (StringUtils.isNotBlank(processRequest.getProcessDefKey())) {
				processInstance = runtimeService.startProcessInstanceByKey(processRequest.getProcessDefKey(),
						variables);
			} else {
				processInstance = runtimeService.startProcessInstanceById(processRequest.getProcessDefId(), variables);
			}
			// 创建成功
			if (processInstance != null && StringUtils.isNotBlank(processInstance.getId())) {
				processInstanceId = processInstance.getId();
				List taskList = simpleGetTasks(processInstanceId);
				logger.info(JSON.toJSONString(taskList));
//				if (taskList != null && taskList.size() == 1) {
//					taskService.complete(taskList.get(0).getId(), variables);
//					taskService.createComment(taskList.get(0).getId(), processInstanceId, "提交流程");
//					resultList = simpleGetTasks(processInstanceId);
//				} else {
//					throw new Exception("获取提交任务失败:" + taskList.size());
//				}
			} else {
				throw new Exception("创建流程实例失败:");
			}
			System.out.println(JSON.toJSONString(resultList));

		} catch (Exception e) {
			e.printStackTrace();
		}
	}

        执行预取:

@Test
	public void simulationNextPath() {
		String userId = "bx1";
		String processInstanceId = "5e46947a-8cd1-11ec-b7ab-8c1645647a47";

		AuthenticationService authenticationService = new AuthenticationService();
		String engineName = processEngine.getName();
		UserAuthentication authentication = (UserAuthentication) authenticationService.createAuthenticate(engineName,
				userId, null, null);
		logger.info("authentication--------->" + authentication.getName());
		identityService.setAuthenticatedUserId(authentication.getName());
		Map condition = runtimeService.getVariables(processInstanceId);
		condition.put("amount", 500);
		System.out.println("condition---->" + JSON.toJSONString(condition));
		List tasks = null;
		try {
			tasks = getNextTaskInfos(processInstanceId, condition);
		} catch (Exception e) {
			e.printStackTrace();
		}
		logger.info("----------->" + JSON.toJSONString(tasks, SerializerFeature.DisableCircularReferenceDetect));
		JSONArray ja = new JSONArray();
		if (!CollectionUtils.isEmpty(tasks)) {
			for (TaskDefinition task : tasks) {
				JSONObject jo = new JSONObject();
				jo.put("key", task.getKey());
				jo.put("name", task.getNameExpression().getExpressionText());
				jo.put("assignment",
						task.getAssigneeExpression() == null ? "" : task.getAssigneeExpression().getExpressionText());
				ja.add(jo);
			}
		}
		System.out.println("----->" + ja.toString());

	}

        预取核心代码:

/**
	 * 获取下一个节点任务信息
	 * 
	 * @param processInstanceId
	 *            流程实例ID
	 * @return 下一个节点信息
	 * @throws Exception
	 */
	public List getNextTaskInfos(String processInstanceId, Map condition)
			throws Exception {
		try {
			ProcessDefinitionEntity processDefinitionEntity = null;
			String id = null;
			// List tasks =
			// null;//会出现java.util.ConcurrentModificationException异常,改成CopyOnWriteArrayList
			List tasks = new CopyOnWriteArrayList();
			// 获取流程发布Id信息
			String definitionId = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId)
					.singleResult().getProcessDefinitionId();
			processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService)
					.getDeployedProcessDefinition(definitionId);
			ExecutionEntity execution = (ExecutionEntity) runtimeService.createExecutionQuery()
					.executionId(processInstanceId).singleResult();
			// 当前流程节点Id信息
			String activitiId = execution.getActivityId();
			System.out.println("execution----->" + activitiId);
			// 获取流程所有节点信息
			List activitiList = processDefinitionEntity.getActivities();

			JSONArray ja = new JSONArray();
			// 遍历所有节点信息
			for (ActivityImpl activityImpl : activitiList) {
				id = activityImpl.getId();
				System.out.println("id----------->" + id + "----->" + activityImpl.getProperty("type"));
				if (activitiId.equals(id)) {
					// 获取下一个节点信息
					tasks = nextTaskDefinitions(activityImpl, activityImpl.getId(), processInstanceId, condition);
					break;
				}
			}

			return tasks;
		} catch (Exception e) {

			logger.error("operation error", e);
			throw e;
		}
	}

	private List nextTaskDefinitions(ActivityImpl activityImpl, String activityId,
			String processInstanceId, Map condition) {
		try {
			PvmActivity ac = null;
			Object s = null;
			System.out.println("activityImpl.getActivityId()---->"+activityImpl.getActivityId()+"---activityId---------->"+activityId+"--->"+activityImpl.getProperty("type"));
			// List taskDefinitions = new
			// ArrayList();
			// //会出现java.util.ConcurrentModificationException异常,改成CopyOnWriteArrayList
			List taskDefinitions = new CopyOnWriteArrayList();
			// 如果遍历节点为用户任务并且节点不是当前节点信息
			if ("userTask".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
				// 获取该节点下一个节点信息
				TaskDefinition taskDefinition = ((UserTaskActivityBehavior) activityImpl.getActivityBehavior())
						.getTaskDefinition();
				taskDefinitions.add(taskDefinition);
			}else if (activityImpl.getProperty("type").toString().contains("EndEvent") && !activityId.equals(activityImpl.getId())) {
				// 设置结束节点
				TaskDefinition taskDefinition = new TaskDefinition(null);
				ExpressionManager expressionManager = new ExpressionManager();
				taskDefinition.setKey(activityImpl.getId() == null ? "end" : activityImpl.getId());
				String name = activityImpl.getProperty("name") == null ? "结束" : activityImpl.getProperty("name").toString();
				taskDefinition.setNameExpression(expressionManager.createExpression(name));
				taskDefinitions.add(taskDefinition);
			} else if ("multiInstanceBody".equals(activityImpl.getProperty("type")) && !activityId.equals(activityImpl.getId())) {
				// 获取该节点下一个节点信息
				List list = ((ActivityImpl) activityImpl).getActivities();
				for(ActivityImpl act : list){
					//System.out.println("act-------------->"+act.getActivityBehavior().getClass().getTypeName());  
					TaskDefinition taskDefinition = ((UserTaskActivityBehavior) act.getActivityBehavior())
							.getTaskDefinition();
					taskDefinitions.add(taskDefinition);
				}
			} else if ("exclusiveGateway".equals(activityImpl.getProperty("type"))
					|| "inclusiveGateway".equals(activityImpl.getProperty("type"))) {// 当前节点为exclusiveGateway或inclusiveGateway
				List outTransitions = activityImpl.getOutgoingTransitions();
				String defaultTransition = (String) activityImpl.getProperty("default");
				if (outTransitions.size() == 1) {
					taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) outTransitions.get(0).getDestination(),
							activityId, processInstanceId, condition));
				} else if (outTransitions.size() > 1) { // 如果排他网关有多条线路信息
					for (PvmTransition tr1 : outTransitions) {
						ActivityImpl actImpl = (ActivityImpl) tr1.getDestination();
						if (actImpl.getProperty("type").toString().contains("EndEvent")) {
							TaskDefinition taskDefinition = new TaskDefinition(null);
							ExpressionManager expressionManager = new ExpressionManager();
							taskDefinition.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
							String name = actImpl.getProperty("name") == null ? "结束"
									: actImpl.getProperty("name").toString();
							taskDefinition.setNameExpression(expressionManager.createExpression(name));
							taskDefinitions.add(taskDefinition);
							break;
						}
						s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
						if (null == s) {
							continue;
						}
						// 判断el表达式是否成立
						if (isCondition(condition, StringUtils.trim(s.toString()))) {
							taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
									processInstanceId, condition));
						}
					}
					if(taskDefinitions.size()==0 && StringUtils.isNotBlank(defaultTransition)){
						for (PvmTransition tr3 : outTransitions) {
							if(defaultTransition.equals(tr3.getId())){
								ActivityImpl actImpl = (ActivityImpl) tr3.getDestination();
								if (actImpl.getProperty("type").toString().contains("EndEvent")) {
									TaskDefinition taskDefinition2 = new TaskDefinition(null);
									ExpressionManager expressionManager2 = new ExpressionManager();
									taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
									String name2 = actImpl.getProperty("name") == null ? "结束"
											: actImpl.getProperty("name").toString();
									taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
									taskDefinitions.add(taskDefinition2);
									break;
								}

								taskDefinitions.addAll(nextTaskDefinitions( actImpl,
										activityId, processInstanceId, condition));
								System.out.println("taskDefinitions---333333333--->"+taskDefinitions.size());
							}
						}
					}
				}
			} else if ("parrallelGateway".equals(activityImpl.getProperty("type"))) {
				List outTransitions = activityImpl.getOutgoingTransitions();
				for (PvmTransition tr1 : outTransitions) {
					taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
							processInstanceId, condition));
				}
			} else {
				// 获取节点所有流向线路信息
				List outTransitions = activityImpl.getOutgoingTransitions();
				List outTransitionsTemp = null;
				for (PvmTransition tr : outTransitions) {
					ac = tr.getDestination(); // 获取线路的终点节点
					System.out.println("ac----------->" + ac.getId() + "------>" + ac.getProperty("type"));
					// 如果流向线路为排他网关或包容网关
					if ("exclusiveGateway".equals(ac.getProperty("type"))
							|| "inclusiveGateway".equals(ac.getProperty("type"))) {
						outTransitionsTemp = ac.getOutgoingTransitions();
						String defaultTransition = (String) ac.getProperty("default");
						// 如果排他网关只有一条线路信息
						if (outTransitionsTemp.size() == 1) {
							taskDefinitions.addAll(
									nextTaskDefinitions((ActivityImpl) outTransitionsTemp.get(0).getDestination(),
											activityId, processInstanceId, condition));
						} else if (outTransitionsTemp.size() > 1) { // 如果排他网关有多条线路信息
							for (PvmTransition tr1 : outTransitionsTemp) {
								ActivityImpl actImpl = (ActivityImpl) tr1.getDestination();
								if (actImpl.getProperty("type").toString().contains("EndEvent")) {
									TaskDefinition taskDefinition2 = new TaskDefinition(null);
									ExpressionManager expressionManager2 = new ExpressionManager();
									taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
									String name2 = actImpl.getProperty("name") == null ? "结束"
											: actImpl.getProperty("name").toString();
									taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
									taskDefinitions.add(taskDefinition2);
									break;
								}

								System.out.println("taskDefinitions--1111---->"+taskDefinitions.size());
								s = tr1.getProperty("conditionText"); // 获取排他网关线路判断条件信息
								if (null == s) {
									continue;
								}
								// 判断el表达式是否成立
								if (isCondition(condition, StringUtils.trim(s.toString()))) {
									taskDefinitions.addAll(nextTaskDefinitions(actImpl,activityId, processInstanceId, condition));
								}
								
								System.out.println("taskDefinitions---22222--->"+taskDefinitions.size());
							}
							if(taskDefinitions.size()==0 && StringUtils.isNotBlank(defaultTransition)){
								for (PvmTransition tr3 : outTransitionsTemp) {
									if(defaultTransition.equals(tr3.getId())){
										ActivityImpl actImpl = (ActivityImpl) tr3.getDestination();
										if (actImpl.getProperty("type").toString().contains("EndEvent")) {
											TaskDefinition taskDefinition2 = new TaskDefinition(null);
											ExpressionManager expressionManager2 = new ExpressionManager();
											taskDefinition2.setKey(actImpl.getId() == null ? "end" : actImpl.getId());
											String name2 = actImpl.getProperty("name") == null ? "结束"
													: actImpl.getProperty("name").toString();
											taskDefinition2.setNameExpression(expressionManager2.createExpression(name2));
											taskDefinitions.add(taskDefinition2);
											break;
										}
	
										taskDefinitions.addAll(nextTaskDefinitions( actImpl,
												activityId, processInstanceId, condition));
										System.out.println("taskDefinitions---333333333--->"+taskDefinitions.size());
									}
								}
							}
						}
					} else if ("userTask".equals(ac.getProperty("type"))) {
						taskDefinitions.add(((UserTaskActivityBehavior) ((ActivityImpl) ac).getActivityBehavior())
								.getTaskDefinition());
					} else if ("multiInstanceBody".equals(ac.getProperty("type"))) {
						List list = ((ActivityImpl) ac).getActivities();
						for(ActivityImpl act : list){
							//System.out.println("act-------------->"+act.getActivityBehavior().getClass().getTypeName());  
							TaskDefinition taskDefinition = ((UserTaskActivityBehavior) act.getActivityBehavior())
									.getTaskDefinition();
							taskDefinitions.add(taskDefinition);
						}
					} else if (ac.getProperty("type").toString().contains("EndEvent")) {
						// 设置结束节点
						TaskDefinition taskDefinition = new TaskDefinition(null);
						ExpressionManager expressionManager = new ExpressionManager();
						taskDefinition.setKey(ac.getId() == null ? "end" : ac.getId());
						String name = ac.getProperty("name") == null ? "结束" : ac.getProperty("name").toString();
						taskDefinition.setNameExpression(expressionManager.createExpression(name));
						taskDefinitions.add(taskDefinition);
					} else if ("parrallelGateway".equals(ac.getProperty("type"))) {
						List poutTransitions = ac.getOutgoingTransitions();
						for (PvmTransition tr1 : poutTransitions) {
							taskDefinitions.addAll(nextTaskDefinitions((ActivityImpl) tr1.getDestination(), activityId,
									processInstanceId, condition));
						}
					}
				}
			}
			return taskDefinitions;

		} catch (Exception e) {
			logger.error("operation error", e);
			throw e;
		}
	}

	private boolean isCondition(Map condition, String el) {
		try {
			ExpressionFactory factory = new ExpressionFactoryImpl();
			SimpleContext context = new SimpleContext();
			if (condition != null) {
				Iterator> iterator = condition.entrySet().iterator();
				while (iterator.hasNext()) {
					Map.Entry value = iterator.next();
					context.setVariable(value.getKey(), factory.createValueExpression(value.getValue(), String.class));
				}
			}
			ValueExpression e = factory.createValueExpression(context, el, boolean.class);
			return (Boolean) e.getValue(context);
		} catch (Exception e) {
			logger.error("operation error", e);
			throw e;
		}
	}

        关于分支条件问题,预取时可以传入变量,模拟修改或设置变量,以便根据isCondition来判断分支条件是否成立,如下,该流程实例启动时设置的amount变量为1100,预取时设置为500,获取到的节点为”审批2“,经测试达到预期效果。Camunda如何获取(预取)下一审批节点_第2张图片

PS:预取代码没有进行严格测试,可能存在缺陷或性能问题,欢迎加QQ群:650886724 进行反馈与讨论,谢谢!

 

你可能感兴趣的:(Camunda,Camunda,获取下一审批节点,预取)