Commit e21c262bd7e3ed687b5aa1f640ecdec7066dd352
1 parent
5ae1d0ab
refactor: 重构查找候选人的逻辑
Showing
12 changed files
with
797 additions
and
0 deletions
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/candidate/vo/BpmTaskCandidateVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; | |
| 4 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 5 | +import lombok.Data; | |
| 6 | + | |
| 7 | +import javax.validation.constraints.NotNull; | |
| 8 | +import java.util.Set; | |
| 9 | + | |
| 10 | +/** | |
| 11 | + * 流程任务分配规则 Base VO,提供给添加、修改、详细的子 VO 使用 | |
| 12 | + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 | |
| 13 | + * | |
| 14 | + * @see BpmTaskAssignRuleBaseVO | |
| 15 | + */ | |
| 16 | +@Data | |
| 17 | +public class BpmTaskCandidateVO { | |
| 18 | + | |
| 19 | + @Schema(description = "规则类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "bpm_task_assign_rule_type") | |
| 20 | + @NotNull(message = "规则类型不能为空") | |
| 21 | + private Integer type; | |
| 22 | + | |
| 23 | + @Schema(description = "规则值数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "1,2,3") | |
| 24 | + @NotNull(message = "规则值数组不能为空") | |
| 25 | + private Set<Long> options; | |
| 26 | + | |
| 27 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmCandidateProcessorConfiguration.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.framework.bpm.config; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 4 | +import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.*; | |
| 5 | +import org.springframework.beans.factory.ObjectProvider; | |
| 6 | +import org.springframework.context.annotation.Bean; | |
| 7 | +import org.springframework.context.annotation.Configuration; | |
| 8 | + | |
| 9 | +import java.util.List; | |
| 10 | + | |
| 11 | +/** | |
| 12 | + * BPM 通用的 Configuration 配置类,提供给 Activiti 和 Flowable | |
| 13 | + * @author kyle | |
| 14 | + */ | |
| 15 | +@Configuration(proxyBeanMethods = false) | |
| 16 | +public class BpmCandidateProcessorConfiguration { | |
| 17 | + @Bean | |
| 18 | + public BpmCandidateAdminUserApiSourceInfoProcessor bpmCandidateAdminUserApiSourceInfoProcessor() { | |
| 19 | + return new BpmCandidateAdminUserApiSourceInfoProcessor(); | |
| 20 | + } | |
| 21 | + | |
| 22 | + @Bean | |
| 23 | + public BpmCandidateDeptApiSourceInfoProcessor bpmCandidateDeptApiSourceInfoProcessor() { | |
| 24 | + return new BpmCandidateDeptApiSourceInfoProcessor(); | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Bean | |
| 28 | + public BpmCandidatePostApiSourceInfoProcessor bpmCandidatePostApiSourceInfoProcessor() { | |
| 29 | + return new BpmCandidatePostApiSourceInfoProcessor(); | |
| 30 | + } | |
| 31 | + | |
| 32 | + @Bean | |
| 33 | + public BpmCandidateRoleApiSourceInfoProcessor bpmCandidateRoleApiSourceInfoProcessor() { | |
| 34 | + return new BpmCandidateRoleApiSourceInfoProcessor(); | |
| 35 | + } | |
| 36 | + | |
| 37 | + @Bean | |
| 38 | + public BpmCandidateUserGroupApiSourceInfoProcessor bpmCandidateUserGroupApiSourceInfoProcessor() { | |
| 39 | + return new BpmCandidateUserGroupApiSourceInfoProcessor(); | |
| 40 | + } | |
| 41 | + | |
| 42 | + /** | |
| 43 | + * 可以自己定制脚本,然后通过这里设置到处理器里面去 | |
| 44 | + * @param scriptsOp | |
| 45 | + * @return | |
| 46 | + */ | |
| 47 | + @Bean | |
| 48 | + public BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor(ObjectProvider<BpmTaskAssignScript> scriptsOp) { | |
| 49 | + BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor = new BpmCandidateScriptApiSourceInfoProcessor(); | |
| 50 | + bpmCandidateScriptApiSourceInfoProcessor.setScripts(scriptsOp); | |
| 51 | + return bpmCandidateScriptApiSourceInfoProcessor; | |
| 52 | + } | |
| 53 | +} | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfo.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.rule.BpmTaskAssignRuleBaseVO; | |
| 5 | +import io.swagger.v3.oas.annotations.media.Schema; | |
| 6 | +import lombok.AllArgsConstructor; | |
| 7 | +import lombok.Data; | |
| 8 | +import lombok.NoArgsConstructor; | |
| 9 | +import org.flowable.engine.delegate.DelegateExecution; | |
| 10 | + | |
| 11 | +import java.util.HashSet; | |
| 12 | +import java.util.Set; | |
| 13 | + | |
| 14 | +/** | |
| 15 | + * 获取候选人信息 | |
| 16 | + */ | |
| 17 | +@AllArgsConstructor | |
| 18 | +@NoArgsConstructor | |
| 19 | +@Data | |
| 20 | +public class BpmCandidateSourceInfo { | |
| 21 | + | |
| 22 | + @Schema(description = "流程id") | |
| 23 | + private String processInstanceId; | |
| 24 | + | |
| 25 | + @Schema(description = "当前任务ID") | |
| 26 | + private String taskId; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 通过这些规则,生成最终需要生成的用户 | |
| 30 | + */ | |
| 31 | + @Schema(description = "当前任务预选规则") | |
| 32 | + private Set<BpmTaskCandidateVO> rules; | |
| 33 | + | |
| 34 | + @Schema(description = "源执行流程") | |
| 35 | + private DelegateExecution execution; | |
| 36 | + | |
| 37 | + public void addRule(BpmTaskCandidateVO vo) { | |
| 38 | + assert vo != null; | |
| 39 | + if (rules == null) { | |
| 40 | + rules = new HashSet<>(); | |
| 41 | + } | |
| 42 | + rules.add(vo); | |
| 43 | + } | |
| 44 | +} | |
| 0 | 45 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | + | |
| 7 | +import java.util.Collections; | |
| 8 | +import java.util.HashSet; | |
| 9 | +import java.util.Set; | |
| 10 | + | |
| 11 | +public interface BpmCandidateSourceInfoProcessor { | |
| 12 | + /** | |
| 13 | + * 获取该处理器支持的类型 | |
| 14 | + * 来自 {@link BpmTaskAssignRuleTypeEnum} | |
| 15 | + * | |
| 16 | + * @return | |
| 17 | + */ | |
| 18 | + Set<Integer> getSupportedTypes(); | |
| 19 | + | |
| 20 | + /** | |
| 21 | + * 对规则和人员做校验 | |
| 22 | + * | |
| 23 | + * @param type 规则 | |
| 24 | + * @param options 人员id | |
| 25 | + */ | |
| 26 | + void validRuleOptions(Integer type, Set<Long> options); | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 默认的处理 | |
| 30 | + * 如果想去操作所有的规则,则可以覆盖此方法 | |
| 31 | + * | |
| 32 | + * @param request | |
| 33 | + * @param chain | |
| 34 | + * @return 必须包含的是用户ID,而不是其他的ID | |
| 35 | + * @throws Exception | |
| 36 | + */ | |
| 37 | + default Set<Long> process(BpmCandidateSourceInfo request, BpmCandidateSourceInfoProcessorChain chain) throws Exception { | |
| 38 | + Set<BpmTaskCandidateVO> rules = request.getRules(); | |
| 39 | + Set<Long> results = new HashSet<>(); | |
| 40 | + for (BpmTaskCandidateVO rule : rules) { | |
| 41 | + // 每个处理器都有机会处理自己支持的事件 | |
| 42 | + if (CollUtil.contains(getSupportedTypes(), rule.getType())) { | |
| 43 | + results.addAll(doProcess(request, rule)); | |
| 44 | + } | |
| 45 | + } | |
| 46 | + return results; | |
| 47 | + } | |
| 48 | + | |
| 49 | + default Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 50 | + return Collections.emptySet(); | |
| 51 | + } | |
| 52 | +} | |
| 0 | 53 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChain.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 5 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 6 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 7 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 8 | +import org.flowable.engine.delegate.DelegateExecution; | |
| 9 | +import org.springframework.beans.factory.ObjectProvider; | |
| 10 | +import org.springframework.stereotype.Service; | |
| 11 | + | |
| 12 | +import javax.annotation.Resource; | |
| 13 | +import java.util.*; | |
| 14 | +import java.util.stream.Collectors; | |
| 15 | + | |
| 16 | +@Service | |
| 17 | +public class BpmCandidateSourceInfoProcessorChain { | |
| 18 | + | |
| 19 | + // 保存处理节点 | |
| 20 | + | |
| 21 | + private List<BpmCandidateSourceInfoProcessor> processorList; | |
| 22 | + @Resource | |
| 23 | + private AdminUserApi adminUserApi; | |
| 24 | + | |
| 25 | + /** | |
| 26 | + * 可添加其他处理器 | |
| 27 | + * | |
| 28 | + * @param processorOp | |
| 29 | + * @return | |
| 30 | + */ | |
| 31 | + @Resource | |
| 32 | + // 动态扩展处理节点 | |
| 33 | + public BpmCandidateSourceInfoProcessorChain addProcessor(ObjectProvider<BpmCandidateSourceInfoProcessor> processorOp) { | |
| 34 | + List<BpmCandidateSourceInfoProcessor> processor = processorOp.orderedStream().collect(Collectors.toList()); | |
| 35 | + if (null == processorList) { | |
| 36 | + processorList = new ArrayList<>(processor.size()); | |
| 37 | + } | |
| 38 | + processorList.addAll(processor); | |
| 39 | + return this; | |
| 40 | + } | |
| 41 | + | |
| 42 | + // 获取处理器处理 | |
| 43 | + public Set<Long> process(BpmCandidateSourceInfo sourceInfo) throws Exception { | |
| 44 | + // Verify our parameters | |
| 45 | + if (sourceInfo == null) { | |
| 46 | + throw new IllegalArgumentException(); | |
| 47 | + } | |
| 48 | + for (BpmCandidateSourceInfoProcessor processor : processorList) { | |
| 49 | + try { | |
| 50 | + for (BpmTaskCandidateVO vo : sourceInfo.getRules()) { | |
| 51 | + processor.validRuleOptions(vo.getType(), vo.getOptions()); | |
| 52 | + } | |
| 53 | + } catch (Exception e) { | |
| 54 | + e.printStackTrace(); | |
| 55 | + throw e; | |
| 56 | + } | |
| 57 | + } | |
| 58 | + Set<Long> saveResult = Collections.emptySet(); | |
| 59 | + Exception saveException = null; | |
| 60 | + for (BpmCandidateSourceInfoProcessor processor : processorList) { | |
| 61 | + try { | |
| 62 | + saveResult = processor.process(sourceInfo, this); | |
| 63 | + if (CollUtil.isNotEmpty(saveResult)) { | |
| 64 | + removeDisableUsers(saveResult); | |
| 65 | + break; | |
| 66 | + } | |
| 67 | + } catch (Exception e) { | |
| 68 | + saveException = e; | |
| 69 | + break; | |
| 70 | + } | |
| 71 | + } | |
| 72 | + // Return the exception or result state from the last execute() | |
| 73 | + if ((saveException != null)) { | |
| 74 | + throw saveException; | |
| 75 | + } else { | |
| 76 | + return (saveResult); | |
| 77 | + } | |
| 78 | + } | |
| 79 | + | |
| 80 | + public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution, BpmCandidateSourceInfo sourceInfo) { | |
| 81 | + sourceInfo.setExecution(execution); | |
| 82 | + Set<Long> results = Collections.emptySet(); | |
| 83 | + try { | |
| 84 | + results = process(sourceInfo); | |
| 85 | + } catch (Exception e) { | |
| 86 | + e.printStackTrace(); | |
| 87 | + } | |
| 88 | + return results; | |
| 89 | + } | |
| 90 | + | |
| 91 | + /** | |
| 92 | + * 移除禁用用户 | |
| 93 | + * @param assigneeUserIds | |
| 94 | + */ | |
| 95 | + public void removeDisableUsers(Set<Long> assigneeUserIds) { | |
| 96 | + if (CollUtil.isEmpty(assigneeUserIds)) { | |
| 97 | + return; | |
| 98 | + } | |
| 99 | + Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(assigneeUserIds); | |
| 100 | + assigneeUserIds.removeIf(id -> { | |
| 101 | + AdminUserRespDTO user = userMap.get(id); | |
| 102 | + return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus()); | |
| 103 | + }); | |
| 104 | + } | |
| 105 | +} | |
| 0 | 106 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateAdminUserApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 8 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 9 | + | |
| 10 | +import javax.annotation.Resource; | |
| 11 | +import java.util.Set; | |
| 12 | + | |
| 13 | +public class BpmCandidateAdminUserApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 14 | + @Resource | |
| 15 | + private AdminUserApi api; | |
| 16 | + | |
| 17 | + @Override | |
| 18 | + public Set<Integer> getSupportedTypes() { | |
| 19 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.USER.getType()); | |
| 20 | + } | |
| 21 | + | |
| 22 | + @Override | |
| 23 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 24 | + api.validateUserList(options); | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 29 | + return rule.getOptions(); | |
| 30 | + } | |
| 31 | +} | |
| 0 | 32 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateDeptApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 8 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 9 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 10 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 11 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 12 | + | |
| 13 | +import javax.annotation.Resource; | |
| 14 | +import java.util.Collections; | |
| 15 | +import java.util.List; | |
| 16 | +import java.util.Objects; | |
| 17 | +import java.util.Set; | |
| 18 | + | |
| 19 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 20 | + | |
| 21 | +public class BpmCandidateDeptApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 22 | + @Resource | |
| 23 | + private DeptApi api; | |
| 24 | + @Resource | |
| 25 | + private AdminUserApi adminUserApi; | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public Set<Integer> getSupportedTypes() { | |
| 29 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), | |
| 30 | + BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); | |
| 31 | + } | |
| 32 | + | |
| 33 | + @Override | |
| 34 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 35 | + api.validateDeptList(options); | |
| 36 | + } | |
| 37 | + | |
| 38 | + @Override | |
| 39 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 40 | + if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType(), rule.getType())) { | |
| 41 | + List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(rule.getOptions()); | |
| 42 | + return convertSet(users, AdminUserRespDTO::getId); | |
| 43 | + } else if (Objects.equals(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType(), rule.getType())) { | |
| 44 | + List<DeptRespDTO> depts = api.getDeptList(rule.getOptions()); | |
| 45 | + return convertSet(depts, DeptRespDTO::getLeaderUserId); | |
| 46 | + } | |
| 47 | + return Collections.emptySet(); | |
| 48 | + } | |
| 49 | +} | |
| 0 | 50 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidatePostApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 8 | +import cn.iocoder.yudao.module.system.api.dept.PostApi; | |
| 9 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 10 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 11 | + | |
| 12 | +import javax.annotation.Resource; | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Set; | |
| 15 | + | |
| 16 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | |
| 17 | + | |
| 18 | +public class BpmCandidatePostApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 19 | + @Resource | |
| 20 | + private PostApi api; | |
| 21 | + @Resource | |
| 22 | + private AdminUserApi adminUserApi; | |
| 23 | + | |
| 24 | + @Override | |
| 25 | + public Set<Integer> getSupportedTypes() { | |
| 26 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.POST.getType()); | |
| 27 | + } | |
| 28 | + | |
| 29 | + @Override | |
| 30 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 31 | + api.validPostList(options); | |
| 32 | + } | |
| 33 | + | |
| 34 | + @Override | |
| 35 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 36 | + List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(rule.getOptions()); | |
| 37 | + return convertSet(users, AdminUserRespDTO::getId); | |
| 38 | + } | |
| 39 | +} | |
| 0 | 40 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateRoleApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 6 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 8 | +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 9 | +import cn.iocoder.yudao.module.system.api.permission.RoleApi; | |
| 10 | + | |
| 11 | +import javax.annotation.Resource; | |
| 12 | +import java.util.Set; | |
| 13 | + | |
| 14 | +public class BpmCandidateRoleApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 15 | + @Resource | |
| 16 | + private RoleApi api; | |
| 17 | + | |
| 18 | + @Resource | |
| 19 | + private PermissionApi permissionApi; | |
| 20 | + | |
| 21 | + @Override | |
| 22 | + public Set<Integer> getSupportedTypes() { | |
| 23 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.ROLE.getType()); | |
| 24 | + } | |
| 25 | + | |
| 26 | + @Override | |
| 27 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 28 | + api.validRoleList(options); | |
| 29 | + } | |
| 30 | + | |
| 31 | + @Override | |
| 32 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 33 | + return permissionApi.getUserRoleIdListByRoleIds(rule.getOptions()); | |
| 34 | + } | |
| 35 | + | |
| 36 | +} | |
| 0 | 37 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateScriptApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.hutool.core.collection.CollUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 6 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 7 | +import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants; | |
| 8 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 9 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 10 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 11 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 12 | +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; | |
| 13 | +import org.flowable.engine.delegate.DelegateExecution; | |
| 14 | +import org.springframework.beans.factory.ObjectProvider; | |
| 15 | + | |
| 16 | +import javax.annotation.Resource; | |
| 17 | +import java.util.*; | |
| 18 | +import java.util.stream.Collectors; | |
| 19 | + | |
| 20 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | |
| 21 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | |
| 22 | +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_ASSIGN_SCRIPT_NOT_EXISTS; | |
| 23 | + | |
| 24 | +public class BpmCandidateScriptApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 25 | + @Resource | |
| 26 | + private DictDataApi dictDataApi; | |
| 27 | + | |
| 28 | + /** | |
| 29 | + * 任务分配脚本 | |
| 30 | + */ | |
| 31 | + private Map<Long, BpmTaskAssignScript> scriptMap = Collections.emptyMap(); | |
| 32 | + | |
| 33 | + public void setScripts(ObjectProvider<BpmTaskAssignScript> scriptsOp) { | |
| 34 | + List<BpmTaskAssignScript> scripts = scriptsOp.orderedStream().collect(Collectors.toList()); | |
| 35 | + setScripts(scripts); | |
| 36 | + } | |
| 37 | + | |
| 38 | + public void setScripts(List<BpmTaskAssignScript> scripts) { | |
| 39 | + this.scriptMap = convertMap(scripts, script -> script.getEnum().getId()); | |
| 40 | + } | |
| 41 | + | |
| 42 | + @Override | |
| 43 | + public Set<Integer> getSupportedTypes() { | |
| 44 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); | |
| 45 | + } | |
| 46 | + | |
| 47 | + @Override | |
| 48 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 49 | + dictDataApi.validateDictDataList(DictTypeConstants.TASK_ASSIGN_SCRIPT, | |
| 50 | + CollectionUtils.convertSet(options, String::valueOf)); | |
| 51 | + } | |
| 52 | + | |
| 53 | + @Override | |
| 54 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 55 | + return calculateTaskCandidateUsersByScript(request.getExecution(), rule.getOptions()); | |
| 56 | + } | |
| 57 | + | |
| 58 | + private Set<Long> calculateTaskCandidateUsersByScript(DelegateExecution execution, Set<Long> options) { | |
| 59 | + // 获得对应的脚本 | |
| 60 | + List<BpmTaskAssignScript> scripts = new ArrayList<>(options.size()); | |
| 61 | + options.forEach(id -> { | |
| 62 | + BpmTaskAssignScript script = scriptMap.get(id); | |
| 63 | + if (script == null) { | |
| 64 | + throw exception(TASK_ASSIGN_SCRIPT_NOT_EXISTS, id); | |
| 65 | + } | |
| 66 | + scripts.add(script); | |
| 67 | + }); | |
| 68 | + // 逐个计算任务 | |
| 69 | + Set<Long> userIds = new HashSet<>(); | |
| 70 | + scripts.forEach(script -> CollUtil.addAll(userIds, script.calculateTaskCandidateUsers(execution))); | |
| 71 | + return userIds; | |
| 72 | + } | |
| 73 | +} | |
| 0 | 74 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/candidate/sourceInfoProcessor/BpmCandidateUserGroupApiSourceInfoProcessor.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor; | |
| 2 | + | |
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.SetUtils; | |
| 4 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 5 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 6 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 7 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 8 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessor; | |
| 9 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 10 | + | |
| 11 | +import javax.annotation.Resource; | |
| 12 | +import java.util.HashSet; | |
| 13 | +import java.util.List; | |
| 14 | +import java.util.Set; | |
| 15 | + | |
| 16 | +public class BpmCandidateUserGroupApiSourceInfoProcessor implements BpmCandidateSourceInfoProcessor { | |
| 17 | + @Resource | |
| 18 | + private BpmUserGroupService api; | |
| 19 | + @Resource | |
| 20 | + private BpmUserGroupService userGroupService; | |
| 21 | + | |
| 22 | + @Override | |
| 23 | + public Set<Integer> getSupportedTypes() { | |
| 24 | + return SetUtils.asSet(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); | |
| 25 | + } | |
| 26 | + | |
| 27 | + @Override | |
| 28 | + public void validRuleOptions(Integer type, Set<Long> options) { | |
| 29 | + api.validUserGroups(options); | |
| 30 | + } | |
| 31 | + | |
| 32 | + @Override | |
| 33 | + public Set<Long> doProcess(BpmCandidateSourceInfo request, BpmTaskCandidateVO rule) { | |
| 34 | + List<BpmUserGroupDO> userGroups = userGroupService.getUserGroupList(rule.getOptions()); | |
| 35 | + Set<Long> userIds = new HashSet<>(); | |
| 36 | + userGroups.forEach(group -> userIds.addAll(group.getMemberUserIds())); | |
| 37 | + return userIds; | |
| 38 | + } | |
| 39 | + | |
| 40 | +} | |
| 0 | 41 | \ No newline at end of file | ... | ... |
yudao-module-bpm/yudao-module-bpm-biz/src/test/java/cn/iocoder/yudao/module/bpm/service/candidate/BpmCandidateSourceInfoProcessorChainTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.bpm.service.candidate; | |
| 2 | + | |
| 3 | +import cn.hutool.core.map.MapUtil; | |
| 4 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | |
| 5 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | |
| 6 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | |
| 7 | +import cn.iocoder.yudao.module.bpm.controller.admin.candidate.vo.BpmTaskCandidateVO; | |
| 8 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmTaskAssignRuleDO; | |
| 9 | +import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO; | |
| 10 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum; | |
| 11 | +import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskRuleScriptEnum; | |
| 12 | +import cn.iocoder.yudao.module.bpm.framework.bpm.config.BpmCandidateProcessorConfiguration; | |
| 13 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript; | |
| 14 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX1Script; | |
| 15 | +import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.impl.BpmTaskAssignLeaderX2Script; | |
| 16 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfo; | |
| 17 | +import cn.iocoder.yudao.module.bpm.service.candidate.BpmCandidateSourceInfoProcessorChain; | |
| 18 | +import cn.iocoder.yudao.module.bpm.service.candidate.sourceInfoProcessor.BpmCandidateScriptApiSourceInfoProcessor; | |
| 19 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmTaskAssignRuleServiceImpl; | |
| 20 | +import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; | |
| 21 | +import cn.iocoder.yudao.module.system.api.dept.DeptApi; | |
| 22 | +import cn.iocoder.yudao.module.system.api.dept.PostApi; | |
| 23 | +import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; | |
| 24 | +import cn.iocoder.yudao.module.system.api.dict.DictDataApi; | |
| 25 | +import cn.iocoder.yudao.module.system.api.permission.PermissionApi; | |
| 26 | +import cn.iocoder.yudao.module.system.api.permission.RoleApi; | |
| 27 | +import cn.iocoder.yudao.module.system.api.user.AdminUserApi; | |
| 28 | +import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO; | |
| 29 | +import org.flowable.engine.delegate.DelegateExecution; | |
| 30 | +import org.junit.jupiter.api.Test; | |
| 31 | +import org.springframework.beans.factory.ObjectProvider; | |
| 32 | +import org.springframework.boot.test.mock.mockito.MockBean; | |
| 33 | +import org.springframework.context.annotation.Import; | |
| 34 | + | |
| 35 | +import javax.annotation.Resource; | |
| 36 | +import java.util.Arrays; | |
| 37 | +import java.util.List; | |
| 38 | +import java.util.Map; | |
| 39 | +import java.util.Set; | |
| 40 | + | |
| 41 | +import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet; | |
| 42 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | |
| 43 | +import static java.util.Collections.singleton; | |
| 44 | +import static org.junit.jupiter.api.Assertions.assertEquals; | |
| 45 | +import static org.mockito.ArgumentMatchers.eq; | |
| 46 | +import static org.mockito.Mockito.when; | |
| 47 | + | |
| 48 | +@Import({BpmCandidateSourceInfoProcessorChain.class, BpmCandidateProcessorConfiguration.class, | |
| 49 | + BpmCandidateScriptApiSourceInfoProcessor.class, BpmTaskAssignLeaderX1Script.class, | |
| 50 | + BpmTaskAssignLeaderX2Script.class}) | |
| 51 | +public class BpmCandidateSourceInfoProcessorChainTest extends BaseDbUnitTest { | |
| 52 | + @Resource | |
| 53 | + private BpmCandidateSourceInfoProcessorChain processorChain; | |
| 54 | + | |
| 55 | + @MockBean | |
| 56 | + private BpmUserGroupService userGroupService; | |
| 57 | + @MockBean | |
| 58 | + private DeptApi deptApi; | |
| 59 | + @MockBean | |
| 60 | + private AdminUserApi adminUserApi; | |
| 61 | + @MockBean | |
| 62 | + private PermissionApi permissionApi; | |
| 63 | + @MockBean | |
| 64 | + private RoleApi roleApi; | |
| 65 | + @MockBean | |
| 66 | + private PostApi postApi; | |
| 67 | + @MockBean | |
| 68 | + private DictDataApi dictDataApi; | |
| 69 | + @Resource | |
| 70 | + private BpmCandidateScriptApiSourceInfoProcessor bpmCandidateScriptApiSourceInfoProcessor; | |
| 71 | + | |
| 72 | + @Test | |
| 73 | + public void testCalculateTaskCandidateUsers_Role() { | |
| 74 | + // 准备参数 | |
| 75 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 76 | + .setType(BpmTaskAssignRuleTypeEnum.ROLE.getType()); | |
| 77 | + // mock 方法 | |
| 78 | + when(permissionApi.getUserRoleIdListByRoleIds(eq(rule.getOptions()))) | |
| 79 | + .thenReturn(asSet(11L, 22L)); | |
| 80 | + mockGetUserMap(asSet(11L, 22L)); | |
| 81 | + | |
| 82 | + // 调用 | |
| 83 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 84 | + sourceInfo.addRule(rule); | |
| 85 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 86 | + // 断言 | |
| 87 | + assertEquals(asSet(11L, 22L), results); | |
| 88 | + } | |
| 89 | + | |
| 90 | + @Test | |
| 91 | + public void testCalculateTaskCandidateUsers_DeptMember() { | |
| 92 | + // 准备参数 | |
| 93 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 94 | + .setType(BpmTaskAssignRuleTypeEnum.DEPT_MEMBER.getType()); | |
| 95 | + // mock 方法 | |
| 96 | + List<AdminUserRespDTO> users = CollectionUtils.convertList(asSet(11L, 22L), | |
| 97 | + id -> new AdminUserRespDTO().setId(id)); | |
| 98 | + when(adminUserApi.getUserListByDeptIds(eq(rule.getOptions()))).thenReturn(users); | |
| 99 | + mockGetUserMap(asSet(11L, 22L)); | |
| 100 | + | |
| 101 | + // 调用 | |
| 102 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 103 | + sourceInfo.addRule(rule); | |
| 104 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 105 | + // 断言 | |
| 106 | + assertEquals(asSet(11L, 22L), results); | |
| 107 | + } | |
| 108 | + | |
| 109 | + @Test | |
| 110 | + public void testCalculateTaskCandidateUsers_DeptLeader() { | |
| 111 | + // 准备参数 | |
| 112 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 113 | + .setType(BpmTaskAssignRuleTypeEnum.DEPT_LEADER.getType()); | |
| 114 | + // mock 方法 | |
| 115 | + DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L)); | |
| 116 | + DeptRespDTO dept2 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(22L)); | |
| 117 | + when(deptApi.getDeptList(eq(rule.getOptions()))).thenReturn(Arrays.asList(dept1, dept2)); | |
| 118 | + mockGetUserMap(asSet(11L, 22L)); | |
| 119 | + | |
| 120 | + // 调用 | |
| 121 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 122 | + sourceInfo.addRule(rule); | |
| 123 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 124 | + // 断言 | |
| 125 | + assertEquals(asSet(11L, 22L), results); | |
| 126 | + } | |
| 127 | + | |
| 128 | + @Test | |
| 129 | + public void testCalculateTaskCandidateUsers_Post() { | |
| 130 | + // 准备参数 | |
| 131 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 132 | + .setType(BpmTaskAssignRuleTypeEnum.POST.getType()); | |
| 133 | + // mock 方法 | |
| 134 | + List<AdminUserRespDTO> users = CollectionUtils.convertList(asSet(11L, 22L), | |
| 135 | + id -> new AdminUserRespDTO().setId(id)); | |
| 136 | + when(adminUserApi.getUserListByPostIds(eq(rule.getOptions()))).thenReturn(users); | |
| 137 | + mockGetUserMap(asSet(11L, 22L)); | |
| 138 | + | |
| 139 | + // 调用 | |
| 140 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 141 | + sourceInfo.addRule(rule); | |
| 142 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 143 | + // 断言 | |
| 144 | + assertEquals(asSet(11L, 22L), results); | |
| 145 | + } | |
| 146 | + | |
| 147 | + @Test | |
| 148 | + public void testCalculateTaskCandidateUsers_User() { | |
| 149 | + // 准备参数 | |
| 150 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 151 | + .setType(BpmTaskAssignRuleTypeEnum.USER.getType()); | |
| 152 | + // mock 方法 | |
| 153 | + mockGetUserMap(asSet(1L, 2L)); | |
| 154 | + | |
| 155 | + // 调用 | |
| 156 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 157 | + sourceInfo.addRule(rule); | |
| 158 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 159 | + // 断言 | |
| 160 | + assertEquals(asSet(1L, 2L), results); | |
| 161 | + } | |
| 162 | + | |
| 163 | + @Test | |
| 164 | + public void testCalculateTaskCandidateUsers_UserGroup() { | |
| 165 | + // 准备参数 | |
| 166 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(1L, 2L)) | |
| 167 | + .setType(BpmTaskAssignRuleTypeEnum.USER_GROUP.getType()); | |
| 168 | + // mock 方法 | |
| 169 | + BpmUserGroupDO userGroup1 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(11L, 12L))); | |
| 170 | + BpmUserGroupDO userGroup2 = randomPojo(BpmUserGroupDO.class, o -> o.setMemberUserIds(asSet(21L, 22L))); | |
| 171 | + when(userGroupService.getUserGroupList(eq(rule.getOptions()))).thenReturn(Arrays.asList(userGroup1, userGroup2)); | |
| 172 | + mockGetUserMap(asSet(11L, 12L, 21L, 22L)); | |
| 173 | + | |
| 174 | + // 调用 | |
| 175 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 176 | + sourceInfo.addRule(rule); | |
| 177 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 178 | + // 断言 | |
| 179 | + assertEquals(asSet(11L, 12L, 21L, 22L), results); | |
| 180 | + } | |
| 181 | + | |
| 182 | + private void mockGetUserMap(Set<Long> assigneeUserIds) { | |
| 183 | + Map<Long, AdminUserRespDTO> userMap = CollectionUtils.convertMap(assigneeUserIds, id -> id, | |
| 184 | + id -> new AdminUserRespDTO().setId(id).setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 185 | + when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap); | |
| 186 | + } | |
| 187 | + | |
| 188 | + @Test | |
| 189 | + public void testCalculateTaskCandidateUsers_Script() { | |
| 190 | + // 准备参数 | |
| 191 | + BpmTaskCandidateVO rule = new BpmTaskCandidateVO().setOptions(asSet(20L, 21L)) | |
| 192 | + .setType(BpmTaskAssignRuleTypeEnum.SCRIPT.getType()); | |
| 193 | + // mock 方法 | |
| 194 | + BpmTaskAssignScript script1 = new BpmTaskAssignScript() { | |
| 195 | + | |
| 196 | + @Override | |
| 197 | + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) { | |
| 198 | + return singleton(11L); | |
| 199 | + } | |
| 200 | + | |
| 201 | + @Override | |
| 202 | + public BpmTaskRuleScriptEnum getEnum() { | |
| 203 | + return BpmTaskRuleScriptEnum.LEADER_X1; | |
| 204 | + } | |
| 205 | + }; | |
| 206 | + BpmTaskAssignScript script2 = new BpmTaskAssignScript() { | |
| 207 | + | |
| 208 | + @Override | |
| 209 | + public Set<Long> calculateTaskCandidateUsers(DelegateExecution task) { | |
| 210 | + return singleton(22L); | |
| 211 | + } | |
| 212 | + | |
| 213 | + @Override | |
| 214 | + public BpmTaskRuleScriptEnum getEnum() { | |
| 215 | + return BpmTaskRuleScriptEnum.LEADER_X2; | |
| 216 | + } | |
| 217 | + }; | |
| 218 | + bpmCandidateScriptApiSourceInfoProcessor.setScripts(Arrays.asList(script1, script2)); | |
| 219 | + mockGetUserMap(asSet(11L, 22L)); | |
| 220 | + | |
| 221 | + // 调用 | |
| 222 | + BpmCandidateSourceInfo sourceInfo = new BpmCandidateSourceInfo(); | |
| 223 | + sourceInfo.addRule(rule); | |
| 224 | + Set<Long> results = processorChain.calculateTaskCandidateUsers(null, sourceInfo); | |
| 225 | + // 断言 | |
| 226 | + assertEquals(asSet(11L, 22L), results); | |
| 227 | + } | |
| 228 | + | |
| 229 | + @Test | |
| 230 | + public void testRemoveDisableUsers() { | |
| 231 | + // 准备参数. 1L 可以找到;2L 是禁用的;3L 找不到 | |
| 232 | + Set<Long> assigneeUserIds = asSet(1L, 2L, 3L); | |
| 233 | + // mock 方法 | |
| 234 | + AdminUserRespDTO user1 = randomPojo(AdminUserRespDTO.class, o -> o.setId(1L) | |
| 235 | + .setStatus(CommonStatusEnum.ENABLE.getStatus())); | |
| 236 | + AdminUserRespDTO user2 = randomPojo(AdminUserRespDTO.class, o -> o.setId(2L) | |
| 237 | + .setStatus(CommonStatusEnum.DISABLE.getStatus())); | |
| 238 | + Map<Long, AdminUserRespDTO> userMap = MapUtil.builder(user1.getId(), user1) | |
| 239 | + .put(user2.getId(), user2).build(); | |
| 240 | + when(adminUserApi.getUserMap(eq(assigneeUserIds))).thenReturn(userMap); | |
| 241 | + | |
| 242 | + // 调用 | |
| 243 | + processorChain.removeDisableUsers(assigneeUserIds); | |
| 244 | + // 断言 | |
| 245 | + assertEquals(asSet(1L), assigneeUserIds); | |
| 246 | + } | |
| 247 | + | |
| 248 | +} | |
| 0 | 249 | \ No newline at end of file | ... | ... |