activiti学习9:给用户任务分配权限

大部分的业务流程都会有人的参与,用户任务是最常用的任务,在流程图中使用userTask元素定义用户任务。

当流程到达用户任务时该任务会被分配到特定用户或者用户组,这就是给用户任务分配权限。这个分配权限指的是分配后可以通过activiti提供的任务查询api根据用户或者用户组来查询到这个任务。

一、使用JUEL表达式分配权限

1.1给用户任务分配候选人

这是一个含有一个用户任务的流程图

一个任务可以设置多个候选人,候选人在业务上指的是有权对该任务进行操作的群体。在流程图上使用juel表达式分配候选人的方法如下

 <userTask id="sid-31845D76-A308-4442-AE19-4AA4238DB39A" name="juel表达式分配候选人" activiti:candidateUsers="${candidateUsers}"></userTask>

这里的candidateUsers是一个流程变量,以list的形式存放了候选人列表。

启动流程时创建这样一个流程变量,流程启动后会在任务表中创建一个用户任务,该任务的候选人就是流程变量中传递的这几个值,注意任务和候选人的关系存储在act_ru_identitylink表中

//使用juel表达式指定候选人
        List<String> candidateUsers=new ArrayList<>();
        candidateUsers.add("zhangsan");
        candidateUsers.add("lisi");
        Map<String,Object> variableMap=new HashMap<>();
        variableMap.put("candidateUsers",candidateUsers);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("juel-candidateUser2",variableMap);
        System.out.println(processInstance);

权限分配成功后就可以使用activiti提供的任务查询api来根据候选人查询任务

List<Task> list = taskService.createTaskQuery().taskCandidateUser("lisi").list();
        for (Task task : list) {
            System.out.println(task.getName());
        }

注意这里流程变量中放的值activiti会当做用户id来处理,但这个用户可以不在activiti的用户表中存在,所以可以用来关联自己系统中的用户id

1.2 给用户任务分配候选组

候选组的概念和候选人类似,用来把一个群体的人指定为一个任务的权限人,对应的是activiti中的用户组,分配一个用户组id到某个任务上,可以指定整个组的人为该任务的候选人,在流程图上指定候选组的方式和指定候选人类似

 <userTask id="juel-candidateGroup" name="juel表达式指定候选组" activiti:candidateGroups="${candidateGroup}"></userTask>

这里的candidateGroup也是一个流程变量,其中存放了用户组id的lsit集合

Map<String,Object> map=new HashMap<>();
        List<String> groupList=new ArrayList<>();
        groupList.add("项目经理");
        groupList.add("测试");
        map.put("candidateGroup",groupList);
        runtimeService.startProcessInstanceByKey("juel-candidateGroup2",map);

注意这个用户组在activiti的群组表中可以不存在。

可以使用任务查询api查询群组对应的任务

List<Task> list = taskService.createTaskQuery().taskCandidateGroup("项目经理").list();
        for (Task task : list) {
            System.out.println(task.getName());
        }

1.3 给用户任务分配代理人

和候选人不同,一个用户任务只允许有一个代理人。为一个任务分配代理人后act_ru_task表的ASSIGNEE_字段会被设置为响应的值。设置方法和候选人类似,可以在流程文件中用juel表达式配置

<userTask id="sid-9253B2C0-D7CF-49C9-BE00-3B68D87413D4" name="juel表达式分配代理人" activiti:assignee="${assignee}"></userTask>

assignee也是一个流程变量

 //使用juel表达式指定代理人
        Map<String,Object> map=new HashMap<>();
        map.put("assignee","jerry");
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("juel-assignee",map);
        System.out.println(processInstance);

同样的,流程变量assignee中配置的用户id也可以不在activiti的用户表中。

根据用户任务权限查询api查询任务

List<Task> list = taskService.createTaskQuery().taskAssignee("jerry").list();
        for (Task task : list) {
            System.out.println(task.getName());
        }

与候选人和候选组不同的是,代理人会被设置到任务表act_ru_taskASSIGNEE_字段中


上面的juel表达式中放置的都是一个流程变量,流程变量中存的是集合或者字符串,实际上也可以在流程变量中存一个JavaBean对象,然后在juel表达式中调用这个对象的方法和或者属性,调用属性时需要提供属性的get方法,并且属性要是public的,调用方式如下

${authBean.getAssignee}
${authBean.getCandidateUsers}

二、使用任务监听器给用户任务分配权限

在activiti中可以通过编写自定义的任务监听器,在监听器中进行任务权限分配。

public class AuthListener implements TaskListener {
    @Override
    public void notify(DelegateTask delegateTask) {
        delegateTask.setAssignee("岳不群");
        delegateTask.addCandidateUser("林平之");
        delegateTask.addCandidateUser("令狐冲");
        delegateTask.addCandidateGroup("华山派");
    }
}

自定义任务监听器要实现TaskListener接口,在notify方法中进行权限分配,然后在流程图中配置监听器

<userTask id="sid-B6160828-7BF0-4936-B172-5EE48E8B12C8" name="使用监听器分配权限">
      <extensionElements>
         <activiti:taskListener event="create" class="com.lyy.activiti_listener.AuthListener">            </activiti:taskListener>
      </extensionElements>
</userTask>

其中的event=create表示在创建这个用户任务时执行这个监听

这种方式比juel表达式要灵活些,如果要修改某个任务的权限人规则,不需要重新部署流程图,只需要修改任务监听就可以了。

public void test17(){
        ProcessInstance processInstance = 		            runtimeService.startProcessInstanceByKey("tasklistener-auth");
       System.out.println(processInstance);
    }

三、使用taskService的api分配

如果想在任务创建号了以后改变任务的权限人,可以使用taskService提供的api完成

	taskService.setAssignee("taskId","userId");
    taskService.addCandidateGroup("taskId","groupId");
    taskService.addCandidateUser("taskId","userId");

类似的,如果要删除某个任务的权限人,也可以使用taskService中的api