个人任务
个人任务指某个任务就只能被一个人查看,前面的学习都是在流程图中指定assignee属性值的。实际开发中,肯定不会是这样的。以下我们来学习如何动态的指定办理人。
1. 通过流程变量指定办理人
启动流程实例
String processDefinitionKey = "personalTask";
Map<String, Object> variables = new HashMap<>();
variables.put("assignee", "张三"); //设置流程变量
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey,variables);
查询张三的任务
String userId = "张三";
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()
.taskAssignee(userId) //where 办理人字段=张三
.orderByTaskCreateTime().desc() //按任务创建时间倒序排列
.list();
张三完成任务
String taskId = "2505";
Map<String, Object> variables = new HashMap<>();
variables.put("assignee", "李四"); //设置下一个办理人
processEngine.getTaskService().complete(taskId,variables);
李四完成任务
2. 通过监听器指定办理人
为任务节点添加create事件的监听类,通过delegateTask设置办理人
//监听类,省略部分代码,监听器的使用请查询我前面的例子
public void notify(DelegateTask delegateTask) {
delegateTask.setAssignee("张三");
}
3. 修改办理人
String taskId = "15004"; //需要知道任务id
String userId = "王五"; //修改任务办理人为王五
TaskService taskService = processEngine.getTaskService();
taskService.setAssignee(taskId, userId); //无须关系原办理人是否存在,调用setAssignee就能修改
多用户任务
多用户任务就是一个任务多个人可以查看,但是最终处理任务的人只有一个。
1. 使用流程变量指定多个办理人
启动流程实例
String processDefinitionKey = "personalTask2";
Map<String, Object> variables = new HashMap<>();
variables.put("users", "张三,李四,王五"); //设置多个任务办理人,以逗号分隔
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey,variables);
多用户查询自己的任务
String candidateUser = "张三"; //候选人,张三、李四、王五都可以查到任务
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()
//.taskAssignee(assignee) 这时候不能用Assignee,查不到的
.taskCandidateUser(candidateUser) //where 候选人=张三
.orderByTaskCreateTime().desc() //按任务创建时间倒序排列
.list();
for (Task task : list) {
System.out.println("任务名称:" + task.getName());
System.out.println("办理人:" + task.getAssignee());
}
查询正在执行多用户任务的人员名单
String taskId = "5005"; //使用任务id查候选人列表
List<IdentityLink> list = processEngine.getTaskService().getIdentityLinksForTask(taskId);
//使用实例id查参与者列表
//List<IdentityLink> list = processEngine.getRuntimeService().getIdentityLinksForProcessInstance(instanceId);
for(IdentityLink identityLink:list ){
System.out.println("userid="+identityLink.getUserId());
}
查询历史多用户任务的人员名单
String taskId = "5005";
List<HistoricIdentityLink> list = processEngine.getHistoryService().getHistoricIdentityLinksForTask(taskId);
//List<HistoricIdentityLink> list = processEngine.getHistoryService().getHistoricIdentityLinksForProcessInstance(processInstanceId);
for(HistoricIdentityLink identityLink:list ){
System.out.println("userId="+identityLink.getUserId());
}
拾取任务,简单的说就是指定真正的办理人,由多用户任务变为个人任务
String taskId = "5005";
String userId = "马龙"; //由马龙处理,这里可以指定任何人处理,并非一定是原名单内的人
processEngine.getTaskService().claim(taskId, userId);
拾取任务后,一旦assignee字段有值后,张三、李四、王五就不会再查到该条任务了
如何恢复多用户任务?
String taskId = "5005";
TaskService taskService = processEngine.getTaskService();
taskService.setAssignee(taskId, null); //将个人任务恢复到多用户任务
//这里不再演示了,知道就好
马龙完成任务
String taskId = "5005";
Map<String, Object> variables = new HashMap<>();
variables.put("users", "赵发,陈单"); //设置下一个组办理人
processEngine.getTaskService().complete(taskId,variables);
重复上述步骤直到完成
最终act_ru_task、act_ru_identitylink表无记录,act_hi_identitylink会记录历史
2.使用监听器设置组任务
为任务节点添加create事件的监听类,通过delegateTask设置组候选人
//监听类,省略部分代码,监听器的使用请查询我前面的例子
public void notify(DelegateTask delegateTask) {
delegateTask.addCandidateUser("张三");
delegateTask.addCandidateUser("李四");
delegateTask.addCandidateUser("王五");
}
组任务(角色)
某一个审批任务节点可以分配一个组,然后属于这个组的任何一个用户都可以去完成这个任务节点的审批。在activiti的数据表中,有4张表结构是为组任务设计的,用户表、用户信息表、用户组表、用户和角色关系表。在实际开发中一般用的是自己的一套用户角色体系,这里以两种不同的场景,演示如何使用组任务。
场景一:使用activiti自带的用户体系创建组任务
1.部署流程定义
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("groupTaskDemo")
.addClasspathResource("diagrams/groupTask.bpmn")
.deploy();
IdentityService identityService = processEngine.getIdentityService(); //使用用户身份相关的Service
identityService.saveGroup(new GroupEntity("部门经理")); //创建组,对应数据表act_id_group
//创建用户,对应数据表act_id_user
identityService.saveUser(new UserEntity("张三"));
identityService.saveUser(new UserEntity("李四"));
identityService.saveUser(new UserEntity("王五"));
identityService.createMembership("李四", "部门经理"); //创建用户和组的关系,对应数据表act_id_membership
2.启动流程实例
//省略启动代码,启动后的数据表如下
3.查询任务
String candidateUser = "李四"; //候选人
List<Task> list = processEngine.getTaskService()
.createTaskQuery()
//由于我们已经插入了用户与组的关系,所以使用api查询时,会进行任务、组、用户之间的关联查询
.taskCandidateUser(candidateUser)
.orderByTaskCreateTime().asc()
.list();
4.拾取任务
String taskId = "2504";
String userId = "李四";
processEngine.getTaskService().claim(taskId, userId); //只要不是个人任务都需要拾取任务
5.完成任务(省略代码)
场景二:使用我们自己的角色创建组任务(还是同一个流程图的设置)
1.部署流程定义
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("groupTaskDemo")
.addClasspathResource("diagrams/groupTask.bpmn")
.deploy();
//不需要插入act_id_group等表的数据
2.启动流程实例
//省略启动代码
3.查询任务
String processInstanceId = "2501"; //根据实例id查询,这里可以根据应用系统自己的用户角色判断,谁拥有查询权限
Task task = processEngine.getTaskService().createTaskQuery()
.processInstanceId(processInstanceId)
.taskCandidateGroup("部门经理") //这里换成按组查询
.taskDefinitionKey("usertask1") //对应流程图中节点的id值
.active() //这个是状态,对应act_ru_task.SUSPENSION_STATE_,有两个值,活跃或暂停,根据实际情况带不带这个值查询
.singleResult();
4.拾取任务、完成任务......(省略代码类同,不再演示)