Activiti系列七: 流程分支

一 连线流程(SequenceFlow)

另一条线的设置如下:

代码如下:

public void queryAndExecTasks(String deployId){
		ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();
		//获得流程执行服务类对象
		RuntimeService runServ=engine.getRuntimeService();
		//获得任务管理服务类对象
		TaskService taskServ=engine.getTaskService();
		TaskQuery taskQuery= taskServ.createTaskQuery().deploymentId(deployId);
		List<Task> taskList=taskQuery.orderByTaskCreateTime().asc().list();
		Map<String, Object> varMap=null;
		for(Task task:taskList){
			if(task.getTaskDefinitionKey().equals("leaveApply01")){
				System.out.println("当前进行流程第一步,进行第一步流程变量定义");
				LeaveVariableEntity variableEntity=new LeaveVariableEntity();
				variableEntity.setLeavePerson(task.getAssignee());
				variableEntity.setReason("回家结婚");
				variableEntity.setHours(8);
				runServ.setVariable(task.getProcessInstanceId(), "leave01", variableEntity);
			}
			if(task.getTaskDefinitionKey().equals("managerApprove02")){
				//${msg=='unimportant'}
				varMap=new HashMap<String, Object>();
				varMap.put("msg", "important");
				System.out.println("当前进行流程第二步,获取上一步流程变量");
				LeaveVariableEntity processVariableEntity=runServ.getVariable(task.getProcessInstanceId(), "leave01", LeaveVariableEntity.class);
				System.out.println("请假人:"+processVariableEntity.getLeavePerson()+",原因:"+processVariableEntity.getReason()+",请假时间:"+processVariableEntity.getHours());
			}
			System.out.println("taskId:"+task.getId()+",taskName:"+task.getName()+",办理人assinger:"+task.getAssignee());
			if(varMap!=null && varMap.get("msg").equals("important")){
				System.out.println("第二步设置流程变量"+varMap.get("msg")+",指示下一步要不要执行");
				taskServ.complete(task.getId(),varMap);
			}else{
				taskServ.complete(task.getId());
			}
			
			System.out.println("**********当前任务已完成*****************");
		}
	}

1. 一个活动中可以指定一个或多个SequenceFlow(Start中有一个,End中没有)。

  * 开始活动中有一个SequenceFlow 。

  * 结束活动中没有SequenceFlow 。

  * 其他活动中有1条或多条SequenceFlow

2、如果只有一个,则可以不使用流程变量设置codition的名称;

 

如果有多个,则需要使用流程变量设置codition的名称。message表示流程变量的名称,‘不重要’表示流程变量的值,${}中间的内容要使用boolean类型的表达式,用来判断应该执行的连线。

 

二  排它网关

最上面的分支是默认分支,可以不设置条件

最下面的分支设置如图:

验证代码:

//查询当前是谁执行的流程并执行
	public void queryAndExecTasks(String deployId){
		ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();
		//获得任务管理服务类对象
		TaskService taskServ=engine.getTaskService();
		TaskQuery taskQuery= taskServ.createTaskQuery().deploymentId(deployId);
		List<Task> taskList=taskQuery.orderByTaskCreateTime().asc().list();
		Map<String, Object> varMap=null;
		if(taskList.size()==0){
			System.out.println("流程已经结束");
			return;
		}
		for(Task task:taskList){
			if(task.getTaskDefinitionKey().equals("userTask1")){
				varMap=new HashMap<String, Object>();
				varMap.put("money", 1650);
				System.out.println("当前进行流程第一步,设置流程变量money="+varMap.get("money")+",进行排它网关验证");
			}
			System.out.println("taskId:"+task.getId()+",taskName:"+task.getName()+",办理人assinger:"+task.getAssignee());
			if(varMap!=null){
				System.out.println("请观察下一步审批人是谁");
				taskServ.complete(task.getId(),varMap);
			}else{
				taskServ.complete(task.getId());
			}
			System.out.println("**********当前任务已完成*****************");
		}
	}

说明:

  1. 一个排他网关对应一个以上的顺序流
  2. 由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
  3. 决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
  4. 如果没有任何一个出口符合条件,则抛出异常

使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开。

三、 并行网关(parallelGateWay)

验证代码

