mirror of
https://gitee.com/hhyykk/ipms-sjy.git
synced 2025-02-03 12:14:57 +08:00
【代码重构】工作流:BpmTaskCandidateStrategy 拆分成 calculateUsers、calculateUsersByTask、calculateUsersByActivity,定位更明确
This commit is contained in:
parent
0c7fd9e1db
commit
c73d7fe32b
@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConver
|
|||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmFormDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateStartUserSelectStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept.BpmTaskCandidateStartUserSelectStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmCategoryService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmFormService;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
|
@ -17,7 +17,7 @@ import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConver
|
|||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
|
import cn.iocoder.yudao.module.bpm.event.BpmProcessInstanceStatusEvent;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateStartUserSelectStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept.BpmTaskCandidateStartUserSelectStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
|
import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
|
||||||
|
@ -53,7 +53,7 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
||||||
if (assigneeUserIds == null) {
|
if (assigneeUserIds == null) {
|
||||||
assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
|
assigneeUserIds = taskCandidateInvoker.calculateUsersByTask(execution);
|
||||||
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
||||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||||
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过!
|
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过!
|
||||||
|
@ -46,7 +46,7 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
Set<Long> assigneeUserIds = (Set<Long>) execution.getVariable(super.collectionVariable, Set.class);
|
||||||
if (assigneeUserIds == null) {
|
if (assigneeUserIds == null) {
|
||||||
assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
|
assigneeUserIds = taskCandidateInvoker.calculateUsersByTask(execution);
|
||||||
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
||||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||||
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过!
|
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,避免自动通过!
|
||||||
|
@ -57,7 +57,7 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
|
|||||||
|
|
||||||
// 情况二,如果非多实例的任务,则计算任务处理人
|
// 情况二,如果非多实例的任务,则计算任务处理人
|
||||||
// 第一步,先计算可处理该任务的处理人们
|
// 第一步,先计算可处理该任务的处理人们
|
||||||
Set<Long> candidateUserIds = taskCandidateInvoker.calculateUsers(execution);
|
Set<Long> candidateUserIds = taskCandidateInvoker.calculateUsersByTask(execution);
|
||||||
if (CollUtil.isEmpty(candidateUserIds)) {
|
if (CollUtil.isEmpty(candidateUserIds)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
@ -89,31 +90,66 @@ public class BpmTaskCandidateInvoker {
|
|||||||
* @return 用户编号集合
|
* @return 用户编号集合
|
||||||
*/
|
*/
|
||||||
@DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人
|
@DataPermission(enable = false) // 忽略数据权限,避免因为过滤,导致找不到候选人
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution) {
|
||||||
// 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过
|
// 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过
|
||||||
Integer approveType = BpmnModelUtils.parseApproveType(execution.getCurrentFlowElement());
|
FlowElement flowElement = execution.getCurrentFlowElement();
|
||||||
|
Integer approveType = BpmnModelUtils.parseApproveType(flowElement);
|
||||||
if (ObjectUtils.equalsAny(approveType,
|
if (ObjectUtils.equalsAny(approveType,
|
||||||
BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(),
|
BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(),
|
||||||
BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
|
BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
|
||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
Integer strategy = BpmnModelUtils.parseCandidateStrategy(execution.getCurrentFlowElement());
|
Integer strategy = BpmnModelUtils.parseCandidateStrategy(flowElement);
|
||||||
String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement());
|
String param = BpmnModelUtils.parseCandidateParam(flowElement);
|
||||||
// 1.1 计算任务的候选人
|
// 1.1 计算任务的候选人
|
||||||
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsers(execution, param);
|
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsersByTask(execution, param);
|
||||||
// 1.2 移除被禁用的用户 TODO @芋艿 在 calculateUsers 方法中默认已经移除了被禁用的用户, 这里还需要移除被禁用的用户吗?
|
// 1.2 移除被禁用的用户
|
||||||
removeDisableUsers(userIds);
|
removeDisableUsers(userIds);
|
||||||
|
|
||||||
// 2. 候选人为空时,根据“审批人为空”的配置补充
|
// 2. 候选人为空时,根据“审批人为空”的配置补充
|
||||||
if (CollUtil.isEmpty(userIds)) {
|
if (CollUtil.isEmpty(userIds)) {
|
||||||
userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
|
userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
|
||||||
.calculateUsers(execution, param);
|
.calculateUsersByTask(execution, param);
|
||||||
// ASSIGN_EMPTY 策略,不需要移除被禁用的用户。原因是,再移除,可能会出现更没审批人了!!!
|
// ASSIGN_EMPTY 策略,不需要移除被禁用的用户。原因是,再移除,可能会出现更没审批人了!!!
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 移除发起人的用户
|
// 3. 移除发起人的用户
|
||||||
removeStartUserIfSkip(execution, userIds);
|
ProcessInstance processInstance = SpringUtil.getBean(BpmProcessInstanceService.class)
|
||||||
|
.getProcessInstance(execution.getProcessInstanceId());
|
||||||
|
Assert.notNull(processInstance, "流程实例({}) 不存在", execution.getProcessInstanceId());
|
||||||
|
removeStartUserIfSkip(userIds, flowElement, Long.valueOf(processInstance.getStartUserId()));
|
||||||
|
return userIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId,
|
||||||
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
|
// 审批类型非人工审核时,不进行计算候选人。原因是:后续会自动通过、不通过
|
||||||
|
FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, activityId);
|
||||||
|
Integer approveType = BpmnModelUtils.parseApproveType(flowElement);
|
||||||
|
if (ObjectUtils.equalsAny(approveType,
|
||||||
|
BpmUserTaskApproveTypeEnum.AUTO_APPROVE.getType(),
|
||||||
|
BpmUserTaskApproveTypeEnum.AUTO_REJECT.getType())) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
Integer strategy = BpmnModelUtils.parseCandidateStrategy(flowElement);
|
||||||
|
String param = BpmnModelUtils.parseCandidateParam(flowElement);
|
||||||
|
// 1.1 计算任务的候选人
|
||||||
|
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsersByActivity(bpmnModel, activityId, param,
|
||||||
|
startUserId, processDefinitionId, processVariables);
|
||||||
|
// 1.2 移除被禁用的用户
|
||||||
|
removeDisableUsers(userIds);
|
||||||
|
|
||||||
|
// 2. 候选人为空时,根据“审批人为空”的配置补充
|
||||||
|
if (CollUtil.isEmpty(userIds)) {
|
||||||
|
userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
|
||||||
|
.calculateUsersByActivity(bpmnModel, activityId, param, startUserId, processDefinitionId, processVariables);
|
||||||
|
// ASSIGN_EMPTY 策略,不需要移除被禁用的用户。原因是,再移除,可能会出现更没审批人了!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 移除发起人的用户
|
||||||
|
removeStartUserIfSkip(userIds, flowElement, startUserId);
|
||||||
return userIds;
|
return userIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,25 +170,23 @@ public class BpmTaskCandidateInvoker {
|
|||||||
*
|
*
|
||||||
* 注意:如果只有一个候选人,则不处理,避免无法审批
|
* 注意:如果只有一个候选人,则不处理,避免无法审批
|
||||||
*
|
*
|
||||||
* @param execution 执行中的任务
|
|
||||||
* @param assigneeUserIds 当前分配的候选人
|
* @param assigneeUserIds 当前分配的候选人
|
||||||
|
* @param flowElement 当前节点
|
||||||
|
* @param startUserId 发起人
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void removeStartUserIfSkip(DelegateExecution execution, Set<Long> assigneeUserIds) {
|
void removeStartUserIfSkip(Set<Long> assigneeUserIds, FlowElement flowElement, Long startUserId) {
|
||||||
if (CollUtil.size(assigneeUserIds) <= 1) {
|
if (CollUtil.size(assigneeUserIds) <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Integer assignStartUserHandlerType = BpmnModelUtils.parseAssignStartUserHandlerType(execution.getCurrentFlowElement());
|
Integer assignStartUserHandlerType = BpmnModelUtils.parseAssignStartUserHandlerType(flowElement);
|
||||||
if (ObjectUtil.notEqual(assignStartUserHandlerType, BpmUserTaskAssignStartUserHandlerTypeEnum.SKIP.getType())) {
|
if (ObjectUtil.notEqual(assignStartUserHandlerType, BpmUserTaskAssignStartUserHandlerTypeEnum.SKIP.getType())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ProcessInstance processInstance = SpringUtil.getBean(BpmProcessInstanceService.class)
|
assigneeUserIds.remove(startUserId);
|
||||||
.getProcessInstance(execution.getProcessInstanceId());
|
|
||||||
Assert.notNull(processInstance, "流程实例({}) 不存在", execution.getProcessInstanceId());
|
|
||||||
assigneeUserIds.remove(Long.valueOf(processInstance.getStartUserId()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public BpmTaskCandidateStrategy getCandidateStrategy(Integer strategy) {
|
private BpmTaskCandidateStrategy getCandidateStrategy(Integer strategy) {
|
||||||
BpmTaskCandidateStrategyEnum strategyEnum = BpmTaskCandidateStrategyEnum.valueOf(strategy);
|
BpmTaskCandidateStrategyEnum strategyEnum = BpmTaskCandidateStrategyEnum.valueOf(strategy);
|
||||||
Assert.notNull(strategyEnum, "策略(%s) 不存在", strategy);
|
Assert.notNull(strategyEnum, "策略(%s) 不存在", strategy);
|
||||||
BpmTaskCandidateStrategy strategyObj = strategyMap.get(strategyEnum);
|
BpmTaskCandidateStrategy strategyObj = strategyMap.get(strategyEnum);
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -42,47 +42,44 @@ public interface BpmTaskCandidateStrategy {
|
|||||||
/**
|
/**
|
||||||
* 基于候选人参数,获得任务的候选用户们
|
* 基于候选人参数,获得任务的候选用户们
|
||||||
*
|
*
|
||||||
|
* 注意:实现 calculateUsers 系列方法时,有两种选择:
|
||||||
|
* 1. 只重写 calculateUsers 默认方法
|
||||||
|
* 2. 都重写 calculateUsersByTask 和 calculateUsersByActivity 两个方法
|
||||||
|
*
|
||||||
* @param param 执行任务
|
* @param param 执行任务
|
||||||
* @return 用户编号集合
|
* @return 用户编号集合
|
||||||
*/
|
*/
|
||||||
default Set<Long> calculateUsers(String param) {
|
default Set<Long> calculateUsers(String param) {
|
||||||
return Collections.emptySet();
|
throw new UnsupportedOperationException("该分配方法未实现,请检查!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于执行任务,获得任务的候选用户们
|
* 基于【执行任务】,获得任务的候选用户们
|
||||||
*
|
*
|
||||||
* @param execution 执行任务
|
* @param execution 执行任务
|
||||||
* @return 用户编号集合
|
* @return 用户编号集合
|
||||||
*/
|
*/
|
||||||
default Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
default Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
Set<Long> users = calculateUsers(param);
|
return calculateUsers(param);
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于流程实例,获得任务的候选用户们
|
* 基于【流程活动】,获得任务的候选用户们
|
||||||
* <p>
|
* <p>
|
||||||
* 目的:用于获取未执行节点的候选用户们
|
* 目的:用于获取未执行节点的候选用户们
|
||||||
*
|
*
|
||||||
* @param startUserId 流程发起人编号
|
* @param bpmnModel 流程图
|
||||||
* @param processInstance 流程实例编号
|
* @param activityId 活动 ID (对应 Bpmn XML id)
|
||||||
* @param activityId 活动 Id (对应 Bpmn XML id)
|
|
||||||
* @param param 节点的参数
|
* @param param 节点的参数
|
||||||
|
* @param startUserId 流程发起人编号
|
||||||
|
* @param processDefinitionId 流程定义编号
|
||||||
|
* @param processVariables 流程变量
|
||||||
* @return 用户编号集合
|
* @return 用户编号集合
|
||||||
*/
|
*/
|
||||||
default Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
|
@SuppressWarnings("unused")
|
||||||
Set<Long> users = calculateUsers(param);
|
default Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
removeDisableUsers(users);
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
return users;
|
return calculateUsers(param);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 移除被禁用的用户
|
|
||||||
*
|
|
||||||
* @param users 用户 Ids
|
|
||||||
*/
|
|
||||||
void removeDisableUsers(Set<Long> users);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* {@link BpmTaskCandidateStrategy} 抽象类
|
|
||||||
*
|
|
||||||
* @author jason
|
|
||||||
*/
|
|
||||||
public abstract class BpmTaskCandidateAbstractStrategy implements BpmTaskCandidateStrategy {
|
|
||||||
|
|
||||||
protected AdminUserApi adminUserApi;
|
|
||||||
|
|
||||||
public BpmTaskCandidateAbstractStrategy(AdminUserApi adminUserApi) {
|
|
||||||
this.adminUserApi = adminUserApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeDisableUsers(Set<Long> users) {
|
|
||||||
if (CollUtil.isEmpty(users)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(users);
|
|
||||||
users.removeIf(id -> {
|
|
||||||
AdminUserRespDTO user = userMap.get(id);
|
|
||||||
return user == null || !CommonStatusEnum.ENABLE.getStatus().equals(user.getStatus());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
|
||||||
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.user.AdminUserApi;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
||||||
import jakarta.annotation.Resource;
|
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
|
||||||
import org.springframework.context.annotation.Lazy;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static cn.hutool.core.collection.ListUtil.toList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发起人连续多级部门的负责人 {@link BpmTaskCandidateStrategy} 实现类
|
|
||||||
*
|
|
||||||
* @author jason
|
|
||||||
*/
|
|
||||||
@Component
|
|
||||||
public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
@Lazy
|
|
||||||
private BpmProcessInstanceService processInstanceService;
|
|
||||||
|
|
||||||
public BpmTaskCandidateStartUserDeptLeaderMultiStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
|
||||||
super(adminUserApi, deptApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
|
||||||
return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER_MULTI;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void validateParam(String param) {
|
|
||||||
// 参数是部门的层级
|
|
||||||
Assert.isTrue(Integer.parseInt(param) > 0, "部门的层级必须大于 0");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
|
||||||
// 获得流程发起人
|
|
||||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
|
||||||
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
|
||||||
// 获取发起人的 multi 部门负责人
|
|
||||||
DeptRespDTO dept = getStartUserDept(startUserId);
|
|
||||||
if (dept == null) {
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
Set<Long> users = getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
|
|
||||||
// TODO @jason:这里 removeDisableUsers 的原因是啥呀?
|
|
||||||
// TODO @芋艿 calculateUsers(execution, param) calculateUsers(startUserId, processInstance, activityId, param) 现在这两个方法, 默认都移除了被禁用的用户
|
|
||||||
// TODO @芋艿 因为被禁用的用户是不能审批任务。 在这里移除是不是好一点。 代码可以重用。
|
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
|
|
||||||
DeptRespDTO dept = getStartUserDept(startUserId);
|
|
||||||
if (dept == null) {
|
|
||||||
return new HashSet<>();
|
|
||||||
}
|
|
||||||
Set<Long> users = getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
|
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取发起人的部门
|
|
||||||
*
|
|
||||||
* @param startUserId 发起人 Id
|
|
||||||
*/
|
|
||||||
protected DeptRespDTO getStartUserDept(Long startUserId) {
|
|
||||||
AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);
|
|
||||||
if (startUser.getDeptId() == null) { // 找不到部门
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return deptApi.getDept(startUser.getDeptId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCand
|
|||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
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.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -14,14 +16,12 @@ import java.util.*;
|
|||||||
*
|
*
|
||||||
* @author jason
|
* @author jason
|
||||||
*/
|
*/
|
||||||
public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy extends BpmTaskCandidateAbstractStrategy {
|
public abstract class AbstractBpmTaskCandidateDeptLeaderStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
|
@Resource
|
||||||
protected DeptApi deptApi;
|
protected DeptApi deptApi;
|
||||||
|
@Resource
|
||||||
public BpmTaskCandidateAbstractDeptLeaderStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
protected AdminUserApi adminUserApi;
|
||||||
super(adminUserApi);
|
|
||||||
this.deptApi = deptApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得指定层级的部门负责人,只有第 level 的负责人
|
* 获得指定层级的部门负责人,只有第 level 的负责人
|
||||||
@ -75,4 +75,17 @@ public abstract class BpmTaskCandidateAbstractDeptLeaderStrategy extends BpmTas
|
|||||||
return deptLeaderIds;
|
return deptLeaderIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取发起人的部门
|
||||||
|
*
|
||||||
|
* @param startUserId 发起人 Id
|
||||||
|
*/
|
||||||
|
protected DeptRespDTO getStartUserDept(Long startUserId) {
|
||||||
|
AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);
|
||||||
|
if (startUser.getDeptId() == null) { // 找不到部门
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return deptApi.getDept(startUser.getDeptId());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,13 +1,12 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,11 +15,7 @@ import java.util.Set;
|
|||||||
* @author jason
|
* @author jason
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
|
public class BpmTaskCandidateDeptLeaderMultiStrategy extends AbstractBpmTaskCandidateDeptLeaderStrategy {
|
||||||
|
|
||||||
public BpmTaskCandidateDeptLeaderMultiStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
|
||||||
super(adminUserApi, deptApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
@ -32,14 +27,19 @@ public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbs
|
|||||||
// 参数格式: | 分隔:1)左边为部门(多个部门用 , 分隔)。2)右边为部门层级
|
// 参数格式: | 分隔:1)左边为部门(多个部门用 , 分隔)。2)右边为部门层级
|
||||||
String[] params = param.split("\\|");
|
String[] params = param.split("\\|");
|
||||||
Assert.isTrue(params.length == 2, "参数格式不匹配");
|
Assert.isTrue(params.length == 2, "参数格式不匹配");
|
||||||
deptApi.validateDeptList(StrUtils.splitToLong(params[0], ","));
|
List<Long> deptIds = StrUtils.splitToLong(params[0], ",");
|
||||||
Assert.isTrue(Integer.parseInt(params[1]) > 0, "部门层级必须大于 0");
|
int level = Integer.parseInt(params[1]);
|
||||||
|
// 校验部门存在
|
||||||
|
deptApi.validateDeptList(deptIds);
|
||||||
|
Assert.isTrue(level > 0, "部门层级必须大于 0");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(String param) {
|
public Set<Long> calculateUsers(String param) {
|
||||||
String[] params = param.split("\\|");
|
String[] params = param.split("\\|");
|
||||||
return getMultiLevelDeptLeaderIds(StrUtils.splitToLong(params[0], ","), Integer.valueOf(params[1]));
|
List<Long> deptIds = StrUtils.splitToLong(params[0], ",");
|
||||||
|
int level = Integer.parseInt(params[1]);
|
||||||
|
return super.getMultiLevelDeptLeaderIds(deptIds, level);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
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.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,14 +19,10 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateDeptLeaderStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateDeptLeaderStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
private final DeptApi deptApi;
|
@Resource
|
||||||
|
private DeptApi deptApi;
|
||||||
public BpmTaskCandidateDeptLeaderStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
this.deptApi = deptApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidat
|
|||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,14 +20,12 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateDeptMemberStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateDeptMemberStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
private final DeptApi deptApi;
|
@Resource
|
||||||
|
private DeptApi deptApi;
|
||||||
public BpmTaskCandidateDeptMemberStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
@Resource
|
||||||
super(adminUserApi);
|
private AdminUserApi adminUserApi;
|
||||||
this.deptApi = deptApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
@ -0,0 +1,70 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.hutool.core.collection.ListUtil.toList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发起人连续多级部门的负责人 {@link BpmTaskCandidateStrategy} 实现类
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends AbstractBpmTaskCandidateDeptLeaderStrategy {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
@Lazy
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
|
return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER_MULTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validateParam(String param) {
|
||||||
|
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||||
|
Assert.isTrue(level > 0, "部门的层级必须大于 0");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
|
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||||
|
// 获得流程发起人
|
||||||
|
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||||
|
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
||||||
|
// 获取发起人的 multi 部门负责人
|
||||||
|
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||||
|
if (dept == null) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
return super.getMultiLevelDeptLeaderIds(toList(dept.getId()), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
|
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||||
|
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||||
|
if (dept == null) {
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
return super.getMultiLevelDeptLeaderIds(toList(dept.getId()), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,21 +1,20 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
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.dept.dto.DeptRespDTO;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||||
@ -26,7 +25,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
|||||||
* @author jason
|
* @author jason
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidateAbstractDeptLeaderStrategy {
|
public class BpmTaskCandidateStartUserDeptLeaderStrategy extends AbstractBpmTaskCandidateDeptLeaderStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 避免循环依赖
|
@Lazy // 避免循环依赖
|
||||||
@ -37,10 +36,6 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat
|
|||||||
return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER;
|
return BpmTaskCandidateStrategyEnum.START_USER_DEPT_LEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BpmTaskCandidateStartUserDeptLeaderStrategy(AdminUserApi adminUserApi, DeptApi deptApi) {
|
|
||||||
super(adminUserApi, deptApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void validateParam(String param) {
|
public void validateParam(String param) {
|
||||||
// 参数是部门的层级
|
// 参数是部门的层级
|
||||||
@ -48,44 +43,29 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
// 获得流程发起人
|
// 获得流程发起人
|
||||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||||
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
||||||
// 获取发起人的部门负责人
|
// 获取发起人的部门负责人
|
||||||
Set<Long> users = getStartUserDeptLeader(startUserId, param);
|
return getStartUserDeptLeader(startUserId, param);
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
// 获取发起人的部门负责人
|
// 获取发起人的部门负责人
|
||||||
Set<Long> users = getStartUserDeptLeader(startUserId, param);
|
return getStartUserDeptLeader(startUserId, param);
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<Long> getStartUserDeptLeader(Long startUserId, String param) {
|
private Set<Long> getStartUserDeptLeader(Long startUserId, String param) {
|
||||||
DeptRespDTO dept = getStartUserDept(startUserId);
|
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||||
|
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||||
if (dept == null) {
|
if (dept == null) {
|
||||||
return new HashSet<>();
|
return new HashSet<>();
|
||||||
}
|
}
|
||||||
Long deptLeaderId = getAssignLevelDeptLeaderId(dept, Integer.valueOf(param)); // 参数是部门的层级
|
Long deptLeaderId = super.getAssignLevelDeptLeaderId(dept, level);
|
||||||
return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>();
|
return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取发起人的部门
|
|
||||||
*
|
|
||||||
* @param startUserId 发起人 Id
|
|
||||||
*/
|
|
||||||
protected DeptRespDTO getStartUserDept(Long startUserId) {
|
|
||||||
AdminUserRespDTO startUser = adminUserApi.getUser(startUserId);
|
|
||||||
if (startUser.getDeptId() == null) { // 找不到部门
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return deptApi.getDept(startUser.getDeptId());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -1,12 +1,13 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
import cn.hutool.core.collection.CollUtil;
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import com.google.common.collect.Sets;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.flowable.bpmn.model.BpmnModel;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.bpmn.model.UserTask;
|
import org.flowable.bpmn.model.UserTask;
|
||||||
@ -23,16 +24,12 @@ import java.util.*;
|
|||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateStartUserSelectStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateStartUserSelectStrategy extends AbstractBpmTaskCandidateDeptLeaderStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 延迟加载,避免循环依赖
|
@Lazy // 延迟加载,避免循环依赖
|
||||||
private BpmProcessInstanceService processInstanceService;
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
public BpmTaskCandidateStartUserSelectStrategy(AdminUserApi adminUserApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
return BpmTaskCandidateStrategyEnum.START_USER_SELECT;
|
return BpmTaskCandidateStrategyEnum.START_USER_SELECT;
|
||||||
@ -42,7 +39,12 @@ public class BpmTaskCandidateStartUserSelectStrategy extends BpmTaskCandidateAbs
|
|||||||
public void validateParam(String param) {}
|
public void validateParam(String param) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
public boolean isParamRequired() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LinkedHashSet<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||||
Assert.notNull(processInstance, "流程实例({})不能为空", execution.getProcessInstanceId());
|
Assert.notNull(processInstance, "流程实例({})不能为空", execution.getProcessInstanceId());
|
||||||
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processInstance);
|
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processInstance);
|
||||||
@ -50,28 +52,22 @@ public class BpmTaskCandidateStartUserSelectStrategy extends BpmTaskCandidateAbs
|
|||||||
execution.getProcessInstanceId());
|
execution.getProcessInstanceId());
|
||||||
// 获得审批人
|
// 获得审批人
|
||||||
List<Long> assignees = startUserSelectAssignees.get(execution.getCurrentActivityId());
|
List<Long> assignees = startUserSelectAssignees.get(execution.getCurrentActivityId());
|
||||||
Set<Long> users = new LinkedHashSet<>(assignees);
|
return new LinkedHashSet<>(assignees);
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
|
public LinkedHashSet<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
if (processInstance == null) {
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
return Collections.emptySet();
|
if (processVariables == null) {
|
||||||
|
return Sets.newLinkedHashSet();
|
||||||
|
}
|
||||||
|
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processVariables);
|
||||||
|
if (startUserSelectAssignees == null) {
|
||||||
|
return Sets.newLinkedHashSet();
|
||||||
}
|
}
|
||||||
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processInstance);
|
|
||||||
Assert.notNull(startUserSelectAssignees, "流程实例({}) 的发起人自选审批人不能为空", processInstance.getId());
|
|
||||||
// 获得审批人
|
// 获得审批人
|
||||||
List<Long> assignees = startUserSelectAssignees.get(activityId);
|
List<Long> assignees = startUserSelectAssignees.get(activityId);
|
||||||
Set<Long> users = new LinkedHashSet<>(assignees);
|
return new LinkedHashSet<>(assignees);
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isParamRequired() {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
@ -7,13 +7,15 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCand
|
|||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@ -23,16 +25,12 @@ import java.util.Set;
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateAssignEmptyStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateAssignEmptyStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 延迟加载,避免循环依赖
|
@Lazy // 延迟加载,避免循环依赖
|
||||||
private BpmProcessDefinitionService processDefinitionService;
|
private BpmProcessDefinitionService processDefinitionService;
|
||||||
|
|
||||||
public BpmTaskCandidateAssignEmptyStrategy(AdminUserApi adminUserApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
return BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY;
|
return BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY;
|
||||||
@ -43,19 +41,28 @@ public class BpmTaskCandidateAssignEmptyStrategy extends BpmTaskCandidateAbstrac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
|
return getCandidateUsers(execution.getProcessDefinitionId(), execution.getCurrentFlowElement());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
|
FlowElement flowElement = BpmnModelUtils.getFlowElementById(bpmnModel, activityId);
|
||||||
|
return getCandidateUsers(processDefinitionId, flowElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<Long> getCandidateUsers(String processDefinitionId, FlowElement flowElement) {
|
||||||
// 情况一:指定人员审批
|
// 情况一:指定人员审批
|
||||||
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(execution.getCurrentFlowElement());
|
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(flowElement);
|
||||||
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType())) {
|
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType())) {
|
||||||
Set<Long> users = new HashSet<>(BpmnModelUtils.parseAssignEmptyHandlerUserIds(execution.getCurrentFlowElement()));
|
return new HashSet<>(BpmnModelUtils.parseAssignEmptyHandlerUserIds(flowElement));
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 情况二:流程管理员
|
// 情况二:流程管理员
|
||||||
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType())) {
|
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType())) {
|
||||||
BpmProcessDefinitionInfoDO processDefinition = processDefinitionService.getProcessDefinitionInfo(execution.getProcessDefinitionId());
|
BpmProcessDefinitionInfoDO processDefinition = processDefinitionService.getProcessDefinitionInfo(processDefinitionId);
|
||||||
Assert.notNull(processDefinition, "流程定义({})不存在", execution.getProcessDefinitionId());
|
Assert.notNull(processDefinition, "流程定义({})不存在", processDefinitionId);
|
||||||
return new HashSet<>(processDefinition.getManagerUserIds());
|
return new HashSet<>(processDefinition.getManagerUserIds());
|
||||||
}
|
}
|
||||||
|
|
@ -1,13 +1,14 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
||||||
|
|
||||||
import cn.hutool.core.convert.Convert;
|
import cn.hutool.core.convert.Convert;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,11 +17,7 @@ import java.util.Set;
|
|||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateExpressionStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateExpressionStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
public BpmTaskCandidateExpressionStrategy(AdminUserApi adminUserApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
@ -33,11 +30,16 @@ public class BpmTaskCandidateExpressionStrategy extends BpmTaskCandidateAbstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
Object result = FlowableUtils.getExpressionValue(execution, param);
|
Object result = FlowableUtils.getExpressionValue(execution, param);
|
||||||
Set<Long> users = Convert.toSet(Long.class, result);
|
return Convert.toSet(Long.class, result);
|
||||||
removeDisableUsers(users);
|
}
|
||||||
return users;
|
|
||||||
|
@Override
|
||||||
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
|
Object result = FlowableUtils.getExpressionValue(processVariables, param);
|
||||||
|
return Convert.toSet(Long.class, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -20,14 +20,10 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateGroupStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateGroupStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
private final BpmUserGroupService userGroupService;
|
@Resource
|
||||||
|
private BpmUserGroupService userGroupService;
|
||||||
public BpmTaskCandidateGroupStrategy(AdminUserApi adminUserApi, BpmUserGroupService userGroupService) {
|
|
||||||
super(adminUserApi);
|
|
||||||
this.userGroupService = userGroupService;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
@ -37,7 +33,7 @@ public class BpmTaskCandidateGroupStrategy extends BpmTaskCandidateAbstractStrat
|
|||||||
@Override
|
@Override
|
||||||
public void validateParam(String param) {
|
public void validateParam(String param) {
|
||||||
Set<Long> groupIds = StrUtils.splitToLongSet(param);
|
Set<Long> groupIds = StrUtils.splitToLongSet(param);
|
||||||
userGroupService.getUserGroupList(groupIds);
|
userGroupService.validUserGroups(groupIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidat
|
|||||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -19,14 +20,12 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidatePostStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidatePostStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
private final PostApi postApi;
|
@Resource
|
||||||
|
private PostApi postApi;
|
||||||
public BpmTaskCandidatePostStrategy(AdminUserApi adminUserApi, PostApi postApi) {
|
@Resource
|
||||||
super(adminUserApi);
|
private AdminUserApi adminUserApi;
|
||||||
this.postApi = postApi;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
@ -1,11 +1,10 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
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.permission.RoleApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -17,17 +16,13 @@ import java.util.Set;
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateRoleStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateRoleStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private RoleApi roleApi;
|
private RoleApi roleApi;
|
||||||
@Resource
|
@Resource
|
||||||
private PermissionApi permissionApi;
|
private PermissionApi permissionApi;
|
||||||
|
|
||||||
public BpmTaskCandidateRoleStrategy(AdminUserApi adminUserApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
return BpmTaskCandidateStrategyEnum.ROLE;
|
return BpmTaskCandidateStrategyEnum.ROLE;
|
@ -1,15 +1,17 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.flowable.engine.runtime.ProcessInstance;
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,16 +22,12 @@ import java.util.Set;
|
|||||||
* @author jason
|
* @author jason
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateStartUserStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
@Lazy // 延迟加载,避免循环依赖
|
@Lazy // 延迟加载,避免循环依赖
|
||||||
private BpmProcessInstanceService processInstanceService;
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
public BpmTaskCandidateStartUserStrategy(AdminUserApi adminUserApi) {
|
|
||||||
super(adminUserApi);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
return BpmTaskCandidateStrategyEnum.START_USER;
|
return BpmTaskCandidateStrategyEnum.START_USER;
|
||||||
@ -45,18 +43,15 @@ public class BpmTaskCandidateStartUserStrategy extends BpmTaskCandidateAbstractS
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
public Set<Long> calculateUsersByTask(DelegateExecution execution, String param) {
|
||||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||||
Set<Long> users = SetUtils.asSet(Long.valueOf(processInstance.getStartUserId()));
|
return SetUtils.asSet(Long.valueOf(processInstance.getStartUserId()));
|
||||||
removeDisableUsers(users);
|
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
|
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||||
Set<Long> users = SetUtils.asSet(startUserId);
|
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||||
removeDisableUsers(users);
|
return SetUtils.asSet(startUserId);
|
||||||
return users;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.hutool.core.text.StrPool;
|
import cn.hutool.core.text.StrPool;
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 用户 {@link BpmTaskCandidateStrategy} 实现类
|
* 用户 {@link BpmTaskCandidateStrategy} 实现类
|
||||||
@ -16,11 +16,10 @@ import java.util.Set;
|
|||||||
* @author kyle
|
* @author kyle
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class BpmTaskCandidateUserStrategy extends BpmTaskCandidateAbstractStrategy {
|
public class BpmTaskCandidateUserStrategy implements BpmTaskCandidateStrategy {
|
||||||
|
|
||||||
public BpmTaskCandidateUserStrategy(AdminUserApi adminUserApi) {
|
@Resource
|
||||||
super(adminUserApi);
|
private AdminUserApi adminUserApi;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||||
@ -33,7 +32,7 @@ public class BpmTaskCandidateUserStrategy extends BpmTaskCandidateAbstractStrate
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> calculateUsers(String param) {
|
public LinkedHashSet<Long> calculateUsers(String param) {
|
||||||
return new LinkedHashSet<>(StrUtils.splitToLong(param, StrPool.COMMA));
|
return new LinkedHashSet<>(StrUtils.splitToLong(param, StrPool.COMMA));
|
||||||
}
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ public class BpmCopyTaskDelegate implements JavaDelegate {
|
|||||||
@Override
|
@Override
|
||||||
public void execute(DelegateExecution execution) {
|
public void execute(DelegateExecution execution) {
|
||||||
// 1. 获得抄送人
|
// 1. 获得抄送人
|
||||||
Set<Long> userIds = taskCandidateInvoker.calculateUsers(execution);
|
Set<Long> userIds = taskCandidateInvoker.calculateUsersByTask(execution);
|
||||||
if (CollUtil.isEmpty(userIds)) {
|
if (CollUtil.isEmpty(userIds)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import cn.hutool.core.map.MapUtil;
|
|||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.hutool.core.util.ObjUtil;
|
import cn.hutool.core.util.ObjUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||||
@ -23,7 +22,6 @@ import org.flowable.bpmn.model.Process;
|
|||||||
import org.flowable.bpmn.model.*;
|
import org.flowable.bpmn.model.*;
|
||||||
import org.flowable.common.engine.api.FlowableException;
|
import org.flowable.common.engine.api.FlowableException;
|
||||||
import org.flowable.common.engine.impl.util.io.BytesStreamSource;
|
import org.flowable.common.engine.impl.util.io.BytesStreamSource;
|
||||||
import org.flowable.engine.ManagementService;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -773,20 +771,16 @@ public class BpmnModelUtils {
|
|||||||
* @return 是否满足条件
|
* @return 是否满足条件
|
||||||
*/
|
*/
|
||||||
public static boolean evalConditionExpress(Map<String, Object> variables, String express) {
|
public static boolean evalConditionExpress(Map<String, Object> variables, String express) {
|
||||||
ManagementService managementService = SpringUtil.getBean(ManagementService.class);
|
|
||||||
if (express == null) {
|
if (express == null) {
|
||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
// TODO @jason:疑问,为啥这里要在 managementService 里执行哈?
|
try {
|
||||||
Object result = managementService.executeCommand(context -> {
|
Object result = FlowableUtils.getExpressionValue(variables, express);
|
||||||
try {
|
return Boolean.TRUE.equals(result);
|
||||||
return FlowableUtils.getExpressionValue(variables, express);
|
} catch (FlowableException ex) {
|
||||||
} catch (FlowableException ex) {
|
log.error("[evalConditionExpress][条件表达式({}) 变量({}) 解析报错", express, variables, ex);
|
||||||
log.error("[evalConditionExpress][条件表达式({}) 解析报错", express, ex);
|
return Boolean.FALSE;
|
||||||
return Boolean.FALSE;
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
return Boolean.TRUE.equals(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("PatternVariableCanBeUsed")
|
@SuppressWarnings("PatternVariableCanBeUsed")
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
|
||||||
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||||
@ -9,6 +10,7 @@ import org.flowable.common.engine.api.variable.VariableContainer;
|
|||||||
import org.flowable.common.engine.impl.el.ExpressionManager;
|
import org.flowable.common.engine.impl.el.ExpressionManager;
|
||||||
import org.flowable.common.engine.impl.identity.Authentication;
|
import org.flowable.common.engine.impl.identity.Authentication;
|
||||||
import org.flowable.common.engine.impl.variable.MapDelegateVariableContainer;
|
import org.flowable.common.engine.impl.variable.MapDelegateVariableContainer;
|
||||||
|
import org.flowable.engine.ManagementService;
|
||||||
import org.flowable.engine.ProcessEngineConfiguration;
|
import org.flowable.engine.ProcessEngineConfiguration;
|
||||||
import org.flowable.engine.history.HistoricProcessInstance;
|
import org.flowable.engine.history.HistoricProcessInstance;
|
||||||
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||||
@ -146,9 +148,22 @@ public class FlowableUtils {
|
|||||||
* @param processInstance 流程实例
|
* @param processInstance 流程实例
|
||||||
* @return 发起用户选择的审批人 Map
|
* @return 发起用户选择的审批人 Map
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static Map<String, List<Long>> getStartUserSelectAssignees(ProcessInstance processInstance) {
|
public static Map<String, List<Long>> getStartUserSelectAssignees(ProcessInstance processInstance) {
|
||||||
return (Map<String, List<Long>>) processInstance.getProcessVariables().get(
|
return processInstance != null ? getStartUserSelectAssignees(processInstance.getProcessVariables()) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得流程实例的发起用户选择的审批人 Map
|
||||||
|
*
|
||||||
|
* @param processVariables 流程变量
|
||||||
|
* @return 发起用户选择的审批人 Map
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static Map<String, List<Long>> getStartUserSelectAssignees(Map<String, Object> processVariables) {
|
||||||
|
if (processVariables == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (Map<String, List<Long>>) processVariables.get(
|
||||||
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES);
|
BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,18 +217,29 @@ public class FlowableUtils {
|
|||||||
|
|
||||||
// ========== Expression 相关的工具方法 ==========
|
// ========== Expression 相关的工具方法 ==========
|
||||||
|
|
||||||
public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {
|
private static Object getExpressionValue(VariableContainer variableContainer, String expressionString,
|
||||||
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
ProcessEngineConfigurationImpl processEngineConfiguration) {
|
||||||
assert processEngineConfiguration != null;
|
assert processEngineConfiguration!= null;
|
||||||
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
|
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
|
||||||
assert expressionManager != null;
|
assert expressionManager!= null;
|
||||||
Expression expression = expressionManager.createExpression(expressionString);
|
Expression expression = expressionManager.createExpression(expressionString);
|
||||||
return expression.getValue(variableContainer);
|
return expression.getValue(variableContainer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object getExpressionValue(VariableContainer variableContainer, String expressionString) {
|
||||||
|
ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
|
||||||
|
if (processEngineConfiguration != null) {
|
||||||
|
return getExpressionValue(variableContainer, expressionString, processEngineConfiguration);
|
||||||
|
}
|
||||||
|
// 如果 ProcessEngineConfigurationImpl 获取不到,则需要通过 ManagementService 来获取
|
||||||
|
ManagementService managementService = SpringUtil.getBean(ManagementService.class);
|
||||||
|
assert managementService != null;
|
||||||
|
return managementService.executeCommand(context ->
|
||||||
|
getExpressionValue(variableContainer, expressionString, CommandContextUtil.getProcessEngineConfiguration()));
|
||||||
|
}
|
||||||
|
|
||||||
public static Object getExpressionValue(Map<String, Object> variable, String expressionString) {
|
public static Object getExpressionValue(Map<String, Object> variable, String expressionString) {
|
||||||
VariableContainer variableContainer = new MapDelegateVariableContainer(variable,
|
VariableContainer variableContainer = new MapDelegateVariableContainer(variable, VariableContainer.empty());
|
||||||
VariableContainer.empty());
|
|
||||||
return getExpressionValue(variableContainer, expressionString);
|
return getExpressionValue(variableContainer, expressionString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because one or more lines are too long
@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
|
|||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateUserStrategy;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user.BpmTaskCandidateUserStrategy;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
@ -47,13 +47,13 @@ public class BpmTaskCandidateInvokerTest extends BaseMockitoUnitTest {
|
|||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
strategy = new BpmTaskCandidateUserStrategy(adminUserApi); // 创建strategy实例
|
strategy = new BpmTaskCandidateUserStrategy(); // 创建strategy实例
|
||||||
strategyList = Collections.singletonList(strategy); // 创建strategyList
|
strategyList = Collections.singletonList(strategy); // 创建strategyList
|
||||||
taskCandidateInvoker = new BpmTaskCandidateInvoker(strategyList, adminUserApi);
|
taskCandidateInvoker = new BpmTaskCandidateInvoker(strategyList, adminUserApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalculateUsers() {
|
public void testCalculateUsersByTask() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String param = "1,2";
|
String param = "1,2";
|
||||||
DelegateExecution execution = mock(DelegateExecution.class);
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
@ -74,7 +74,7 @@ public class BpmTaskCandidateInvokerTest extends BaseMockitoUnitTest {
|
|||||||
when(adminUserApi.getUserMap(eq(asSet(1L, 2L)))).thenReturn(userMap);
|
when(adminUserApi.getUserMap(eq(asSet(1L, 2L)))).thenReturn(userMap);
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = taskCandidateInvoker.calculateUsers(execution);
|
Set<Long> results = taskCandidateInvoker.calculateUsersByTask(execution);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(1L, 2L), results);
|
assertEquals(asSet(1L, 2L), results);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,43 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateDeptLeaderMultiStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private DeptApi deptApi;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsers() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "10,20|2";
|
||||||
|
// mock 方法
|
||||||
|
when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
|
||||||
|
Long deptId = invocationOnMock.getArgument(0);
|
||||||
|
return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsers(param);
|
||||||
|
// 断言结果
|
||||||
|
assertEquals(Sets.newLinkedHashSet(11L, 1001L, 21L, 2001L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,15 +1,16 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
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.dept.dto.DeptRespDTO;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
|
||||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
import static java.util.Arrays.asList;
|
import static java.util.Arrays.asList;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
@ -27,16 +28,16 @@ public class BpmTaskCandidateDeptLeaderStrategyTest extends BaseMockitoUnitTest
|
|||||||
@Test
|
@Test
|
||||||
public void testCalculateUsers() {
|
public void testCalculateUsers() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String param = "1,2";
|
String param = "10,20";
|
||||||
// mock 方法
|
// mock 方法
|
||||||
DeptRespDTO dept1 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(11L));
|
when(deptApi.getDeptList(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(
|
||||||
DeptRespDTO dept2 = randomPojo(DeptRespDTO.class, o -> o.setLeaderUserId(22L));
|
randomPojo(DeptRespDTO.class, o -> o.setId(10L).setParentId(10L).setLeaderUserId(11L)),
|
||||||
when(deptApi.getDeptList(eq(asSet(1L, 2L)))).thenReturn(asList(dept1, dept2));
|
randomPojo(DeptRespDTO.class, o -> o.setId(20L).setParentId(20L).setLeaderUserId(21L))));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsers(param);
|
||||||
// 断言
|
// 断言结果
|
||||||
assertEquals(asSet(11L, 22L), results);
|
assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,17 +1,19 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||||
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
import static java.util.Arrays.asList;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import static org.mockito.ArgumentMatchers.eq;
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
@ -21,22 +23,24 @@ public class BpmTaskCandidateDeptMemberStrategyTest extends BaseMockitoUnitTest
|
|||||||
@InjectMocks
|
@InjectMocks
|
||||||
private BpmTaskCandidateDeptMemberStrategy strategy;
|
private BpmTaskCandidateDeptMemberStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private DeptApi deptApi;
|
||||||
@Mock
|
@Mock
|
||||||
private AdminUserApi adminUserApi;
|
private AdminUserApi adminUserApi;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalculateUsers() {
|
public void testCalculateUsers() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String param = "11,22";
|
String param = "10,20";
|
||||||
// mock 方法
|
// mock 方法
|
||||||
List<AdminUserRespDTO> users = convertList(asSet(11L, 22L),
|
when(adminUserApi.getUserListByDeptIds(eq(SetUtils.asSet(10L, 20L)))).thenReturn(asList(
|
||||||
id -> new AdminUserRespDTO().setId(id));
|
randomPojo(AdminUserRespDTO.class, o -> o.setId(11L)),
|
||||||
when(adminUserApi.getUserListByDeptIds(eq(asSet(11L, 22L)))).thenReturn(users);
|
randomPojo(AdminUserRespDTO.class, o -> o.setId(21L))));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsers(param);
|
||||||
// 断言
|
// 断言结果
|
||||||
assertEquals(asSet(11L, 22L), results);
|
assertEquals(Sets.newLinkedHashSet(11L, 21L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
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.user.AdminUserApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateStartUserDeptLeaderMultiStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdminUserApi adminUserApi;
|
||||||
|
@Mock
|
||||||
|
private DeptApi deptApi;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByTask() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法(获得流程发起人)
|
||||||
|
Long startUserId = 1L;
|
||||||
|
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||||
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
|
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||||
|
when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
|
||||||
|
// mock 方法(获取发起人的 multi 部门负责人)
|
||||||
|
mockGetStartUserDept(startUserId);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByActivity() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法
|
||||||
|
Long startUserId = 1L;
|
||||||
|
mockGetStartUserDept(startUserId);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
|
||||||
|
startUserId, null, null);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockGetStartUserDept(Long startUserId) {
|
||||||
|
when(adminUserApi.getUser(eq(startUserId))).thenReturn(
|
||||||
|
randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));
|
||||||
|
when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
|
||||||
|
Long deptId = invocationOnMock.getArgument(0);
|
||||||
|
return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
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.user.AdminUserApi;
|
||||||
|
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateStartUserDeptLeaderStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private AdminUserApi adminUserApi;
|
||||||
|
@Mock
|
||||||
|
private DeptApi deptApi;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByTask() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法(获得流程发起人)
|
||||||
|
Long startUserId = 1L;
|
||||||
|
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||||
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
|
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||||
|
when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
|
||||||
|
// mock 方法(获取发起人的部门负责人)
|
||||||
|
mockGetStartUserDeptLeader(startUserId);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(1001L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetStartUserDeptLeader() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法
|
||||||
|
Long startUserId = 1L;
|
||||||
|
mockGetStartUserDeptLeader(startUserId);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
|
||||||
|
startUserId, null, null);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(1001L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void mockGetStartUserDeptLeader(Long startUserId) {
|
||||||
|
when(adminUserApi.getUser(eq(startUserId))).thenReturn(
|
||||||
|
randomPojo(AdminUserRespDTO.class, o -> o.setId(startUserId).setDeptId(10L)));
|
||||||
|
when(deptApi.getDept(any())).thenAnswer((Answer<DeptRespDTO>) invocationOnMock -> {
|
||||||
|
Long deptId = invocationOnMock.getArgument(0);
|
||||||
|
return randomPojo(DeptRespDTO.class, o -> o.setId(deptId).setParentId(deptId * 100).setLeaderUserId(deptId + 1));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateStartUserSelectStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateStartUserSelectStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByTask() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法(获得流程发起人)
|
||||||
|
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||||
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
|
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||||
|
when(execution.getCurrentActivityId()).thenReturn("activity_001");
|
||||||
|
// mock 方法(FlowableUtils)
|
||||||
|
Map<String, Object> processVariables = new HashMap<>();
|
||||||
|
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
|
||||||
|
MapUtil.of("activity_001", List.of(1L, 2L)));
|
||||||
|
when(processInstance.getProcessVariables()).thenReturn(processVariables);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByActivity() {
|
||||||
|
// 准备参数
|
||||||
|
String activityId = "activity_001";
|
||||||
|
Map<String, Object> processVariables = new HashMap<>();
|
||||||
|
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_SELECT_ASSIGNEES,
|
||||||
|
MapUtil.of("activity_001", List.of(1L, 2L)));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByActivity(null, activityId, null,
|
||||||
|
null, null, processVariables);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(1L, 2L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.ListUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||||
|
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
|
||||||
|
import org.flowable.bpmn.model.BpmnModel;
|
||||||
|
import org.flowable.bpmn.model.FlowElement;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateAssignEmptyStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateAssignEmptyStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BpmProcessDefinitionService processDefinitionService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByTask() {
|
||||||
|
try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class);
|
||||||
|
MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {
|
||||||
|
// 准备参数
|
||||||
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
|
String param = randomString();
|
||||||
|
// mock 方法(execution)
|
||||||
|
String processDefinitionId = randomString();
|
||||||
|
when(execution.getProcessDefinitionId()).thenReturn(processDefinitionId);
|
||||||
|
FlowElement flowElement = mock(FlowElement.class);
|
||||||
|
when(execution.getCurrentFlowElement()).thenReturn(flowElement);
|
||||||
|
// mock 方法(parseAssignEmptyHandlerType)
|
||||||
|
bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))
|
||||||
|
.thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType());
|
||||||
|
bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerUserIds(same(flowElement)))
|
||||||
|
.thenReturn(ListUtil.of(1L, 2L));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(SetUtils.asSet(1L, 2L), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByActivity() {
|
||||||
|
try (MockedStatic<BpmnModelUtils> bpmnModelUtilsMockedStatic = mockStatic(BpmnModelUtils.class)) {
|
||||||
|
// 准备参数
|
||||||
|
String processDefinitionId = randomString();
|
||||||
|
String activityId = randomString();
|
||||||
|
String param = randomString();
|
||||||
|
// mock 方法(getFlowElementById)
|
||||||
|
FlowElement flowElement = mock(FlowElement.class);
|
||||||
|
BpmnModel bpmnModel = mock(BpmnModel.class);
|
||||||
|
bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.getFlowElementById(same(bpmnModel), eq(activityId)))
|
||||||
|
.thenReturn(flowElement);
|
||||||
|
// mock 方法(parseAssignEmptyHandlerType)
|
||||||
|
bpmnModelUtilsMockedStatic.when(() -> BpmnModelUtils.parseAssignEmptyHandlerType(same(flowElement)))
|
||||||
|
.thenReturn(BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType());
|
||||||
|
// mock 方法(getProcessDefinitionInfo)
|
||||||
|
BpmProcessDefinitionInfoDO processDefinition = randomPojo(BpmProcessDefinitionInfoDO.class,
|
||||||
|
o -> o.setManagerUserIds(ListUtil.of(1L, 2L)));
|
||||||
|
when(processDefinitionService.getProcessDefinitionInfo(eq(processDefinitionId))).thenReturn(processDefinition);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByActivity(bpmnModel, activityId, param,
|
||||||
|
null, processDefinitionId, null);
|
||||||
|
// 断言
|
||||||
|
assertEquals(SetUtils.asSet(1L, 2L), userIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,14 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.other;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||||
import org.flowable.engine.delegate.DelegateExecution;
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.MockedStatic;
|
import org.mockito.MockedStatic;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
import static cn.iocoder.yudao.framework.common.util.collection.SetUtils.asSet;
|
||||||
@ -20,7 +22,7 @@ public class BpmTaskCandidateExpressionStrategyTest extends BaseMockitoUnitTest
|
|||||||
private BpmTaskCandidateExpressionStrategy strategy;
|
private BpmTaskCandidateExpressionStrategy strategy;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalculateUsers() {
|
public void testCalculateUsersByTask() {
|
||||||
try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
|
try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String param = "1,2";
|
String param = "1,2";
|
||||||
@ -30,7 +32,25 @@ public class BpmTaskCandidateExpressionStrategyTest extends BaseMockitoUnitTest
|
|||||||
.thenReturn(asSet(1L, 2L));
|
.thenReturn(asSet(1L, 2L));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(execution, param);
|
Set<Long> results = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(asSet(1L, 2L), results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByActivity() {
|
||||||
|
try (MockedStatic<FlowableUtils> flowableUtilMockedStatic = mockStatic(FlowableUtils.class)) {
|
||||||
|
// 准备参数
|
||||||
|
String param = "1,2";
|
||||||
|
Map<String, Object> processVariables = new HashMap<>();
|
||||||
|
// mock 方法
|
||||||
|
flowableUtilMockedStatic.when(() -> FlowableUtils.getExpressionValue(same(processVariables), eq(param)))
|
||||||
|
.thenReturn(asSet(1L, 2L));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> results = strategy.calculateUsersByActivity(null, null, param,
|
||||||
|
null, null, processVariables);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(1L, 2L), results);
|
assertEquals(asSet(1L, 2L), results);
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmUserGroupDO;
|
||||||
@ -34,9 +34,9 @@ public class BpmTaskCandidateGroupStrategyTest extends BaseMockitoUnitTest {
|
|||||||
when(userGroupService.getUserGroupList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(userGroup1, userGroup2));
|
when(userGroupService.getUserGroupList(eq(asSet(1L, 2L)))).thenReturn(Arrays.asList(userGroup1, userGroup2));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsersByTask(null, param);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(11L, 12L, 21L, 22L), results);
|
assertEquals(asSet(11L, 12L, 21L, 22L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
import cn.iocoder.yudao.module.system.api.dept.PostApi;
|
||||||
@ -37,9 +37,9 @@ public class BpmTaskCandidatePostStrategyTest extends BaseMockitoUnitTest {
|
|||||||
when(adminUserApi.getUserListByPostIds(eq(asSet(1L, 2L)))).thenReturn(users);
|
when(adminUserApi.getUserListByPostIds(eq(asSet(1L, 2L)))).thenReturn(users);
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsersByTask(null, param);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(11L, 22L), results);
|
assertEquals(asSet(11L, 22L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
|
||||||
@ -33,9 +33,9 @@ public class BpmTaskCandidateRoleStrategyTest extends BaseMockitoUnitTest {
|
|||||||
.thenReturn(asSet(11L, 22L));
|
.thenReturn(asSet(11L, 22L));
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsersByTask(null, param);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(11L, 22L), results);
|
assertEquals(asSet(11L, 22L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||||
|
import org.assertj.core.util.Sets;
|
||||||
|
import org.flowable.engine.delegate.DelegateExecution;
|
||||||
|
import org.flowable.engine.runtime.ProcessInstance;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
public class BpmTaskCandidateStartUserStrategyTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private BpmTaskCandidateStartUserStrategy strategy;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private BpmProcessInstanceService processInstanceService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByTask() {
|
||||||
|
// 准备参数
|
||||||
|
String param = "2";
|
||||||
|
// mock 方法(获得流程发起人)
|
||||||
|
Long startUserId = 1L;
|
||||||
|
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||||
|
DelegateExecution execution = mock(DelegateExecution.class);
|
||||||
|
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||||
|
when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(startUserId), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCalculateUsersByActivity() {
|
||||||
|
// 准备参数
|
||||||
|
Long startUserId = 1L;
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Set<Long> userIds = strategy.calculateUsersByActivity(null, null, null,
|
||||||
|
startUserId, null, null);
|
||||||
|
// 断言
|
||||||
|
assertEquals(Sets.newLinkedHashSet(startUserId), userIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.user;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -15,14 +15,15 @@ public class BpmTaskCandidateUserStrategyTest extends BaseMockitoUnitTest {
|
|||||||
private BpmTaskCandidateUserStrategy strategy;
|
private BpmTaskCandidateUserStrategy strategy;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalculateUsers() {
|
public void test() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
String param = "1,2";
|
String param = "1,2";
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Set<Long> results = strategy.calculateUsers(null, param);
|
Set<Long> userIds = strategy.calculateUsersByTask(null, param);
|
||||||
// 断言
|
// 断言
|
||||||
assertEquals(asSet(1L, 2L), results);
|
assertEquals(asSet(1L, 2L), userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user