mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2025-01-19 03:30:06 +08:00
【功能新增】工作流:支持审批人为空时,根据配置进行自动通过、自动拒绝、指定人审批的效果
This commit is contained in:
parent
d4306846f9
commit
0d738fa397
@ -0,0 +1,29 @@
|
||||
package cn.iocoder.yudao.module.bpm.enums.definition;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* BPM 用户任务的审批人为空时,处理类型枚举
|
||||
*
|
||||
* @author 芋道源码
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Getter
|
||||
public enum BpmUserTaskAssignEmptyHandlerTypeEnum implements IntArrayValuable {
|
||||
|
||||
APPROVE(1), // 自动通过
|
||||
REJECT(2), // 自动拒绝
|
||||
ASSIGN_USER(3), // 指定人员审批
|
||||
ASSIGN_ADMIN(4), // 转交给流程管理员
|
||||
;
|
||||
|
||||
private final Integer type;
|
||||
|
||||
@Override
|
||||
public int[] array() {
|
||||
return new int[0];
|
||||
}
|
||||
|
||||
}
|
@ -28,6 +28,8 @@ public enum BpmReasonEnum {
|
||||
ASSIGN_START_USER_APPROVE_WHEN_SKIP("审批人与提交人为同一人时,自动通过"),
|
||||
ASSIGN_START_USER_APPROVE_WHEN_DEPT_LEADER_NOT_FOUND("审批人与提交人为同一人时,找不到部门负责人,自动通过"),
|
||||
ASSIGN_START_USER_TRANSFER_DEPT_LEADER("审批人与提交人为同一人时,转交给部门负责人审批"),
|
||||
ASSIGN_EMPTY_APPROVE("审批人为空,自动通过"),
|
||||
ASSIGN_EMPTY_REJECT("审批人为空,自动不通过"),
|
||||
;
|
||||
|
||||
private final String reason;
|
||||
|
@ -86,6 +86,11 @@ public class BpmSimpleModelNodeVO {
|
||||
@InEnum(BpmUserTaskAssignStartUserHandlerTypeEnum.class)
|
||||
private Integer assignStartUserHandlerType;
|
||||
|
||||
/**
|
||||
* 空处理策略
|
||||
*/
|
||||
private AssignEmptyHandler assignEmptyHandler;
|
||||
|
||||
@Data
|
||||
@Schema(description = "审批节点拒绝处理策略")
|
||||
public static class RejectHandler {
|
||||
@ -121,6 +126,21 @@ public class BpmSimpleModelNodeVO {
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Schema(description = "空处理策略")
|
||||
@Valid
|
||||
public static class AssignEmptyHandler {
|
||||
|
||||
@Schema(description = "空处理类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "空处理类型不能为空")
|
||||
@InEnum(BpmUserTaskAssignEmptyHandlerTypeEnum.class)
|
||||
private Integer type;
|
||||
|
||||
@Schema(description = "指定人员审批的用户编号数组", example = "1")
|
||||
private List<Long> userIds;
|
||||
|
||||
}
|
||||
|
||||
@Data
|
||||
@Schema(description = "操作按钮设置")
|
||||
public static class OperationButtonSetting {
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
|
||||
import lombok.Setter;
|
||||
@ -49,6 +51,10 @@ public class BpmParallelMultiInstanceBehavior extends ParallelMultiInstanceBehav
|
||||
|
||||
// 第二步,获取任务的所有处理人
|
||||
Set<Long> assigneeUserIds = taskCandidateInvoker.calculateUsers(execution);
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务,避免自动通过!
|
||||
assigneeUserIds = SetUtils.asSet((Long) null);
|
||||
}
|
||||
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
||||
return assigneeUserIds.size();
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
|
||||
import lombok.Setter;
|
||||
@ -43,6 +45,10 @@ public class BpmSequentialMultiInstanceBehavior extends SequentialMultiInstanceB
|
||||
|
||||
// 第二步,获取任务的所有处理人
|
||||
Set<Long> assigneeUserIds = new LinkedHashSet<>(taskCandidateInvoker.calculateUsers(execution)); // 保证有序!!!
|
||||
if (CollUtil.isEmpty(assigneeUserIds)) {
|
||||
// 特殊:如果没有处理人的情况下,至少有一个 null 空元素,保证在 BpmUserTaskActivityBehavior 至少创建出一个 Task 任务,避免自动通过!
|
||||
assigneeUserIds = SetUtils.asSet((Long) null);
|
||||
}
|
||||
execution.setVariable(super.collectionVariable, assigneeUserIds);
|
||||
return assigneeUserIds.size();
|
||||
}
|
||||
|
@ -1,9 +1,16 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.RandomUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRejectReqVO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.enums.task.BpmReasonEnum;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateInvoker;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.bpmn.model.UserTask;
|
||||
@ -14,6 +21,8 @@ import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
|
||||
import org.flowable.engine.impl.util.TaskHelper;
|
||||
import org.flowable.task.service.TaskService;
|
||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -41,9 +50,29 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
|
||||
DelegateExecution execution, ProcessEngineConfigurationImpl processEngineConfiguration) {
|
||||
// 第一步,获得任务的候选用户
|
||||
Long assigneeUserId = calculateTaskCandidateUsers(execution);
|
||||
Assert.notNull(assigneeUserId, "任务处理人不能为空");
|
||||
// 第二步,设置作为负责人
|
||||
if (assigneeUserId != null) {
|
||||
TaskHelper.changeTaskAssignee(task, String.valueOf(assigneeUserId));
|
||||
return;
|
||||
}
|
||||
|
||||
// 特殊:审批人为空,根据配置是否要自动通过、自动拒绝
|
||||
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(userTask);
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.APPROVE.getType())) {
|
||||
SpringUtil.getBean(BpmTaskService.class).approveTask(null, new BpmTaskApproveReqVO()
|
||||
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_APPROVE.getReason()));
|
||||
} else if (ObjectUtil.equal(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.REJECT.getType())) {
|
||||
SpringUtil.getBean(BpmTaskService.class).rejectTask(null, new BpmTaskRejectReqVO()
|
||||
.setId(task.getId()).setReason(BpmReasonEnum.ASSIGN_EMPTY_REJECT.getReason()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private Long calculateTaskCandidateUsers(DelegateExecution execution) {
|
||||
@ -56,6 +85,9 @@ public class BpmUserTaskActivityBehavior extends UserTaskActivityBehavior {
|
||||
// 情况二,如果非多实例的任务,则计算任务处理人
|
||||
// 第一步,先计算可处理该任务的处理人们
|
||||
Set<Long> candidateUserIds = taskCandidateInvoker.calculateUsers(execution);
|
||||
if (CollUtil.isEmpty(candidateUserIds)) {
|
||||
return null;
|
||||
}
|
||||
// 第二步,后随机选择一个任务的处理人
|
||||
// 疑问:为什么一定要选择一个任务处理人?
|
||||
// 解答:项目对 bpm 的任务是责任到人,所以每个任务有且仅有一个处理人。
|
||||
|
@ -27,7 +27,6 @@ import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.MODEL_DEPLOY_FAIL_TASK_CANDIDATE_NOT_CONFIG;
|
||||
import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.TASK_CREATE_FAIL_NO_CANDIDATE_USER;
|
||||
|
||||
/**
|
||||
* {@link BpmTaskCandidateStrategy} 的调用者,用于调用对应的策略,实现任务的候选人的计算
|
||||
@ -89,17 +88,16 @@ public class BpmTaskCandidateInvoker {
|
||||
String param = BpmnModelUtils.parseCandidateParam(execution.getCurrentFlowElement());
|
||||
// 1.1 计算任务的候选人
|
||||
Set<Long> userIds = getCandidateStrategy(strategy).calculateUsers(execution, param);
|
||||
// 1.2 移除被禁用的用户
|
||||
removeDisableUsers(userIds);
|
||||
// 1.2 候选人为空时,根据“审批人为空”的配置补充
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
userIds = getCandidateStrategy(BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY.getStrategy())
|
||||
.calculateUsers(execution, param);
|
||||
}
|
||||
// 1.3 移除发起人的用户
|
||||
removeStartUserIfSkip(execution, userIds);
|
||||
|
||||
// 2. 校验是否有候选人
|
||||
if (CollUtil.isEmpty(userIds)) {
|
||||
log.error("[calculateUsers][流程任务({}/{}/{}) 任务规则({}/{}) 找不到候选人]", execution.getId(),
|
||||
execution.getProcessDefinitionId(), execution.getCurrentActivityId(), strategy, param);
|
||||
throw exception(TASK_CREATE_FAIL_NO_CANDIDATE_USER);
|
||||
}
|
||||
// 2. 移除被禁用的用户
|
||||
removeDisableUsers(userIds);
|
||||
return userIds;
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy;
|
||||
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskAssignEmptyHandlerTypeEnum;
|
||||
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.util.BpmnModelUtils;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.flowable.engine.delegate.DelegateExecution;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* 审批人为空 {@link BpmTaskCandidateStrategy} 实现类
|
||||
*
|
||||
* @author kyle
|
||||
*/
|
||||
@Component
|
||||
public class BpmTaskCandidateAssignEmptyStrategy implements BpmTaskCandidateStrategy {
|
||||
|
||||
@Resource
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@Override
|
||||
public BpmTaskCandidateStrategyEnum getStrategy() {
|
||||
return BpmTaskCandidateStrategyEnum.ASSIGN_EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateParam(String param) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
|
||||
// 情况一:指定人员审批
|
||||
Integer assignEmptyHandlerType = BpmnModelUtils.parseAssignEmptyHandlerType(execution.getCurrentFlowElement());
|
||||
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_USER.getType())) {
|
||||
return new HashSet<>(BpmnModelUtils.parseAssignEmptyHandlerUserIds(execution.getCurrentFlowElement()));
|
||||
}
|
||||
|
||||
// 情况二:流程管理员
|
||||
if (Objects.equals(assignEmptyHandlerType, BpmUserTaskAssignEmptyHandlerTypeEnum.ASSIGN_ADMIN.getType())) {
|
||||
// TODO 芋艿:需要等待流程实例的管理员支持
|
||||
throw new UnsupportedOperationException("暂时实现!!!");
|
||||
}
|
||||
|
||||
// 都不满足,还是返回空
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
}
|
@ -30,6 +30,7 @@ public enum BpmTaskCandidateStrategyEnum implements IntArrayValuable {
|
||||
START_USER_MULTI_LEVEL_DEPT_LEADER(38, "发起人连续多级部门的负责人"),
|
||||
USER_GROUP(40, "用户组"),
|
||||
EXPRESSION(60, "流程表达式"), // 表达式 ExpressionManager
|
||||
ASSIGN_EMPTY(1, "审批人为空"),
|
||||
;
|
||||
|
||||
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BpmTaskCandidateStrategyEnum::getStrategy).toArray();
|
||||
|
@ -38,6 +38,15 @@ public interface BpmnModelConstants {
|
||||
*/
|
||||
String USER_TASK_ASSIGN_START_USER_HANDLER_TYPE = "assignStartUserHandlerType";
|
||||
|
||||
/**
|
||||
* BPMN ExtensionElement 的扩展属性,用于标记用户任务的空处理类型
|
||||
*/
|
||||
String USER_TASK_ASSIGN_EMPTY_HANDLER_TYPE = "assignEmptyHandlerType";
|
||||
/**
|
||||
* BPMN ExtensionElement 的扩展属性,用于标记用户任务的空处理的指定用户编号数组
|
||||
*/
|
||||
String USER_TASK_ASSIGN_USER_IDS = "assignEmptyUserIds";
|
||||
|
||||
/**
|
||||
* BPMN ExtensionElement 的扩展属性,用于标记用户任务拒绝处理类型
|
||||
*/
|
||||
|
@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
|
||||
import cn.iocoder.yudao.framework.common.util.string.StrUtils;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmUserTaskRejectHandlerType;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnModelConstants;
|
||||
@ -45,16 +46,24 @@ public class BpmnModelUtils {
|
||||
}
|
||||
|
||||
public static BpmUserTaskRejectHandlerType parseRejectHandlerType(FlowElement userTask) {
|
||||
Integer rejectHandlerType = NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE));
|
||||
Integer rejectHandlerType = NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_REJECT_HANDLER_TYPE));
|
||||
return BpmUserTaskRejectHandlerType.typeOf(rejectHandlerType);
|
||||
}
|
||||
|
||||
public static String parseReturnTaskId(FlowElement flowElement) {
|
||||
return BpmnModelUtils.parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID);
|
||||
return parseExtensionElement(flowElement, USER_TASK_REJECT_RETURN_TASK_ID);
|
||||
}
|
||||
|
||||
public static Integer parseAssignStartUserHandlerType(FlowElement userTask) {
|
||||
return NumberUtils.parseInt(BpmnModelUtils.parseExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE));
|
||||
return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE));
|
||||
}
|
||||
|
||||
public static Integer parseAssignEmptyHandlerType(FlowElement userTask) {
|
||||
return NumberUtils.parseInt(parseExtensionElement(userTask, USER_TASK_ASSIGN_EMPTY_HANDLER_TYPE));
|
||||
}
|
||||
|
||||
public static List<Long> parseAssignEmptyHandlerUserIds(FlowElement userTask) {
|
||||
return StrUtils.splitToLong(parseExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS), ",");
|
||||
}
|
||||
|
||||
public static String parseExtensionElement(FlowElement flowElement, String elementName) {
|
||||
|
@ -19,10 +19,7 @@ import org.flowable.bpmn.BpmnAutoLayout;
|
||||
import org.flowable.bpmn.model.Process;
|
||||
import org.flowable.bpmn.model.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.OperationButtonSetting;
|
||||
import static cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO.TimeoutHandler;
|
||||
@ -456,7 +453,6 @@ public class SimpleModelUtils {
|
||||
userTask.setDueDate(node.getTimeoutHandler().getTimeDuration());
|
||||
}
|
||||
|
||||
// TODO @jason:addCandidateElements、processMultiInstanceLoopCharacteristics 建议一起搞哈?
|
||||
// 添加候选人元素
|
||||
addCandidateElements(node.getCandidateStrategy(), node.getCandidateParam(), userTask);
|
||||
// 添加表单字段权限属性元素
|
||||
@ -469,6 +465,8 @@ public class SimpleModelUtils {
|
||||
addTaskRejectElements(node.getRejectHandler(), userTask);
|
||||
// 添加用户任务的审批人与发起人相同时的处理元素
|
||||
addAssignStartUserHandlerType(node.getAssignStartUserHandlerType(), userTask);
|
||||
// 添加用户任务的空处理元素
|
||||
addAssignEmptyHandlerType(node.getAssignEmptyHandler(), userTask);
|
||||
return userTask;
|
||||
}
|
||||
|
||||
@ -487,6 +485,14 @@ public class SimpleModelUtils {
|
||||
addExtensionElement(userTask, USER_TASK_ASSIGN_START_USER_HANDLER_TYPE, assignStartUserHandlerType.toString());
|
||||
}
|
||||
|
||||
private static void addAssignEmptyHandlerType(BpmSimpleModelNodeVO.AssignEmptyHandler emptyHandler, UserTask userTask) {
|
||||
if (emptyHandler == null) {
|
||||
return;
|
||||
}
|
||||
addExtensionElement(userTask, USER_TASK_ASSIGN_EMPTY_HANDLER_TYPE, StrUtil.toStringOrNull(emptyHandler.getType()));
|
||||
addExtensionElement(userTask, USER_TASK_ASSIGN_USER_IDS, StrUtil.join(",", emptyHandler.getUserIds()));
|
||||
}
|
||||
|
||||
private static void processMultiInstanceLoopCharacteristics(Integer approveMethod, Integer approveRatio, UserTask userTask) {
|
||||
BpmApproveMethodEnum bpmApproveMethodEnum = BpmApproveMethodEnum.valueOf(approveMethod);
|
||||
if (bpmApproveMethodEnum == null || bpmApproveMethodEnum == BpmApproveMethodEnum.RANDOM) {
|
||||
@ -496,7 +502,7 @@ public class SimpleModelUtils {
|
||||
addExtensionElement(userTask, BpmnModelConstants.USER_TASK_APPROVE_METHOD,
|
||||
approveMethod == null ? null : approveMethod.toString());
|
||||
MultiInstanceLoopCharacteristics multiInstanceCharacteristics = new MultiInstanceLoopCharacteristics();
|
||||
// 设置 collectionVariable。本系统用不到。会在 仅仅为了校验。
|
||||
// 设置 collectionVariable。本系统用不到。仅仅为了 Flowable 校验不报错。
|
||||
multiInstanceCharacteristics.setInputDataItem("${coll_userList}");
|
||||
if (bpmApproveMethodEnum == BpmApproveMethodEnum.ANY) {
|
||||
multiInstanceCharacteristics.setCompletionCondition(ANY_OF_APPROVE_COMPLETE_EXPRESSION);
|
||||
|
@ -191,7 +191,10 @@ public class BpmTaskServiceImpl implements BpmTaskService {
|
||||
*/
|
||||
private Task validateTask(Long userId, String taskId) {
|
||||
Task task = validateTaskExist(taskId);
|
||||
if (!Objects.equals(userId, NumberUtils.parseLong(task.getAssignee()))) {
|
||||
// 为什么判断 assignee 非空的情况下?
|
||||
// 例如说:在审批人为空时,我们会有“自动审批通过”的策略,此时 userId 为 null,允许通过
|
||||
if (StrUtil.isNotBlank(task.getAssignee())
|
||||
&& ObjectUtil.notEqual(userId, NumberUtils.parseLong(task.getAssignee()))) {
|
||||
throw exception(TASK_OPERATE_FAIL_ASSIGN_NOT_SELF);
|
||||
}
|
||||
return task;
|
||||
|
Loading…
Reference in New Issue
Block a user