Activiti6.0 用户任务分配方式总结(单人任务、多人任务)


Activiti以三种方式设置节点处理人,分别是:

  • Assignment:办理人,指定唯一一个。

  • Candidate users:候选人,可以指定多个人。

  • Candidate groups:候选组,可以指定多个组。

单人任务

单个用户方式

1. 在流程图中对任务节点进行配置,直接指定接收任务用户

img

直接在bpmn文件中显式指定

启动流程查看userTask任务的指定人为张三丰

img

act_ru_task表

缺点:硬式编码,将任务分配的用户写死了


2. 在流程图中对任务节点进行配置,通过流程变量方式指定接收任务的用户

img

可以在流程启动或者其他时候指定该任务的处理用户

        //启动流程
        ProcessEngine processEngine = getProcessEngine();
        RuntimeService runtimeService = processEngine.getRuntimeService();

        //流程启动时设置流程变量
        Map<String,Object> variables = new HashMap<String, Object>();
        variables.put("userId","周芷若");
        runtimeService.startProcessInstanceByKey("testUserAssignee",variables);

查看数据库中任务节点的assignee

img

act_ru_task表


3. 在流程定义中,userTask节点的assignee什么也不配,通过指定一个任务监听器,在监听器中动态指定
  • 任务监听器需要实现TaskListener接口

bpmn流程配置

   <userTask activiti:exclusive="true" id="userTask" name="审批">
      <extensionElements>
        <activiti:taskListener class="cn.cf.activiti.atguigu.AssigneeTaskUser" event="create"/>
      </extensionElements>
    </userTask>

监听类

public class AssigneeTaskUser implements TaskListener {
    public void notify(DelegateTask delegateTask) {
        delegateTask.setAssignee("金毛狮王");
    }
}

启动流程,查看数据库中任务节点的处理人

img

act_ru_task.png

可以在任务已经分配给指定用户的情况下,通过taskService.setAssignee(taskId,userId);重新指定办理人


多人任务

会有个签收任务的概念。只要任务还未被签收,候选组内的任意用户都可以签收该任务;一旦任务被签收,候选组内的其他用户就无法查看与签收该任务咯。

在这里插入图片描述

一、多人任务分配方式

所谓组任务,也就是任务的候选人,候选人中的用户有权认领该任务并且完成该任务,当任务被领取之后,其他候选人即无法再看到此任务。
当用户认领任务时,就算该用户不在候选人列表中,依然可以认领任务

涉及的数据库表有:

  • act_ru_identitylink 表存放任务的办理人,包括个人任务和组任务,表示正在执行的任务

  • act_hi_identitylink 表存放任务的办理人,包括个人任务和组任务,表示历史任务

通过表中的TYPE_字段进行区分用户是办理人还是候选人。在个人任务中(即通过assignee指定),该字段的值为participant(参与者),如果是组任务(即通过candidateUser or candidateGroup指定),TYPE_可以是participant也可以是candidate(候选人)

  • 分配方式同上三种配置方式
1. 在bpmn流程定义文件中直接写 candidate-users=“小A,小B,小C,小D"
2. 在bpmn流程定义文件中写 candidate-users =“#{userIDs}”,变量的值要是String的。使用流程变量指定办理人
 Map<String, Object> variables = new HashMap<String, Object>();
 variables.put("userIDs", "大大,小小,中中");
3. 使用TaskListener接口,使用类实现该接口
//为用户任务添加候选人(可以连续添加多个)
delegateTask.addCandidateUser(userId1);
delegateTask.addCandidateUser(userId2);

二、组任务分配方式

在这里插入图片描述

使用 candidate groups 属性指定 任务组,其中部门经理表示一个用户组的角色

先建立人员组关系
	    设置组任务的办理人,向Activity表中存放组和用户的信息
		IdentityService identityService = processEngine.getIdentityService();//认证:保存组和用户信息
		identityService.saveGroup(new GroupEntity("部门经理"));//建立组
		identityService.saveGroup(new GroupEntity("总经理"));//建立组
		identityService.saveUser(new UserEntity("小张"));
		identityService.saveUser(new UserEntity("小李"));
		identityService.saveUser(new UserEntity("小王"));
		identityService.createMembership("小张", "部门经理");//建立组和用户关系
		identityService.createMembership("小李", "部门经理");//建立组和用户关系
		identityService.createMembership("小王", "总经理");//建立组和用户关系

表结构介绍

act_id_group:角色组表

act_id_user:用户表

act_id_membership:用户角色表

  • 创建用户

    User user = identityService.newUser(userId);
    user.setFirstName("Deniro");
    user.setLastName("Lee");
    user.setEmail("xxx@163.com");
    identityService.saveUser(user);
    
  • 创建组

    //新建组对象
    Group group = identityService.newGroup(groupId);
    group.setName("部门领导");
    group.setType("assignment");
    
    //保存
    identityService.saveGroup(group);
    
  • 关联组和用户

    //把用户加到指定组
    identityService.createMembership(userId, groupId);
    
    //查询指定组下的用户
    User userInGroup = identityService.createUserQuery().memberOfGroup(groupId).singleResult();
    
    //查询指定用户下的组
    Group groupContainUser = identityService.createGroupQuery().groupMember(userId).singleResult();
    
查询组待签任务列表
String userId = "小李";//小张,小李可以查询结果,小王不可以,因为他不是部门经理
		List<Task> list = processEngine.getTaskService()//
		                .createTaskQuery()//
		                .taskCandidateUser(userId)//指定组任务查询
		                .list();
查询组任务成员列表
	String taskId = "4408";
		List<IdentityLink> list = processEngine.getTaskService()//
		                .getIdentityLinksForTask(taskId);
		for(IdentityLink identityLink:list ){
			System.out.println("userId="+identityLink.getUserId());
			System.out.println("taskId="+identityLink.getTaskId());
			System.out.println("piId="+identityLink.getProcessInstanceId());
			System.out.println("######################");
		}

扩展

查询下组参与人员的任务:
processEngine.getTaskService().createTaskQuery().taskCandidateUser(assignee)//参与者,组任务查询
组任务分配给个人任务(认领任务):
processEngine.getTaskService().claim(taskId, userId);
个人任务分配给组任务:被认领之后的任务可再扯回组任务(前提:之前这个任务是组任务),其他人员则还可以认领:
processEngine.getTaskService(). setAssignee(taskId, null);
向组任务添加人员:组任务可以继续添加组参与人员:
processEngine.getTaskService().addCandidateUser(taskId, userId);
向组任务删除人员:组任务可以删除参与人员:
processEngine.getTaskService().deleteCandidateUser(taskId, userId);
查询正在执行的组任务列表:
List<IdentityLink>list = processEngine.getTaskService().getIdentityLinksForTask(taskId);

补充:claim与setAssignee区别在于claim领取之后别人不可以再领取不然会报错而setAssignee则不然


加群一起抱团取暖,共同进步

🍎QQ群【837324215】
🍎关注我的公众号【Java大厂面试官】,一起学习呗🍎🍎🍎
🍎个人vxlakernote

img

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lakernote

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值