transition: 流转。
通过transition把流程的各个活动连接起来。
1、关于transition
1)start活动只能有一个transition
2)end活动没有transition
3)其他活动可以有一条或多条transition
4)如果某个活动只有一个transition,可以不指定transition的名称;如果某个活动有多个transition,需要分别指定唯一的名称
2、使用transition
如果某个活动有多个transition,在处理完成任务时,需要手工指定下一步的transition。
1)先看一下报销的流程
1.1)流程图
1.2)定义文件
<?xml version="1.0" encoding="UTF-8"?> <process name="Reimbursement" xmlns="http://jbpm.org/4.4/jpdl"> <start name="start1" g="110,16,48,48"> <transition name="to 提交报销单" to="提交报销单" g="-79,-20"/> </start> <end name="end1" g="110,393,48,48"/> <task name="提交报销单" g="88,96,92,52" assignee="员工A"> <transition name="to 部门经理审批" to="部门经理审批" g="-91,-20"/> </task> <task name="部门经理审批" g="88,180,92,52" assignee="部门经理B"> <transition name="to 总经理审批" to="总经理审批" g="-38,-8"/> <transition name="to 财务拨款" to="财务拨款" g="-67,-20"/> </task> <task name="总经理审批" g="271,264,92,52" assignee="总经理C"> <transition name="to 财务拨款" to="财务拨款" g="-34,-10"/> </task> <task name="财务拨款" g="86,299,92,52" assignee="财务D"> <transition name="to end1" to="end1" g="-45,-20"/> </task> </process>
2)手工指定下一步的transition
在部门经理审批节点,有两个transition,在部门经理B审批完成后,需要指定下一步的transition。
2.1)没有指定transition
//处理待办 @Test public void testCompleteTask() { String userId = "部门经理B"; List<Task> tasks = processEngine.getTaskService().findPersonalTasks(userId); for(Task task : tasks) { processEngine.getTaskService().completeTask(task.getId());//没有指定transition } }
上面的代码在完成任务的时候没有指定transition,会报错:org.jbpm.api.JbpmException: No unnamed transitions were found for the task '部门经理审批'。
2.2)完成任务时指定transition
//处理待办 @Test public void testCompleteTask() { String userId = "部门经理B"; List<Task> tasks = processEngine.getTaskService().findPersonalTasks(userId); for(Task task : tasks) { String transition = "to 总经理审批"; //String transition = "to 财务拨款"; processEngine.getTaskService().completeTask(userId, transition);//指定transition } }
比如当报销金额>=5000元时,指定下一步是总经理审批;当报销金额<5000元时,指定下一步是财务拨款。
3、在实际使用中,会在页面上把下一步的transition列出来,让用户选择流转。
decision:决定性判断。
根据条件自动在多个流转路径中选择其一通过。
decision可以有多个流出转移,当流程实例到达decision活动时,会根据最先匹配成功的一个条件通过相应的流出转移。
decision和transition的区别是:decision根据条件自动选择转移路径,只使用transition则需要手工指定转移路径。
1、看一下使用decision的报销流程
1)流程定义图
2)流程定义文件
<?xml version="1.0" encoding="UTF-8"?> <process name="Reimbursement" xmlns="http://jbpm.org/4.4/jpdl"> <start name="start1" g="110,16,48,48"> <transition name="to 提交报销单" to="提交报销单" g="-79,-20"/> </start> <end name="end1" g="117,439,48,48"/> <task name="提交报销单" g="88,96,92,52" assignee="员工A"> <transition name="to 部门经理审批" to="部门经理审批" g="-91,-20"/> </task> <task name="部门经理审批" g="88,180,92,52" assignee="部门经理B"> <transition name="to exclusive1" to="exclusive1" g="-70,-11"/> </task> <decision name="exclusive1" g="110,264,48,48"> <handler class="cn.luxh.jbpm4.handler.MoneyDecisionHander" /> <transition name="to 财务拨款" to="财务拨款" g="-67,-20"/> <transition name="to 总经理审批" to="总经理审批" g="-34,-18"/> </decision> <task name="财务拨款" g="92,362,92,44" assignee="财务D"> <transition name="to end1" to="end1" g="-45,-20"/> </task> <task name="总经理审批" g="240,301,92,52" assignee="总经理C"> <transition name="to 财务拨款" to="财务拨款" g="-42,-20"/> </task> </process>
在decision活动处加了一个MoneyDecisionHandler处理类去自动判断金额。
2、MoneyDecisionHandler处理类
MoneyDecisionHandler处理类需要实现DecisionHandler接口。
package cn.luxh.jbpm4.handler; import org.jbpm.api.jpdl.DecisionHandler; import org.jbpm.api.model.OpenExecution; /** * 金额判断 * @author Luxh */ public class MoneyDecisionHander implements DecisionHandler { @Override public String decide(OpenExecution execution) { System.out.println("执行金额判断handler"); //从流程变量中获取提交报销单时的报销金额 int money = (Integer) execution.getVariable("money"); if(money>=5000) { return "to 总经理审批"; }else { return "to 财务拨款"; } } }
3、在提交申请单时,把报销金额存到流程变量中
@Test public void testCompleteTask() { String userId = "员工A"; List<Task> tasks = processEngine.getTaskService().findPersonalTasks(userId); System.out.println("tasks.size---"+tasks.size()); for(Task task : tasks) { Map<String,Integer> variables = new HashMap<String, Integer>(); variables.put("money", 6000); //提交报销单时把报销金额存到流程变量中 processEngine.getTaskService().setVariables(task.getId(), variables); processEngine.getTaskService().completeTask(task.getId()); } }