//查询当前是谁执行的流程并执行
	public void queryAndExecTasks(String deployId){
		ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();
		//获得流程执行服务类对象
		RuntimeService runServ=engine.getRuntimeService();
		//获得任务管理服务类对象
		TaskService taskServ=engine.getTaskService();
		TaskQuery taskQuery= taskServ.createTaskQuery().deploymentId(deployId);
		List<Task> taskList=taskQuery.orderByTaskCreateTime().asc().list();
		Map<String, Object> varMap=null;
		if(taskList.size()==0){
			System.out.println("流程已经结束");
			return;
		}
		Task task=taskList.get(0);
		if(task.getTaskDefinitionKey().contains("userTask2")){
			ProcessInstance pi=runServ.createProcessInstanceQuery().processDefinitionId(task.getProcessDefinitionId()).singleResult();
			System.out.println("当前进行流程第二步,进行并行网关验证,流程实例id:"+pi.getId()+",实例id2:"+pi.getProcessInstanceId()+",executionId:"+task.getExecutionId());
			String theValue=(String)runServ.getVariable(task.getProcessInstanceId(), "startVar");
			System.out.println("流程变量==>"+theValue);
		}
		System.out.println("taskId:"+task.getId()+",taskName:"+task.getName()+",办理人assinger:"+task.getAssignee());
		taskServ.complete(task.getId());
		System.out.println("**********任务【"+task.getName()+"】已完成*****************");
	}

说明:

  1. 一个流程中流程实例只有1个,执行对象有多个
  2. 并行网关的功能是基于进入和外出的顺序流的:

分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。

汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

  1. 并行网关的进入和外出都是使用相同节点标识
  2. 如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
  3. 并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。

并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目不一定相等)。如图中标示是合法的:

四 任务驳回与主动撤回

1. 任务驳回

部门经理审批驳回设置

验证代码:

/**
	 * 查询流程并处理
	 * @param deployId
	 */
	public void queryAndExecTasks(String deployId,String step,String idea){
		Map<String, Object> varMap=new HashMap<String, Object>();
		ProcessEngine theEngine=ProcessEngines.getDefaultProcessEngine();
		//任务管理服务
		TaskService taskServ=theEngine.getTaskService();
		TaskQuery theQuery=taskServ.createTaskQuery().deploymentId(deployId)
				                 .orderByTaskCreateTime().asc();
		List<Task> taskList=theQuery.list();
		if(taskList.size()>0){
			for(Task task:taskList){
				//如果是流程第一步
				if(step.equals("leaveApply01")){
					taskServ.complete(task.getId());
					System.out.println("第一步完成==>处理人:"+task.getAssignee()+",任务id:"+task.getId());
				}
				//如果是流程第二步
				if(step.equals("managerApprove02")){
					//${departIdea=='pass'}
					varMap.put("departIdea", idea);
					taskServ.complete(task.getId(),varMap);
					System.out.println("第二步完成==>处理人:"+task.getAssignee()+",处理意见==>"+idea);
				}
				//如果是流程第三步
				if(step.equals("presidentApprove03")){
					varMap.put("managerIdea", idea);
					taskServ.complete(task.getId(),varMap);
					System.out.println("第三步完成==>处理人:"+task.getAssignee()+",处理意见==>"+idea);
				}
			}
		}else{
			System.out.println("请假流程结束!");
		}
	}

 2. 任务主动撤回

流程图仍然是上面的图

/**
	 * 根据当前任务id主动撤回
	 * @param taskId
	 */
	public void back(String taskId){
		Map<String, Object> varMap=new HashMap<String, Object>();
		ProcessEngine engine=ProcessEngines.getDefaultProcessEngine();
		RepositoryService repoServ=engine.getRepositoryService();
		HistoryService hisServ=engine.getHistoryService();
		RuntimeService runServ=engine.getRuntimeService();
		TaskService taskServ=engine.getTaskService();
		HistoricTaskInstance hisTask=hisServ.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
		
		if(hisTask==null){
			System.out.println("没有该任务,可能已经被删除");
			return;
		}
		ProcessInstance processInstance= runServ.createProcessInstanceQuery().processInstanceId(hisTask.getProcessInstanceId()).singleResult();
		if(processInstance==null){
			System.out.println("流程已经结束,无法回退");
		}
		//获得当前任务
		List<Task> curTaskList=taskServ.createTaskQuery().processInstanceId(processInstance.getId()).orderByTaskCreateTime().asc().list();
		if(curTaskList.size()==0){
			System.out.println("任务被删除,无法回退");
		}
		for(Task task:curTaskList){
			//如果是流程第二步
			if(task.getTaskDefinitionKey().equals("managerApprove02")){
				//${departIdea=='pass'}
				varMap.put("departIdea", "fail");
				taskServ.complete(task.getId(),varMap);
				System.out.println("第二步自动处理回退到第一步");
			}
			//如果是流程第三步
			if(task.getTaskDefinitionKey().equals("presidentApprove03")){
				varMap.put("managerIdea", "fail");
				//taskServ.set
				taskServ.complete(task.getId(),varMap);
				System.out.println("第三步自动处理回退到第一步");
			}
		}
		
	}

思路:

1. 根据任务id的到历史任务实例对象

2. 获得当前流程实例对象

3 获得当前任务列表

4.判断当前任务到哪一步了,然后根据流程图的连线撤回

 

猜你喜欢

转载自blog.csdn.net/wx5040257/article/details/114183271
今日推荐