一 连线流程(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("**********当前任务已完成*****************");
}
}
说明:
- 一个排他网关对应一个以上的顺序流
- 由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
- 决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
- 如果没有任何一个出口符合条件,则抛出异常
使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开。
三、 并行网关(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个,执行对象有多个
- 并行网关的功能是基于进入和外出的顺序流的:
分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。
- 并行网关的进入和外出都是使用相同节点标识
- 如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
- 并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目不一定相等)。如图中标示是合法的:
四 任务驳回与主动撤回
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.判断当前任务到哪一步了,然后根据流程图的连线撤回