feat: 创建流程实例时,提前指派审批人

This commit is contained in:
kehaiyou 2023-11-05 14:21:37 +08:00
parent b400aaac36
commit ca184026cf
7 changed files with 82 additions and 6 deletions

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.framework.flowable.core.context;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.ttl.TransmittableThreadLocal;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 工作流--用户用到的上下文相关信息
*/
public class FlowableContextHolder {
private static final ThreadLocal<Map<String, List<Long>>> ASSIGNEE = new TransmittableThreadLocal<>();
/**
* 通过流程任务的定义 key 拿到提前选好的审批人
* 此方法目的首次创建流程实例时数据库中还查询不到 assignee 字段所以存入上下文中获取
*
* @param taskDefinitionKey 流程任务 key
* @return 审批人 ID 集合
*/
public static List<Long> getAssigneeByTaskDefinitionKey(String taskDefinitionKey) {
if (CollUtil.isNotEmpty(ASSIGNEE.get())) {
return ASSIGNEE.get().get(taskDefinitionKey);
}
return Collections.emptyList();
}
/**
* 存入提前选好的审批人到上下文线程变量中
*
* @param assignee 流程任务 key -> 审批人 ID 炅和
*/
public static void setAssignee(Map<String, List<Long>> assignee) {
ASSIGNEE.set(assignee);
}
}

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.api.task.dto;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
/**
@ -30,4 +31,10 @@ public class BpmProcessInstanceCreateReqDTO {
*/
@NotEmpty(message = "业务的唯一标识")
private String businessKey;
/**
* 提前指派的审批人
* 例如 { taskKey1 :[1,2] }则表示 taskKey1 这个任务提前设定了 userId 1,2 的用户进行审批
*/
private Map<String, List<Long>> assignee;
}

View File

@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Map;
@Schema(description = "管理后台 - 流程实例的创建 Request VO")
@ -17,4 +18,7 @@ public class BpmProcessInstanceCreateReqVO {
@Schema(description = "变量实例")
private Map<String, Object> variables;
@Schema(description = "提前指派的审批人", requiredMode = Schema.RequiredMode.REQUIRED, example = "{taskKey1:[1,2]}")
private Map<String, List<Long>> assignee;
}

View File

@ -12,6 +12,7 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
/**
@ -87,4 +88,9 @@ public class BpmProcessInstanceExtDO extends BaseDO {
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, Object> formVariables;
/**
* 提前设定好的审批人
*/
@TableField(typeHandler = JacksonTypeHandler.class)
private Map<String, List<Long>> assignee;
}

View File

@ -18,6 +18,7 @@ import cn.iocoder.yudao.module.bpm.dal.mysql.definition.BpmTaskAssignRuleMapper;
import cn.iocoder.yudao.module.bpm.enums.DictTypeConstants;
import cn.iocoder.yudao.module.bpm.enums.definition.BpmTaskAssignRuleTypeEnum;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.behavior.script.BpmTaskAssignScript;
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.PostApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
@ -39,6 +40,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.function.Function;
import static cn.hutool.core.text.CharSequenceUtil.format;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
@ -77,6 +79,9 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
private DictDataApi dictDataApi;
@Resource
private PermissionApi permissionApi;
@Resource
@Lazy // 解决循环依赖
private BpmProcessInstanceService processInstanceService;
/**
* 任务分配脚本
*/
@ -234,6 +239,12 @@ public class BpmTaskAssignRuleServiceImpl implements BpmTaskAssignRuleService {
@Override
@DataPermission(enable = false) // 忽略数据权限不然分配会存在问题
public Set<Long> calculateTaskCandidateUsers(DelegateExecution execution) {
//1. 先从提前选好的审批人中获取
List<Long> assignee = processInstanceService.getAssigneeByProcessInstanceIdAndTaskDefinitionKey(execution.getProcessInstanceId(), execution.getCurrentActivityId());
if(CollUtil.isNotEmpty(assignee)){
return convertSet(assignee, Function.identity());
}
//2. 通过分配规则计算审批人
BpmTaskAssignRuleDO rule = getTaskRule(execution);
return calculateTaskCandidateUsers(execution, rule);
}

View File

@ -49,16 +49,17 @@ public interface BpmProcessInstanceService {
/**
* 获得流程实例的分页
*
* @param userId 用户编号
* @param userId 用户编号
* @param pageReqVO 分页请求
* @return 流程实例的分页
*/
PageResult<BpmProcessInstancePageItemRespVO> getMyProcessInstancePage(Long userId,
@Valid BpmProcessInstanceMyPageReqVO pageReqVO);
/**
* 创建流程实例提供给前端
*
* @param userId 用户编号
* @param userId 用户编号
* @param createReqVO 创建信息
* @return 实例的编号
*/
@ -67,7 +68,7 @@ public interface BpmProcessInstanceService {
/**
* 创建流程实例提供给内部
*
* @param userId 用户编号
* @param userId 用户编号
* @param createReqDTO 创建信息
* @return 实例的编号
*/
@ -84,7 +85,7 @@ public interface BpmProcessInstanceService {
/**
* 取消流程实例
*
* @param userId 用户编号
* @param userId 用户编号
* @param cancelReqVO 取消信息
*/
void cancelProcessInstance(Long userId, @Valid BpmProcessInstanceCancelReqVO cancelReqVO);
@ -139,9 +140,17 @@ public interface BpmProcessInstanceService {
/**
* 更新 ProcessInstance 拓展记录为不通过
*
* @param id 流程编号
* @param id 流程编号
* @param reason 理由例如说审批不通过时需要传递该值
*/
void updateProcessInstanceExtReject(String id, String reason);
/**
* 去流程实例扩展表中取出指定流程任务提前指定的审批人
*
* @param processInstanceId 流程实例的编号
* @param taskDefinitionKey 流程任务定义的 key
* @return 审批人集合
*/
List<Long> getAssigneeByProcessInstanceIdAndTaskDefinitionKey(String processInstanceId, String taskDefinitionKey);
}