Activiti个人任务及流程变量
1.Activiti中个人任务分配
1.1分配任务负责人:
1.1.1 固定分配,每一个任务都是固定的人进行执行
1.1.2 表达式分配:
UEL表达式,统一表达式语言,在activiti当中支持两种形式,一种是value,另外一种是method形式
1.1.3 创建流程图,给每一个环节制定assignee值,通过UEL表达式分配任务负责人
/*启动流程*/ public class StartInstance { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //设置流程变量 Hoilday hoilday=new Hoilday(); hoilday.setNum(3); //定义一个map集合,存放assignee的值 Map<String ,Object> assMap=new HashMap<>(); assMap.put("hoilday",hoilday); //启动一个流程实例 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("hoilday2", assMap); System.out.println("流程启动成功!"); } }
1.1.4 注意事项
由于使用表达式分配,必须保证在任务执行过程,表达式执行成功,比如:某个任务使用了表达式${order.price>100 && order.price<250},当执行该任务时必须保证order在流程变量中存在,否则activiti异常;
1.1.5 创建流程实例,制定任务执行人
2. 查询任务
查询任务负责人的代办任务;
/*查看代办任务*/ public class GetTask { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取一个TaskService对象 TaskService taskService = processEngine.getTaskService(); //查询代办业务 createTaskQuery查询任务 taskCandidateOrAssigned查询任务执行者 processDefinitionKey执行查看流程 //查看hoilday流程中zhangsan代办的任务 //taskCandidateOrAssigned匹配规则: 1.Assigned 2.配置bpmn文件中定义的值 /*List<Task> list = taskService.createTaskQuery().taskCandidateOrAssigned("zhangsan").processDefinitionKey("hoilday").list();*/ //taskAssignee查看当前指定人的指定任务 List<Task> list = taskService.createTaskQuery().taskAssignee("zhangsan").processDefinitionKey("hoilday").list(); for (Task task:list){ System.out.println("任务名称:"+task.getName()); System.out.println("任务执行人:"+task.getAssignee()); System.out.println("任务ID:"+task.getId()); System.out.println("流程实例ID:"+task.getProcessInstanceId()); } } }
3. 关联businessKey
在activiti实际应用时,查询待办任务可能要显示出业务系统的一些相关信息,比如:查询待审批请假单任务列表需要将请假单的日期,请假天数等信息显示出来,而并没有在activiti数据库中存在,所以是无法通过activiti的api查询到请假天数等信息;
实现:在查询待办任务时,通过businessKey关联查询业务系统的请假单表,查询出请假天数等信息;
4.办理任务
指定任务ID,调用TaskService完成任务;
/*任务处理 * `act_hi_identitylink` 历史参与者信息 * `act_hi_taskinst` 历史任务信息 * `act_ru_execution` 任务执行信息 * `act_ru_task` 任务信息 * 当所有任务处理完毕,对应当前流程实例信息删除,但是可以在历史中查看该信息 * */ public class CompleteTask { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取TaskService对象进行流程部署 TaskService taskService = processEngine.getTaskService(); //任务处理 taskService.complete("7502"); } }
2.什么是流程变量?
流程变量在activiti中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和activiti结合时少不了流程变量,流程变量就是activiti在管理工作流程时根据管理需要而设置的变量;
比如在请假流程流转时如果请假天数大于3天则由总经理审批,否则有人事直接审批,请假天数就可以设置为流程变量,在流程流转时使用;
注意:虽然流程变量中可以存储业务数据,通过activiti的api查询流程变量从而实现查询业务天数,但是不建议这样使用,因为业务数据查询由业务系统负责,activiti设置流程变量是为了流程执行需要而创建;
流程变量类型
注意:如果将pojo存储到流程变量中,必须实现序列化接口serializable,为了防止由新增字段无法反序列化,需要生成serialVersionUID;
流程变量作用域
流程变量的作用域默认是一个流程实例,也可以是一个任务或一个执行实例,这三个作用域流程实例的范围最大,可以成为global变量,任务和执行实例仅仅是针对一个任务和一个执行实例范围,范围没有流程实例大,称为local变量;
global变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值;local变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响;local变量名也可以和global变量名相同,没有影响;
流程变量的使用方法
设置流程变量
通过UEL表达式使用流程变量
可以在activiti处设置UEL表达式,表达式的值为任务的负责人;
比如:${assignee},assignee就是一个流程变量名称;
activiti获取UEL表达式的值,即流程变量assignee的值,将assignee的值作为任务的负责人进行任务分配;
可以在连线上设置UEL表达式,决定流程走向;
比如:${price>=10000}和${price<10000};price就是一个流程变量名称,UEL表达式结果类型为布尔类型;
如果UEL表达式是true,要巨鼎流程执行走向;
使用global变量控制流程
创建请假审批流程,有部门经理审批,部门经理审批通过后请假三天以下有人事经理直接审批,三天以上先有总经理审批,再有人事经理存档;
设置global流程变量
在部门经理审批前设置流程变量,变量值为请假单信息,部门经理审批后可以根据流程变量的值决定流程走向;
启动流程时设置
在启动流程时设置流程变量,变量的作用域是整个流程实例;
通过Map<key,value>设置流程变量,map中可以设置多个变量,这个key就是流程变量的名字;
/*业务实体*/ public class Hoilday implements Serializable { private Integer id; private String hoildayName; //申请人 private Date startDate; //开始时间 private Date endDate; //结束时间 private Integer num; //请假天数 private String reason; //请假事由 private String type; public String getType() { return type; } public void setType(String type) { this.type = type; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getHoildayName() { return hoildayName; } public void setHoildayName(String hoildayName) { this.hoildayName = hoildayName; } public Date getStartDate() { return startDate; } public void setStartDate(Date startDate) { this.startDate = startDate; } public Date getEndDate() { return endDate; } public void setEndDate(Date endDate) { this.endDate = endDate; } public Integer getNum() { return num; } public void setNum(Integer num) { this.num = num; } public String getReason() { return reason; } public void setReason(String reason) { this.reason = reason; } }
/*流程定义*/ public class StartInstance { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //设置流程变量 Hoilday hoilday=new Hoilday(); hoilday.setNum(3); //定义一个map集合,存放assignee的值 Map<String ,Object> assMap=new HashMap<>(); assMap.put("hoilday",hoilday); //启动一个流程实例 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("hoilday2", assMap); System.out.println("流程启动成功!"); } }
任务办理时设置
在完成任务时设置流程变量,该流程只有在该任务完成后其他节点才可使用该变量,它的作用域是整个流程实例,如果设置的流程变量的key在流程实例中已经存在相同的名字则后设置的变量替换前边设置的变量;
这里需要在创建请假单任务完后时设置流程变量;
/*任务处理 * `act_hi_identitylink` 历史参与者信息 * `act_hi_taskinst` 历史任务信息 * `act_ru_execution` 任务执行信息 * `act_ru_task` 任务信息 * 当所有任务处理完毕,对应当前流程实例信息删除,但是可以在历史中查看该信息 * */ public class CompleteTask { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取TaskService对象进行流程部署 TaskService taskService = processEngine.getTaskService(); //设置流程变量 Hoilday hoilday=new Hoilday(); hoilday.setNum(3); //定义一个map集合,存放assignee的值 Map<String ,Object> assMap=new HashMap<>(); assMap.put("hoilday",hoilday); //任务处理 taskService.complete("7502",assMap); } }
说明:通过当前任务设置流程变量,需要指定当前任务id,如果当前执行的任务ID不存在则抛出异常,任务办理时也是通过map<key,value>设置流程变量,一次可以设置多个变量;
通过当前流程实例设置
通过流程实例ID设置全局变量,该流程实例必须未执行完成;
/*通过当前流程实例设置流程变量*/ public class GlobalVariableByExecutionId { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //设置流程变量 Hoilday hoilday=new Hoilday(); hoilday.setNum(3); runtimeService.setVariable("7502","hoilday",hoilday); } }
注意:流程实例ID必须当前未结束的的,通常此id设置流程实例的ID,也可以通过runtimeService.getVariable()获取流程变量;
通过当前任务设置
/*通过当前任务设置*/ public class GlobalVariableByTask { public static void main(String[] args) { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //设置流程变量 Hoilday hoilday=new Hoilday(); hoilday.setNum(3); //当前代办任务ID runtimeService.setVariable("1404","hoilday",hoilday); } }
注意:任务ID必须是当前代办任务ID,如果该任务已经结束,就会报异常;
注意问题:
1、如果UEL 表达式中流程变量名不存在则报错。
2、如果UEL 表达式中流程变量值为空NULL,流程不按UEL 表达式去执行,而流程结束 。
3、如果UEL 表达式都不符合条件,流程结束
4、如果连线不设置条件,会走flow 序号小的那条线