diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java index f4a5d0d9e..f740ffd4c 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/dataobject/task/BpmTaskExtDO.java @@ -29,7 +29,7 @@ public class BpmTaskExtDO extends BaseDO { private Long id; /** - * 流程任务key + * 流程任务key TODO 芋艿,看看这个字段的作用 */ private String taskDefKey; /** diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java index 70c8c1631..bfc25ade2 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/domain/enums/definition/BpmTaskAssignRuleTypeEnum.java @@ -17,8 +17,6 @@ public enum BpmTaskAssignRuleTypeEnum { DEPT_LEADER(21, "部门的负责人"), POST(22, "岗位"), USER(30, "用户"), - USER_SIGN(31, "用户---会签"), - USER_OR_SIGN(32, "用户---或签"), USER_GROUP(40, "用户组"), SCRIPT(50, "自定义脚本"), // 例如说,发起人所在部门的领导、发起人所在部门的领导的领导 ; diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java index bf2feb840..dd2b8a68e 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/config/BpmFlowableConfiguration.java @@ -2,12 +2,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.config; import cn.hutool.core.collection.ListUtil; import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.BpmActivityBehaviorFactory; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import org.flowable.common.engine.api.delegate.event.FlowableEventListener; import org.flowable.spring.SpringProcessEngineConfiguration; import org.flowable.spring.boot.EngineConfigurationConfigurer; @@ -15,8 +10,6 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.List; - /** * BPM 模块的 Flowable 配置类 * @@ -44,19 +37,10 @@ public class BpmFlowableConfiguration { } @Bean - public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService, - BpmUserGroupService userGroupService, - PermissionApi permissionApi, - DeptApi deptApi, - AdminUserApi adminUserApi, - List scripts) { + public BpmActivityBehaviorFactory bpmActivityBehaviorFactory(BpmTaskAssignRuleService taskRuleService) { BpmActivityBehaviorFactory bpmActivityBehaviorFactory = new BpmActivityBehaviorFactory(); bpmActivityBehaviorFactory.setBpmTaskRuleService(taskRuleService); - bpmActivityBehaviorFactory.setUserGroupService(userGroupService); - bpmActivityBehaviorFactory.setAdminUserApi(adminUserApi); - bpmActivityBehaviorFactory.setPermissionApi(permissionApi); - bpmActivityBehaviorFactory.setDeptApi(deptApi); - bpmActivityBehaviorFactory.setScripts(scripts); return bpmActivityBehaviorFactory; } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java index eb8f91acc..0de96c6e9 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmActivityBehaviorFactory.java @@ -1,11 +1,6 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Setter; @@ -17,8 +12,6 @@ import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.flowable.engine.impl.bpmn.parser.factory.DefaultActivityBehaviorFactory; -import java.util.List; - /** * 自定义的 ActivityBehaviorFactory 实现类,目的如下: * 1. 自定义 {@link #createUserTaskActivityBehavior(UserTask)}:实现自定义的流程任务的 assignee 负责人的分配 @@ -32,41 +25,18 @@ public class BpmActivityBehaviorFactory extends DefaultActivityBehaviorFactory { @Setter private BpmTaskAssignRuleService bpmTaskRuleService; - @Setter - private BpmUserGroupService userGroupService; - - @Setter - private PermissionApi permissionApi; - @Setter - private DeptApi deptApi; - @Setter - private AdminUserApi adminUserApi; - @Setter - private List scripts; @Override public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask) { - BpmUserTaskActivityBehavior userTaskActivityBehavior = new BpmUserTaskActivityBehavior(userTask); - userTaskActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); - userTaskActivityBehavior.setPermissionApi(permissionApi); - userTaskActivityBehavior.setDeptApi(deptApi); - userTaskActivityBehavior.setUserGroupService(userGroupService); - userTaskActivityBehavior.setAdminUserApi(adminUserApi); - userTaskActivityBehavior.setScripts(scripts); - return userTaskActivityBehavior; + return new BpmUserTaskActivityBehavior(userTask) + .setBpmTaskRuleService(bpmTaskRuleService); } @Override public ParallelMultiInstanceBehavior createParallelMultiInstanceBehavior(Activity activity, - AbstractBpmnActivityBehavior innerActivityBehavior) { - BpmParallelMultiInstanceActivityBehavior bpmParallelMultiInstanceActivityBehavior = - new BpmParallelMultiInstanceActivityBehavior(activity, innerActivityBehavior); - bpmParallelMultiInstanceActivityBehavior.setBpmTaskRuleService(bpmTaskRuleService); - bpmParallelMultiInstanceActivityBehavior.setPermissionApi(permissionApi); - bpmParallelMultiInstanceActivityBehavior.setDeptApi(deptApi); - bpmParallelMultiInstanceActivityBehavior.setUserGroupService(userGroupService); - bpmParallelMultiInstanceActivityBehavior.setAdminUserApi(adminUserApi); - bpmParallelMultiInstanceActivityBehavior.setScripts(scripts); - return bpmParallelMultiInstanceActivityBehavior; + AbstractBpmnActivityBehavior innerActivityBehavior) { + return new BpmParallelMultiInstanceBehavior(activity, innerActivityBehavior) + .setBpmTaskRuleService(bpmTaskRuleService); } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceActivityBehavior.java deleted file mode 100644 index 0f92a36f4..000000000 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceActivityBehavior.java +++ /dev/null @@ -1,194 +0,0 @@ -package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; - -import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; -import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import com.google.common.annotations.VisibleForTesting; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import org.flowable.bpmn.model.Activity; -import org.flowable.common.engine.api.FlowableException; -import org.flowable.engine.delegate.DelegateExecution; -import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior; -import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; -import org.flowable.engine.impl.util.CommandContextUtil; - -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; - -/** - * @author kemengkai - * @create 2022-04-21 16:57 - */ -@Slf4j -public class BpmParallelMultiInstanceActivityBehavior extends ParallelMultiInstanceBehavior { - - @Setter - private BpmTaskAssignRuleService bpmTaskRuleService; - @Setter - private BpmUserGroupService userGroupService; - @Setter - private DeptApi deptApi; - @Setter - private AdminUserApi adminUserApi; - @Setter - private PermissionApi permissionApi; - /** - * EL表达式集合模板 - */ - private final static String EXPRESSION_TEXT_TEMPLATE = "${coll_userList}"; - - /** - * 任务分配脚本 - */ - private Map scriptMap = Collections.emptyMap(); - - public BpmParallelMultiInstanceActivityBehavior(Activity activity, - AbstractBpmnActivityBehavior innerActivityBehavior) { - super(activity, innerActivityBehavior); - } - - public void setScripts(List scripts) { - this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); - } - - /** - * 创建并行任务 - * - * @param multiInstanceRootExecution 并行任务入参 - * - * @return 返回结果 - */ - @Override - protected int createInstances(DelegateExecution multiInstanceRootExecution) { - // 查找任务信息 - BpmTaskAssignRuleDO taskRule = getTaskRule(multiInstanceRootExecution); - // 获取任务用户 - Set assigneeUserIds = calculateTaskCandidateUsers(multiInstanceRootExecution, taskRule); - // 设置任务集合变量 - String expressionText = String.format("%s_userList", taskRule.getTaskDefinitionKey()); - // 设置任务集合变量与任务关系 - multiInstanceRootExecution.setVariable(expressionText, assigneeUserIds); - // 设置任务集合EL表达式 - this.collectionExpression = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager() - .createExpression(String.format("${%s}", expressionText)); - // 根据会签,或签类型,设置会签,或签条件 - if (BpmTaskAssignRuleTypeEnum.USER_SIGN.getType().equals(taskRule.getType())) { - // 会签 - this.completionCondition = "${ nrOfInstances == nrOfCompletedInstances }"; - } else { - // 或签 - this.completionCondition = "${ nrOfCompletedInstances == 1 }"; - } - // 设置取出集合变量 - this.collectionElementVariable = "user"; - return super.createInstances(multiInstanceRootExecution); - } - - @Override - protected Object resolveCollection(DelegateExecution execution) { - Object collection = null; - if (EXPRESSION_TEXT_TEMPLATE.equals(this.collectionExpression.getExpressionText())) { - // 查找任务信息 - BpmTaskAssignRuleDO taskRule = getTaskRule(execution); - // 设置任务集合变量 - String expressionText = String.format("%s_userList", execution.getCurrentActivityId()); - // 获取任务用户 - Set assigneeUserIds = calculateTaskCandidateUsers(execution, taskRule); - // 设置任务集合变量与任务关系 - execution.setVariable(expressionText, assigneeUserIds); - // 设置任务集合EL表达式 - this.collectionExpression = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager() - .createExpression(String.format("${%s}", expressionText)); - } - if (this.collectionExpression != null) { - collection = this.collectionExpression.getValue(execution); - } else if (this.collectionVariable != null) { - collection = execution.getVariable(this.collectionVariable); - } else if (this.collectionString != null) { - collection = this.collectionString; - } - - return collection; - } - - private BpmTaskAssignRuleDO getTaskRule(DelegateExecution task) { - List taskRules = - bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(), - task.getCurrentActivityId()); - if (CollUtil.isEmpty(taskRules)) { - throw new FlowableException( - StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则", task.getId(), task.getProcessDefinitionId(), - task.getCurrentActivityId())); - } - if (taskRules.size() > 1) { - throw new FlowableException( - StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})", task.getId(), task.getProcessDefinitionId(), - task.getCurrentActivityId(), taskRules.size())); - } - return taskRules.get(0); - } - - Set calculateTaskCandidateUsers(DelegateExecution task, BpmTaskAssignRuleDO rule) { - Set assigneeUserIds = null; - // if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); - // } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { - // assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); - if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersSignByUser(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersSignByUser(task, rule); - } - - // 移除被禁用的用户 - removeDisableUsers(assigneeUserIds); - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 - if (CollUtil.isEmpty(assigneeUserIds)) { - log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", task.getId(), - task.getProcessDefinitionId(), task.getCurrentActivityId(), toJsonString(rule)); - throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); - } - return assigneeUserIds; - } - - private Set calculateTaskCandidateUsersSignByUser(DelegateExecution task, BpmTaskAssignRuleDO rule) { - return rule.getOptions(); - } - - @VisibleForTesting - void removeDisableUsers(Set assigneeUserIds) { - if (CollUtil.isEmpty(assigneeUserIds)) { - return; - } - //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据 - Map userMap = adminUserApi.getUserMap(assigneeUserIds); - assigneeUserIds.removeIf(id -> { - AdminUserRespDTO user = userMap.get(id); - return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); - }); - } -} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java new file mode 100644 index 000000000..d4c2d86b3 --- /dev/null +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmParallelMultiInstanceBehavior.java @@ -0,0 +1,116 @@ +package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; + +import cn.hutool.core.collection.CollUtil; +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.flowable.bpmn.model.Activity; +import org.flowable.engine.delegate.DelegateExecution; +import org.flowable.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior; +import org.flowable.engine.impl.bpmn.behavior.ParallelMultiInstanceBehavior; +import org.flowable.engine.impl.util.CommandContextUtil; + +import java.util.Set; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; + +/** + * @author kemengkai + * @create 2022-04-21 16:57 + */ +@Slf4j +public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehavior { + + /** + * EL表达式集合模板 + */ + private final static String EXPRESSION_TEXT_TEMPLATE = "${coll_userList}"; + + @Setter + private BpmTaskAssignRuleService bpmTaskRuleService; + + public BpmParallelMultiInstanceBehavior(Activity activity, + AbstractBpmnActivityBehavior innerActivityBehavior) { + super(activity, innerActivityBehavior); + } + + /** + * 创建并行任务 + * + * @param multiInstanceRootExecution 并行任务入参 + * + * @return 返回结果 + */ + @Override + protected int createInstances(DelegateExecution multiInstanceRootExecution) { + // 查找任务信息 +// BpmTaskAssignRuleDO taskRule = getTaskRule(multiInstanceRootExecution); + BpmTaskAssignRuleDO taskRule = null; + // 获取任务用户 + Set assigneeUserIds = calculateTaskCandidateUsers(multiInstanceRootExecution, taskRule); + // 设置任务集合变量 + String expressionText = String.format("%s_userList", taskRule.getTaskDefinitionKey()); + // 设置任务集合变量与任务关系 + multiInstanceRootExecution.setVariable(expressionText, assigneeUserIds); + // 设置任务集合EL表达式 + this.collectionExpression = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager() + .createExpression(String.format("${%s}", expressionText)); + // 根据会签,或签类型,设置会签,或签条件 +// if (BpmTaskAssignRuleTypeEnum.USER_SIGN.getType().equals(taskRule.getType())) { +// // 会签 +// this.completionCondition = "${ nrOfInstances == nrOfCompletedInstances }"; +// } else { +// // 或签 +// this.completionCondition = "${ nrOfCompletedInstances == 1 }"; +// } + // 设置取出集合变量 + this.collectionElementVariable = "user"; + return super.createInstances(multiInstanceRootExecution); + } + + @Override + protected Object resolveCollection(DelegateExecution execution) { + Object collection = null; + if (EXPRESSION_TEXT_TEMPLATE.equals(this.collectionExpression.getExpressionText())) { + // 查找任务信息 +// BpmTaskAssignRuleDO taskRule = getTaskRule(execution); + BpmTaskAssignRuleDO taskRule = null; + // 设置任务集合变量 + String expressionText = String.format("%s_userList", execution.getCurrentActivityId()); + // 获取任务用户 + Set assigneeUserIds = calculateTaskCandidateUsers(execution, taskRule); + // 设置任务集合变量与任务关系 + execution.setVariable(expressionText, assigneeUserIds); + // 设置任务集合EL表达式 + this.collectionExpression = CommandContextUtil.getProcessEngineConfiguration().getExpressionManager() + .createExpression(String.format("${%s}", expressionText)); + } + if (this.collectionExpression != null) { + collection = this.collectionExpression.getValue(execution); + } else if (this.collectionVariable != null) { + collection = execution.getVariable(this.collectionVariable); + } else if (this.collectionString != null) { + collection = this.collectionString; + } + + return collection; + } + + Set calculateTaskCandidateUsers(DelegateExecution task, BpmTaskAssignRuleDO rule) { + Set assigneeUserIds = SetUtils.asSet(1L, 104L); + + // 移除被禁用的用户 + // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 + if (CollUtil.isEmpty(assigneeUserIds)) { + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", task.getId(), + task.getProcessDefinitionId(), task.getCurrentActivityId(), toJsonString(rule)); + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); + } + return assigneeUserIds; + } + +} diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java index 23f2cf9f7..9c31af249 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/flowable/core/behavior/BpmUserTaskActivityBehavior.java @@ -2,25 +2,11 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.RandomUtil; -import cn.hutool.core.util.StrUtil; -import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; -import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; -import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleService; -import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; -import cn.iocoder.yudao.module.system.api.dept.DeptApi; -import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; -import cn.iocoder.yudao.module.system.api.permission.PermissionApi; -import cn.iocoder.yudao.module.system.api.user.AdminUserApi; -import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; -import com.google.common.annotations.VisibleForTesting; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.UserTask; -import org.flowable.common.engine.api.FlowableException; import org.flowable.common.engine.impl.el.ExpressionManager; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.impl.bpmn.behavior.UserTaskActivityBehavior; @@ -29,14 +15,9 @@ import org.flowable.engine.impl.util.TaskHelper; import org.flowable.task.service.TaskService; import org.flowable.task.service.impl.persistence.entity.TaskEntity; -import java.util.*; - -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; -import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS; -import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER; +import java.util.List; +import java.util.Map; +import java.util.Set; /** * 自定义的流程任务的 assignee 负责人的分配 @@ -51,153 +32,24 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { @Setter private BpmTaskAssignRuleService bpmTaskRuleService; - @Setter - private BpmUserGroupService userGroupService; - @Setter - private DeptApi deptApi; - @Setter - private AdminUserApi adminUserApi; - @Setter - private PermissionApi permissionApi; - - /** - * 任务分配脚本 - */ - private Map scriptMap = Collections.emptyMap(); public BpmUserTaskActivityBehavior(UserTask userTask) { super(userTask); } - public void setScripts(List scripts) { - this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); - } - @Override @DataPermission(enable = false) // 不需要处理数据权限, 不然会有问题,查询不到数据 protected void handleAssignments(TaskService taskService, String assignee, String owner, List candidateUsers, List candidateGroups, TaskEntity task, ExpressionManager expressionManager, DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) { - /*boolean isMultiInstance = hasMultiInstanceCharacteristics(); - if (isMultiInstance) { - //多实例 会签/或签,执行多次每个人 待办人都在execution里面获取 - Integer assigneeUserId = execution.getVariableLocal("user", Integer.class); - TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); - } else { - // 第一步,获得任务的规则 - BpmTaskAssignRuleDO rule = getTaskRule(task); - // 第二步,获得任务的候选用户们 - Set candidateUserIds = calculateTaskCandidateUsers(task, rule); - // 第三步,设置一个作为负责人 - Long assigneeUserId = chooseTaskAssignee(execution, candidateUserIds); - TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); - } - */ - // 第一步,获得任务的规则 - BpmTaskAssignRuleDO rule = getTaskRule(task); - // 第二步,获得任务的候选用户们 - Set candidateUserIds = calculateTaskCandidateUsers(task, rule); - // 第三步,设置一个作为负责人 + // 第一步,获得任务的候选用户们 + Set candidateUserIds = bpmTaskRuleService.calculateTaskCandidateUsers(task); + // 第二步,选择一个作为候选人 Long assigneeUserId = chooseTaskAssignee(execution, candidateUserIds); + // 第三步,设置作为负责人 TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId)); } - private BpmTaskAssignRuleDO getTaskRule(TaskEntity task) { - List taskRules = - bpmTaskRuleService.getTaskAssignRuleListByProcessDefinitionId(task.getProcessDefinitionId(), - task.getTaskDefinitionKey()); - if (CollUtil.isEmpty(taskRules)) { - throw new FlowableException( - StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则", task.getId(), task.getProcessDefinitionId(), - task.getTaskDefinitionKey())); - } - if (taskRules.size() > 1) { - throw new FlowableException( - StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})", task.getId(), task.getProcessDefinitionId(), - task.getTaskDefinitionKey(), taskRules.size())); - } - return taskRules.get(0); - } - - Set calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) { - Set assigneeUserIds = null; - if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); - } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType(), rule.getType())) { - assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); - } - - // 移除被禁用的用户 - removeDisableUsers(assigneeUserIds); - // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 - if (CollUtil.isEmpty(assigneeUserIds)) { - log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", task.getId(), - task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule)); - throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); - } - return assigneeUserIds; - } - - private Set calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) { - return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); - } - - private Set calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) { - List users = adminUserApi.getUsersByDeptIds(rule.getOptions()); - return convertSet(users, AdminUserRespDTO::getId); - } - - private Set calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) { - List depts = deptApi.getDepts(rule.getOptions()); - return convertSet(depts, DeptRespDTO::getLeaderUserId); - } - - private Set calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) { - List users = adminUserApi.getUsersByPostIds(rule.getOptions()); - return convertSet(users, AdminUserRespDTO::getId); - } - - private Set calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) { - return rule.getOptions(); - } - - private Set calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) { - List userGroups = userGroupService.getUserGroupList(rule.getOptions()); - Set userIds = new HashSet<>(); - userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); - return userIds; - } - - private Set calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) { - // 获得对应的脚本 - List scripts = new ArrayList<>(rule.getOptions().size()); - rule.getOptions().forEach(id -> { - BpmTaskAssignScript script = scriptMap.get(id); - if (script == null) { - throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); - } - scripts.add(script); - }); - // 逐个计算任务 - Set userIds = new HashSet<>(); - scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task))); - return userIds; - } - private Long chooseTaskAssignee(DelegateExecution execution, Set candidateUserIds) { // 获取任务变量 Map variables = execution.getVariables(); @@ -214,16 +66,4 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior { return CollUtil.get(candidateUserIds, index); } - @VisibleForTesting - void removeDisableUsers(Set assigneeUserIds) { - if (CollUtil.isEmpty(assigneeUserIds)) { - return; - } - //TODO 芋艿 这里有数据权限的问题。默认会加上数据权限 dept_id IN (deptId). 导致查询不到数据 - Map userMap = adminUserApi.getUserMap(assigneeUserIds); - assigneeUserIds.removeIf(id -> { - AdminUserRespDTO user = userMap.get(id); - return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); - }); - } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java index 079451597..1aeb450ad 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleService.java @@ -4,10 +4,12 @@ import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAs import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.lang.Nullable; import javax.validation.Valid; import java.util.List; +import java.util.Set; /** * BPM 任务分配规则 Service 接口 @@ -84,4 +86,6 @@ public interface BpmTaskAssignRuleService { */ void checkTaskAssignRuleAllConfig(String id); + Set calculateTaskCandidateUsers(TaskEntity task); + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java index a091ba753..e8f305c99 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmTaskAssignRuleServiceImpl.java @@ -3,25 +3,35 @@ package cn.iocoder.yudao.module.bpm.service.definition; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; import cn.iocoder.yudao.framework.common.util.object.ObjectUtils; +import cn.iocoder.yudao.framework.datapermission.core.annotation.DataPermission; import cn.iocoder.yudao.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleCreateReqVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleUpdateReqVO; import cn.iocoder.yudao.module.bpm.convert.definition.BpmTaskAssignRuleConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; -import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; import cn.iocoder.yudao.module.system.api.dept.DeptApi; import cn.iocoder.yudao.module.system.api.dept.PostApi; +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.dict.DictDataApi; +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi; import cn.iocoder.yudao.module.system.api.user.AdminUserApi; +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; +import com.google.common.annotations.VisibleForTesting; import lombok.extern.slf4j.Slf4j; import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -31,6 +41,9 @@ import javax.validation.Valid; import java.util.*; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.*; /** @@ -61,6 +74,17 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { private AdminUserApi adminUserApi; @Resource private DictDataApi dictDataApi; + @Resource + private PermissionApi permissionApi; + /** + * 任务分配脚本 + */ + private Map scriptMap = Collections.emptyMap(); + + @Resource + public void setScripts(List scripts) { + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); + } @Override public List getTaskAssignRuleListByProcessDefinitionId(String processDefinitionId, @@ -198,10 +222,6 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { adminUserApi.validUsers(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_GROUP.getType())) { userGroupService.validUserGroups(options); - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_SIGN.getType())) { - adminUserApi.validUsers(options); - } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType())) { - adminUserApi.validUsers(options); } else if (Objects.equals(type, BpmTaskAssignRuleTypeEnum.SCRIPT.getType())) { dictDataApi.validDictDatas(DictTypeConstants.TASK_ASSIGN_SCRIPT, CollectionUtils.convertSet(options, String::valueOf)); @@ -209,4 +229,117 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService { throw new IllegalArgumentException(StrUtil.format("未知的规则类型({})", type)); } } + + @Override + @DataPermission(enable = false) // 忽略数据权限,不然分配会存在问题 + public Set calculateTaskCandidateUsers(TaskEntity task) { + BpmTaskAssignRuleDO rule = getTaskRule(task); + return calculateTaskCandidateUsers(task, rule); + } + + @VisibleForTesting + BpmTaskAssignRuleDO getTaskRule(TaskEntity task) { + List taskRules = getTaskAssignRuleListByProcessDefinitionId( + task.getProcessDefinitionId(), task.getTaskDefinitionKey()); + if (CollUtil.isEmpty(taskRules)) { + throw new FlowableException( + StrUtil.format("流程任务({}/{}/{}) 找不到符合的任务规则", task.getId(), task.getProcessDefinitionId(), + task.getTaskDefinitionKey())); + } + if (taskRules.size() > 1) { + throw new FlowableException( + StrUtil.format("流程任务({}/{}/{}) 找到过多任务规则({})", task.getId(), task.getProcessDefinitionId(), + task.getTaskDefinitionKey(), taskRules.size())); + } + return taskRules.get(0); + } + + @VisibleForTesting + Set calculateTaskCandidateUsers(TaskEntity task, BpmTaskAssignRuleDO rule) { + Set assigneeUserIds = null; + if (Objects.equals(BpmTaskAssignRuleTypeEnum.ROLE.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByRole(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByDeptMember(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByDeptLeader(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.POST.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByPost(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByUser(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByUserGroup(task, rule); + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.SCRIPT.getType(), rule.getType())) { + assigneeUserIds = calculateTaskCandidateUsersByScript(task, rule); + } + + // 移除被禁用的用户 + removeDisableUsers(assigneeUserIds); + // 如果候选人为空,抛出异常 TODO 芋艿:没候选人的策略选择。1 - 挂起;2 - 直接结束;3 - 强制一个兜底人 + if (CollUtil.isEmpty(assigneeUserIds)) { + log.error("[calculateTaskCandidateUsers][流程任务({}/{}/{}) 任务规则({}) 找不到候选人]", task.getId(), + task.getProcessDefinitionId(), task.getTaskDefinitionKey(), toJsonString(rule)); + throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER); + } + return assigneeUserIds; + } + + private Set calculateTaskCandidateUsersByRole(TaskEntity task, BpmTaskAssignRuleDO rule) { + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); + } + + private Set calculateTaskCandidateUsersByDeptMember(TaskEntity task, BpmTaskAssignRuleDO rule) { + List users = adminUserApi.getUsersByDeptIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } + + private Set calculateTaskCandidateUsersByDeptLeader(TaskEntity task, BpmTaskAssignRuleDO rule) { + List depts = deptApi.getDepts(rule.getOptions()); + return convertSet(depts, DeptRespDTO::getLeaderUserId); + } + + private Set calculateTaskCandidateUsersByPost(TaskEntity task, BpmTaskAssignRuleDO rule) { + List users = adminUserApi.getUsersByPostIds(rule.getOptions()); + return convertSet(users, AdminUserRespDTO::getId); + } + + private Set calculateTaskCandidateUsersByUser(TaskEntity task, BpmTaskAssignRuleDO rule) { + return rule.getOptions(); + } + + private Set calculateTaskCandidateUsersByUserGroup(TaskEntity task, BpmTaskAssignRuleDO rule) { + List userGroups = userGroupService.getUserGroupList(rule.getOptions()); + Set userIds = new HashSet<>(); + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); + return userIds; + } + + private Set calculateTaskCandidateUsersByScript(TaskEntity task, BpmTaskAssignRuleDO rule) { + // 获得对应的脚本 + List scripts = new ArrayList<>(rule.getOptions().size()); + rule.getOptions().forEach(id -> { + BpmTaskAssignScript script = scriptMap.get(id); + if (script == null) { + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); + } + scripts.add(script); + }); + // 逐个计算任务 + Set userIds = new HashSet<>(); + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(task))); + return userIds; + } + + @VisibleForTesting + void removeDisableUsers(Set assigneeUserIds) { + if (CollUtil.isEmpty(assigneeUserIds)) { + return; + } + Map userMap = adminUserApi.getUserMap(assigneeUserIds); + assigneeUserIds.removeIf(id -> { + AdminUserRespDTO user = userMap.get(id); + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); + }); + } + } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index baaca08d8..a2f8c8909 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -15,7 +15,6 @@ import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmActivityMapper; import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.domain.enums.task.BpmProcessInstanceResultEnum; import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService; import cn.iocoder.yudao.module.business.hi.task.inst.service.HiTaskInstService; @@ -214,11 +213,12 @@ public class BpmTaskServiceImpl implements BpmTaskService { taskAssignRuleMapper.selectListByProcessDefinitionId(task.getProcessDefinitionId(), task.getTaskDefinitionKey()); if (CollUtil.isNotEmpty(bpmTaskAssignRuleList) && bpmTaskAssignRuleList.size() > 0) { - if (BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType().equals(bpmTaskAssignRuleList.get(0).getType())) { - taskExtMapper.delTaskByProcInstIdAndTaskIdAndTaskDefKey( - new BpmTaskExtDO().setTaskId(task.getId()).setTaskDefKey(task.getTaskDefinitionKey()) - .setProcessInstanceId(task.getProcessInstanceId())); - } + // edit by 芋艿 +// if (BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType().equals(bpmTaskAssignRuleList.get(0).getType())) { +// taskExtMapper.delTaskByProcInstIdAndTaskIdAndTaskDefKey( +// new BpmTaskExtDO().setTaskId(task.getId()).setTaskDefKey(task.getTaskDefinitionKey()) +// .setProcessInstanceId(task.getProcessInstanceId())); +// } } } diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java index 56c854563..40751b227 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/business/hi/task/inst/service/HiTaskInstService.java @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskTodoPage import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO; import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper; -import cn.iocoder.yudao.module.bpm.domain.enums.definition.BpmTaskAssignRuleTypeEnum; import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService; import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO; import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; @@ -21,14 +20,18 @@ import org.flowable.common.engine.impl.de.odysseus.el.ExpressionFactoryImpl; import org.flowable.common.engine.impl.de.odysseus.el.util.SimpleContext; import org.flowable.common.engine.impl.javax.el.ExpressionFactory; import org.flowable.common.engine.impl.javax.el.ValueExpression; -import org.flowable.engine.*; +import org.flowable.engine.HistoryService; +import org.flowable.engine.RepositoryService; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.variable.api.history.HistoricVariableInstance; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import java.util.function.Function; import java.util.stream.Collectors; @@ -259,10 +262,11 @@ public class HiTaskInstService { DeptDO deptDO = deptMap.get(adminUserDO.getDeptId()); bpmTaskRespVO.setAssigneeUser(setUser(adminUserDO)); bpmTaskRespVO.getAssigneeUser().setDeptName(deptDO.getName()); - if (!bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType()) - && !bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType())) { - break; - } + // edit by 芋艿 +// if (!bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_OR_SIGN.getType()) +// && !bpmTaskAssignRuleDO.getType().equals(BpmTaskAssignRuleTypeEnum.USER_SIGN.getType())) { +// break; +// } } } getFlow(bpmnModel, nextTaskDefKey, tmpBpmTaskAssignRuleDOList, bpmTaskRespVOList, userDoMap, deptMap, diff --git a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmActivityMapper.xml b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmActivityMapper.xml index d26183569..37ae2a225 100644 --- a/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmActivityMapper.xml +++ b/yudao-module-bpm/yudao-module-bpm-biz/src/main/resources/mapper/BpmActivityMapper.xml @@ -21,6 +21,7 @@ SELECT * FROM act_hi_taskinst; +