工作流Activiti5入门(中)
时光匆匆,没想到转眼离上次写工作流Activiti5入门(上)已经过去快四个月了,上次主要写了有关环境的搭建、工作流的部署、启动、查询、认领、完成任务以及查询流程状态和删除流程等,今天我们看看一些更高级也是非常经常用到的一些功能。
一. 连线
一个流程图不可能都是一些孤立的点,点和点之间需要一些线连接,那么这些线该如何连接呢?
1. 一个活动中可以指定一个或多个SequenceFlow。
开始活动中有一个SequenceFlow 。
结束活动中没有SequenceFlow 。
其他活动中有1条或多条SequenceFlow
2. 如果只有一个,则可以不使用流程变量设置codition的名称;
如果有多个,则需要使用流程变量设置codition的名称。message表示流程变量的名称,‘不重要’表示流程变量的值,${}中间的内容要使用boolean类型的表达式,用来判断应该执行的连线。例如可以这样,如果${}成立,则会按照这个方向走
3. 流程图
4. 完成任务
1 2 3 4 5 6 7 8 9 10 11 12 13 | /**完成我的任务*/ @Test public void completeMyPersonalTask(){ //任务ID String taskId = "3103" ; //完成任务的同时,设置流程变量,使用流程变量用来指定完成任务后,下一个连线,对应sequenceFlow.bpmn文件中${message=='不重要'} Map<String, Object> variables = new HashMap<String, Object>(); variables.put( "message" , "重要" ); processEngine.getTaskService() //与正在执行的任务管理相关的Service .complete(taskId,variables); System.out.println( "完成任务:任务ID:" +taskId); } |
连线比较简单,既不多做介绍了
二. 排他网关
1. 一个排他网关对应一个以上的顺序流
由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。
如果没有任何一个出口符合条件,则抛出异常
使用流程变量,设置连线的条件,并按照连线的条件执行工作流,如果没有条件符合的条件,则以默认的连线离开。
2. 流程图
3. 完成个人任务
1 2 3 4 5 6 7 8 9 10 11 12 | /**完成我的任务*/ @Test public void completeMyPersonalTask(){ //任务ID String taskId = "3904" ; //完成任务的同时,设置流程变量,使用流程变量用来指定完成任务后,下一个连线,对应exclusiveGateWay.bpmn文件中${money>1000} Map<String, Object> variables = new HashMap<String, Object>(); variables.put( "money" , 200); processEngine.getTaskService() //与正在执行的任务管理相关的Service .complete(taskId,variables); System.out.println( "完成任务:任务ID:" +taskId); } |
三. 并行网关
1. 一个流程中流程实例只有1个,执行对象有多个
并行网关的功能是基于进入和外出的顺序流的:
分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
汇聚(join): 所有到达并行网关,在此等待的进入分支, 直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。
并行网关的进入和外出都是使用相同节点标识
如果同一个并行网关有多个进入和多个外出顺序流, 它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。
并行网关不会解析条件。 即使顺序流中定义了条件,也会被忽略。
并行网关不需要是“平衡的”(比如, 对应并行网关的进入和外出节点数目不一定相等)。
2. 流程图
3. 完成任务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | /**启动流程实例*/ @Test public void startProcessInstance(){ //流程定义的key String processDefinitionKey = "parallelGateWay" ; ProcessInstance pi = processEngine.getRuntimeService() //与正在执行的流程实例和执行对象相关的Service .startProcessInstanceByKey(processDefinitionKey); //使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动 System.out.println( "流程实例ID:" +pi.getId()); //流程实例ID 101 System.out.println( "流程定义ID:" +pi.getProcessDefinitionId()); //流程定义ID helloworld:1:4 } /**查询当前人的个人任务*/ @Test public void findMyPersonalTask(){ String assignee = "商家" ; List<Task> list = processEngine.getTaskService() //与正在执行的任务管理相关的Service .createTaskQuery() //创建任务查询对象 /**查询条件(where部分)*/ .taskAssignee(assignee) //指定个人任务查询,指定办理人 // .taskCandidateUser(candidateUser)//组任务的办理人查询 // .processDefinitionId(processDefinitionId)//使用流程定义ID查询 // .processInstanceId(processInstanceId)//使用流程实例ID查询 // .executionId(executionId)//使用执行对象ID查询 /**排序*/ .orderByTaskCreateTime().asc() //使用创建时间的升序排列 /**返回结果集*/ // .singleResult()//返回惟一结果集 // .count()//返回结果集的数量 // .listPage(firstResult, maxResults);//分页查询 .list(); //返回列表 if (list!=null && list.size()>0){ for (Task task:list){ System.out.println( "任务ID:" +task.getId()); System.out.println( "任务名称:" +task.getName()); System.out.println( "任务的创建时间:" +task.getCreateTime()); System.out.println( "任务的办理人:" +task.getAssignee()); System.out.println( "流程实例ID:" +task.getProcessInstanceId()); System.out.println( "执行对象ID:" +task.getExecutionId()); System.out.println( "流程定义ID:" +task.getProcessDefinitionId()); System.out.println( "########################################################" ); } } } /**完成我的任务*/ @Test public void completeMyPersonalTask(){ //任务ID String taskId = "4302" ; processEngine.getTaskService() //与正在执行的任务管理相关的Service .complete(taskId); System.out.println( "完成任务:任务ID:" +taskId); } |
四. 接收活动(receiveTask,即等待活动)
接收任务是一个简单任务,它会等待对应消息的到达。 当前,官方只实现了这个任务的java语义。 当流程达到接收任务,流程状态会保存到数据库中。
在任务创建后,意味着流程会进入等待状态, 直到引擎接收了一个特定的消息, 这会触发流程穿过接收任务继续执行。
例如:
流程图:
完成任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /**启动流程实例+设置流程变量+获取流程变量+向后执行一步*/ @Test public void startProcessInstance(){ //流程定义的key String processDefinitionKey = "receiveTask" ; ProcessInstance pi = processEngine.getRuntimeService() //与正在执行的流程实例和执行对象相关的Service .startProcessInstanceByKey(processDefinitionKey); //使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动 System.out.println( "流程实例ID:" +pi.getId()); //流程实例ID 101 System.out.println( "流程定义ID:" +pi.getProcessDefinitionId()); //流程定义ID helloworld:1:4 /**查询执行对象ID*/ Execution execution1 = processEngine.getRuntimeService() // .createExecutionQuery() //创建执行对象查询 .processInstanceId(pi.getId()) //使用流程实例ID查询 .activityId( "receivetask1" ) //当前活动的id,对应receiveTask.bpmn文件中的活动节点id的属性值 .singleResult(); /**使用流程变量设置当日销售额,用来传递业务参数*/ processEngine.getRuntimeService() // .setVariable(execution1.getId(), "汇总当日销售额" , 21000); /**向后执行一步,如果流程处于等待状态,使得流程继续执行*/ processEngine.getRuntimeService() .signal(execution1.getId()); /**查询执行对象ID*/ Execution execution2 = processEngine.getRuntimeService() // .createExecutionQuery() //创建执行对象查询 .processInstanceId(pi.getId()) //使用流程实例ID查询 .activityId( "receivetask2" ) //当前活动的id,对应receiveTask.bpmn文件中的活动节点id的属性值 .singleResult(); /**从流程变量中获取汇总当日销售额的值*/ Integer value = (Integer)processEngine.getRuntimeService() // .getVariable(execution2.getId(), "汇总当日销售额" ); System.out.println( "给老板发送短信:金额是:" +value); /**向后执行一步,如果流程处于等待状态,使得流程继续执行*/ processEngine.getRuntimeService() .signal(execution2.getId()); } |
五. 用户任务
流程图:
1. 分配个人任务方式一(直接指定办理人),具体配置:
完成任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | /**查询当前人的个人任务*/ @Test public void findMyPersonalTask(){ String assignee = "周芷若" ; List<Task> list = processEngine.getTaskService() //与正在执行的任务管理相关的Service .createTaskQuery() //创建任务查询对象 /**查询条件(where部分)*/ .taskAssignee(assignee) //指定个人任务查询,指定办理人 // .taskCandidateUser(candidateUser)//组任务的办理人查询 // .processDefinitionId(processDefinitionId)//使用流程定义ID查询 // .processInstanceId(processInstanceId)//使用流程实例ID查询 // .executionId(executionId)//使用执行对象ID查询 /**排序*/ .orderByTaskCreateTime().asc() //使用创建时间的升序排列 /**返回结果集*/ // .singleResult()//返回惟一结果集 // .count()//返回结果集的数量 // .listPage(firstResult, maxResults);//分页查询 .list(); //返回列表 if (list!=null && list.size()>0){ for (Task task:list){ System.out.println( "任务ID:" +task.getId()); System.out.println( "任务名称:" +task.getName()); System.out.println( "任务的创建时间:" +task.getCreateTime()); System.out.println( "任务的办理人:" +task.getAssignee()); System.out.println( "流程实例ID:" +task.getProcessInstanceId()); System.out.println( "执行对象ID:" +task.getExecutionId()); System.out.println( "流程定义ID:" +task.getProcessDefinitionId()); System.out.println( "########################################################" ); } } } /**完成我的任务*/ @Test public void completeMyPersonalTask(){ //任务ID String taskId = "5505" ; processEngine.getTaskService() //与正在执行的任务管理相关的Service .complete(taskId); System.out.println( "完成任务:任务ID:" +taskId); } |
2. 分配个人任务方式二(使用流程变量)
具体配置:
完成任务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 2 启动流程 //启动流程实例的同时,设置流程变量 Map<String, Object> variables = new HashMap<String, Object>(); variables.put( "userID" , "张翠三" ); ProcessInstance pi = processEngine.getRuntimeService() // .startProcessInstanceByKey( "taskProcess" ,variables); System.out.println( "pid:" + pi.getId()); } //查询我的个人任务列表 @Test public void findMyTaskList(){ String userId = "张翠三" ; List<Task> list = processEngine.getTaskService() // .createTaskQuery() // .taskAssignee(userId) //指定个人任务查询 .list(); for (Task task:list ){ System.out.println( "id=" +task.getId()); System.out.println( "name=" +task.getName()); System.out.println( "assinee=" +task.getAssignee()); System.out.println( "createTime=" +task.getCreateTime()); System.out.println( "executionId=" +task.getExecutionId()); } } //完成任务 @Test public void completeTask(){ String taskId = "3209" ; processEngine.getTaskService() // .complete(taskId); // System.out.println( "完成任务" ); } |
作 者: BridgeLi,https://www.bridgeli.cn
原文链接:http://www.bridgeli.cn/archives/229
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。
近期评论