仿钉钉流程设计- 获取审批详情接口修改,增加流程未开始情况

This commit is contained in:
jason 2024-09-23 10:38:59 +08:00
parent ac2ae25a87
commit 1ae726f312
20 changed files with 109 additions and 70 deletions

View File

@ -15,7 +15,7 @@ import java.util.Arrays;
@Getter
@AllArgsConstructor
public enum BpmProcessInstanceStatusEnum implements IntArrayValuable {
NOT_START(-1, "未开始"),
RUNNING(1, "审批中"),
APPROVE(2, "审批通过"),
REJECT(3, "审批不通过"),

View File

@ -165,12 +165,12 @@ public class BpmProcessInstanceController {
return success(processInstanceService.getProcessInstanceFormFieldsPermission(reqVO));
}
@GetMapping("/get-progress")
@Operation(summary = "获得流程实例的进度")
@GetMapping("/get-approval-detail")
@Operation(summary = "获得审批详情")
@Parameter(name = "id", description = "流程实例的编号", required = true)
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
public CommonResult<BpmProcessInstanceProgressRespVO> getProcessInstanceProgress(@RequestParam("id") String id) {
return success(processInstanceService.getProcessInstanceProgress(id));
public CommonResult<BpmApprovalDetailRespVO> getApprovalDetail(@Valid BpmApprovalDetailReqVO reqVO) {
return success(processInstanceService.getApprovalDetail(getLoginUserId(), reqVO));
}
}

View File

@ -0,0 +1,15 @@
package cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 审批详情 Request VO")
@Data
public class BpmApprovalDetailReqVO {
@Schema(description = "流程定义的编号", example = "1024")
private String processDefinitionId;
@Schema(description = "流程实例的编号", example = "1024")
private String processInstanceId;
}

View File

@ -7,19 +7,19 @@ import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 流程实例的进度 Response VO")
@Schema(description = "管理后台 - 审批详情 Response VO")
@Data
public class BpmProcessInstanceProgressRespVO {
public class BpmApprovalDetailRespVO {
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
@Schema(description = "审批信息列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<ApproveNodeInfo> approveNodes;
private List<ApprovalNodeInfo> approveNodes;
@Schema(description = "审批节点信息")
@Data
public static class ApproveNodeInfo {
public static class ApprovalNodeInfo {
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartUserNode")
private String id;
@ -39,7 +39,7 @@ public class BpmProcessInstanceProgressRespVO {
private LocalDateTime endTime;
@Schema(description = "审批节点的任务信息")
private List<ApproveTaskInfo> tasks;
private List<ApprovalTaskInfo> tasks;
@Schema(description = "候选人用户列表")
private List<User> candidateUserList; // 用于未运行任务节点
@ -63,7 +63,7 @@ public class BpmProcessInstanceProgressRespVO {
@Schema(description = "审批任务信息")
@Data
public static class ApproveTaskInfo {
public static class ApprovalTaskInfo {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String id;

View File

@ -110,7 +110,7 @@ public class BpmTaskCandidateInvoker {
// 1.3 移除发起人的用户
removeStartUserIfSkip(execution, userIds);
// 2. 移除被禁用的用户
// 2. 移除被禁用的用户 TODO @芋艿 移除禁用的用户是否应该放在 1.1 之后
removeDisableUsers(userIds);
return userIds;
}

View File

@ -2,13 +2,14 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.runtime.ProcessInstance;
import java.util.Collections;
import java.util.Set;
/**
* BPM 任务的候选人的策略接口
*
* <p>
* 例如说分配审批人
*
* @author 芋道源码
@ -38,27 +39,43 @@ public interface BpmTaskCandidateStrategy {
return true;
}
/**
* 基于候选人参数获得任务的候选用户们
*
* @param param 执行任务
* @return 用户编号集合
*/
default Set<Long> calculateUsers(String param) {
return Collections.emptySet();
}
/**
* 基于执行任务获得任务的候选用户们
*
* @param execution 执行任务
* @return 用户编号集合
*/
Set<Long> calculateUsers(DelegateExecution execution, String param);
default Set<Long> calculateUsers(DelegateExecution execution, String param) {
return calculateUsers(param);
}
/**
* 基于流程实例获得任务的候选用户们
*
* <p>
* 目的用于获取未执行节点的候选用户们
*
* @param processInstanceId 流程实例编号
* @param startUserId 流程发起人编号
* @param processInstance 流程实例编号
* @param activityId 活动 Id (对应 Bpmn XML id)
* @param param 节点的参数
* @return 用户编号集合
*/
default Set<Long> calculateUsers(String processInstanceId, String param) {
return Collections.emptySet();
default Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
return calculateUsers(param);
}
// TODO @芋艿后续可以抽象一个 calculateUsers(String param)默认 calculateUsers calculateUsers 调用它
// TODO @芋艿 加了 review 一下
}

View File

@ -5,7 +5,6 @@ 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.enums.BpmTaskCandidateStrategyEnum;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.Set;
@ -37,7 +36,7 @@ public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbs
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
public Set<Long> calculateUsers(String param) {
String[] params = param.split("\\|");
return getMultiLevelDeptLeaderIds(StrUtils.splitToLong(params[0], ","), Integer.valueOf(params[1]));
}

View File

@ -6,7 +6,6 @@ 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.dto.DeptRespDTO;
import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.List;
@ -37,7 +36,7 @@ public class BpmTaskCandidateDeptLeaderStrategy implements BpmTaskCandidateStrat
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
public Set<Long> calculateUsers(String param) {
Set<Long> deptIds = StrUtils.splitToLongSet(param);
List<DeptRespDTO> depts = deptApi.getDeptList(deptIds);
return convertSet(depts, DeptRespDTO::getLeaderUserId);

View File

@ -7,7 +7,6 @@ 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.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.List;
@ -40,12 +39,7 @@ public class BpmTaskCandidateDeptMemberStrategy implements BpmTaskCandidateStrat
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
return calculateUsers((String) null, param);
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
public Set<Long> calculateUsers(String param) {
Set<Long> deptIds = StrUtils.splitToLongSet(param);
List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(deptIds);
return convertSet(users, AdminUserRespDTO::getId);

View File

@ -6,7 +6,6 @@ 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.service.definition.BpmUserGroupService;
import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.Collection;
@ -38,7 +37,7 @@ public class BpmTaskCandidateGroupStrategy implements BpmTaskCandidateStrategy {
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
public Set<Long> calculateUsers(String param) {
Set<Long> groupIds = StrUtils.splitToLongSet(param);
List<BpmUserGroupDO> groups = userGroupService.getUserGroupList(groupIds);
return convertSetByFlatMap(groups, BpmUserGroupDO::getUserIds, Collection::stream);

View File

@ -7,7 +7,6 @@ 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.dto.AdminUserRespDTO;
import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.List;
@ -40,7 +39,7 @@ public class BpmTaskCandidatePostStrategy implements BpmTaskCandidateStrategy {
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
public Set<Long> calculateUsers(String param) {
Set<Long> postIds = StrUtils.splitToLongSet(param);
List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(postIds);
return convertSet(users, AdminUserRespDTO::getId);

View File

@ -6,7 +6,6 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidat
import cn.iocoder.yudao.module.system.api.permission.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component;
import java.util.Set;
@ -36,16 +35,7 @@ public class BpmTaskCandidateRoleStrategy implements BpmTaskCandidateStrategy {
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
return calculateUsersByParam(param);
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
return calculateUsersByParam(param);
}
private Set<Long> calculateUsersByParam(String param) {
public Set<Long> calculateUsers(String param) {
Set<Long> roleIds = StrUtils.splitToLongSet(param);
return permissionApi.getUserRoleIdListByRoleIds(roleIds);
}

View File

@ -63,6 +63,15 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCan
return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
}
@Override
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
DeptRespDTO dept = getStartUserDept(startUserId);
if (dept == null) {
return new HashSet<>();
}
return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
}
/**
* 获取发起人的部门
*

View File

@ -56,6 +56,16 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
// 获取发起人的部门负责人
return getStartUserDeptLeader(startUserId, param);
}
@Override
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
// 获取发起人的部门负责人
return getStartUserDeptLeader(startUserId, param);
}
private Set<Long> getStartUserDeptLeader(Long startUserId, String param) {
DeptRespDTO dept = getStartUserDept(startUserId);
if (dept == null) {
return new HashSet<>();

View File

@ -49,6 +49,18 @@ public class BpmTaskCandidateStartUserSelectStrategy implements BpmTaskCandidate
return new LinkedHashSet<>(assignees);
}
@Override
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
if (processInstance == null) {
return Collections.emptySet();
}
Map<String, List<Long>> startUserSelectAssignees = FlowableUtils.getStartUserSelectAssignees(processInstance);
Assert.notNull(startUserSelectAssignees, "流程实例({}) 的发起人自选审批人不能为空", processInstance.getId());
// 获得审批人
List<Long> assignees = startUserSelectAssignees.get(activityId);
return new LinkedHashSet<>(assignees);
}
@Override
public boolean isParamRequired() {
return false;

View File

@ -6,6 +6,7 @@ import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidat
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
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;
@ -13,7 +14,7 @@ import java.util.Set;
/**
* 发起人自己 {@link BpmTaskCandidateUserStrategy} 实现类
*
* <p>
* 适合场景用于需要发起人信息复核等场景
*
* @author jason
@ -31,7 +32,8 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate
}
@Override
public void validateParam(String param) {}
public void validateParam(String param) {
}
@Override
public boolean isParamRequired() {
@ -40,17 +42,13 @@ public class BpmTaskCandidateStartUserStrategy implements BpmTaskCandidateStrate
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
return getStartUserOfProcessInstance(execution.getProcessInstanceId());
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
return SetUtils.asSet(Long.valueOf(processInstance.getStartUserId()));
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
return getStartUserOfProcessInstance(processInstanceId);
}
private Set<Long> getStartUserOfProcessInstance(String processInstanceId) {
String startUserId = processInstanceService.getProcessInstance(processInstanceId).getStartUserId();
return SetUtils.asSet(Long.valueOf(startUserId));
public Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
return SetUtils.asSet(startUserId);
}
}

View File

@ -32,12 +32,7 @@ public class BpmTaskCandidateUserStrategy implements BpmTaskCandidateStrategy {
}
@Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) {
return StrUtils.splitToLongSet(param);
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
public Set<Long> calculateUsers(String param) {
return StrUtils.splitToLongSet(param);
}

View File

@ -94,12 +94,15 @@ public interface BpmProcessInstanceService {
// TODO @芋艿重点在 review
/**
* 获取流程实例的进度
* 获取审批详情
* <p>
* 可以是准备发起的流程, 进行中的流程, 已经结束的流程
*
* @param id 流程 Id
* @param loginUserId 登录人的用户编号
* @param reqVO 请求信息
* @return 流程实例的进度
*/
BpmProcessInstanceProgressRespVO getProcessInstanceProgress(String id);
BpmApprovalDetailRespVO getApprovalDetail(Long loginUserId, BpmApprovalDetailReqVO reqVO);
// ========== Update 写入相关方法 ==========

View File

@ -5,7 +5,7 @@ import lombok.Data;
import java.util.List;
import java.util.Set;
import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceProgressRespVO.ApproveNodeInfo;
import static cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO.ApprovalNodeInfo;
/**
* 已经进行中的审批节点 Response BO
@ -18,10 +18,10 @@ public class AlreadyRunApproveNodeRespBO {
/**
* 审批节点信息数组
*/
private List<ApproveNodeInfo> approveNodes;
private List<ApprovalNodeInfo> approveNodes;
/**
* 进行中的节点 ID 数组
* 已运行的节点 ID 数组
*/
private Set<String> runNodeIds;