houzhongyi
2024-07-11 e7c1260db32209a078a962aaa0ad5492c35774fb
提交 | 用户 | 时间
e7c126 1 package com.iailab.module.bpm.framework.flowable.core.behavior;
H 2
3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.lang.Assert;
5 import cn.hutool.core.util.RandomUtil;
6 import com.iailab.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
7 import lombok.Setter;
8 import lombok.extern.slf4j.Slf4j;
9 import org.flowable.bpmn.model.UserTask;
10 import org.flowable.common.engine.impl.el.ExpressionManager;
11 import org.flowable.engine.delegate.DelegateExecution;
12 import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior;
13 import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
14 import org.flowable.engine.impl.util.TaskHelper;
15 import org.flowable.task.service.TaskService;
16 import org.flowable.task.service.impl.persistence.entity.TaskEntity;
17
18 import java.util.List;
19 import java.util.Set;
20
21 /**
22  * 自定义的【单个】流程任务的 assignee 负责人的分配
23  * 第一步,基于分配规则,计算出分配任务的【单个】候选人。如果找不到,则直接报业务异常,不继续执行后续的流程;
24  * 第二步,随机选择一个候选人,则选择作为 assignee 负责人。
25  *
26  * @author iailab
27  */
28 @Slf4j
29 public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
30
31     @Setter
32     private BpmTaskCandidateInvoker taskCandidateInvoker;
33
34     public BpmUserTaskActivityBehavior(UserTask userTask) {
35         super(userTask);
36     }
37
38     @Override
39     protected void handleAssignments(TaskService taskService, String assignee, String owner,
40         List<String> candidateUsers, List<String> candidateGroups, TaskEntity task, ExpressionManager expressionManager,
41         DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
42         // 第一步,获得任务的候选用户
43         Long assigneeUserId = calculateTaskCandidateUsers(execution);
44         Assert.notNull(assigneeUserId, "任务处理人不能为空");
45         // 第二步,设置作为负责人
46         TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
47     }
48
49     private Long calculateTaskCandidateUsers(DelegateExecution execution) {
50         // 情况一,如果是多实例的任务,例如说会签、或签等情况,则从 Variable 中获取。
51         // 顺序审批可见 BpmSequentialMultiInstanceBehavior,并发审批可见 BpmSequentialMultiInstanceBehavior
52         if (super.multiInstanceActivityBehavior != null) {
53             return execution.getVariable(super.multiInstanceActivityBehavior.getCollectionElementVariable(), Long.class);
54         }
55
56         // 情况二,如果非多实例的任务,则计算任务处理人
57         // 第一步,先计算可处理该任务的处理人们
58         Set<Long> candidateUserIds = taskCandidateInvoker.calculateUsers(execution);
59         // 第二步,后随机选择一个任务的处理人
60         // 疑问:为什么一定要选择一个任务处理人?
61         // 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。
62         //      如果希望一个任务可以同时被多个人处理,可以考虑使用 BpmParallelMultiInstanceBehavior 实现的会签 or 或签。
63         int index = RandomUtil.randomInt(candidateUserIds.size());
64         return CollUtil.get(candidateUserIds, index);
65     }
66
67 }