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

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 @Getter
@AllArgsConstructor @AllArgsConstructor
public enum BpmProcessInstanceStatusEnum implements IntArrayValuable { public enum BpmProcessInstanceStatusEnum implements IntArrayValuable {
NOT_START(-1, "未开始"),
RUNNING(1, "审批中"), RUNNING(1, "审批中"),
APPROVE(2, "审批通过"), APPROVE(2, "审批通过"),
REJECT(3, "审批不通过"), REJECT(3, "审批不通过"),

View File

@ -165,12 +165,12 @@ public class BpmProcessInstanceController {
return success(processInstanceService.getProcessInstanceFormFieldsPermission(reqVO)); return success(processInstanceService.getProcessInstanceFormFieldsPermission(reqVO));
} }
@GetMapping("/get-progress") @GetMapping("/get-approval-detail")
@Operation(summary = "获得流程实例的进度") @Operation(summary = "获得审批详情")
@Parameter(name = "id", description = "流程实例的编号", required = true) @Parameter(name = "id", description = "流程实例的编号", required = true)
@PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')")
public CommonResult<BpmProcessInstanceProgressRespVO> getProcessInstanceProgress(@RequestParam("id") String id) { public CommonResult<BpmApprovalDetailRespVO> getApprovalDetail(@Valid BpmApprovalDetailReqVO reqVO) {
return success(processInstanceService.getProcessInstanceProgress(id)); 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; import java.util.List;
@Schema(description = "管理后台 - 流程实例的进度 Response VO") @Schema(description = "管理后台 - 审批详情 Response VO")
@Data @Data
public class BpmProcessInstanceProgressRespVO { public class BpmApprovalDetailRespVO {
@Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "流程实例的状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举 private Integer status; // 参见 BpmProcessInstanceStatusEnum 枚举
@Schema(description = "审批信息列表", requiredMode = Schema.RequiredMode.REQUIRED) @Schema(description = "审批信息列表", requiredMode = Schema.RequiredMode.REQUIRED)
private List<ApproveNodeInfo> approveNodes; private List<ApprovalNodeInfo> approveNodes;
@Schema(description = "审批节点信息") @Schema(description = "审批节点信息")
@Data @Data
public static class ApproveNodeInfo { public static class ApprovalNodeInfo {
@Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartUserNode") @Schema(description = "节点编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "StartUserNode")
private String id; private String id;
@ -39,7 +39,7 @@ public class BpmProcessInstanceProgressRespVO {
private LocalDateTime endTime; private LocalDateTime endTime;
@Schema(description = "审批节点的任务信息") @Schema(description = "审批节点的任务信息")
private List<ApproveTaskInfo> tasks; private List<ApprovalTaskInfo> tasks;
@Schema(description = "候选人用户列表") @Schema(description = "候选人用户列表")
private List<User> candidateUserList; // 用于未运行任务节点 private List<User> candidateUserList; // 用于未运行任务节点
@ -63,7 +63,7 @@ public class BpmProcessInstanceProgressRespVO {
@Schema(description = "审批任务信息") @Schema(description = "审批任务信息")
@Data @Data
public static class ApproveTaskInfo { public static class ApprovalTaskInfo {
@Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @Schema(description = "任务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
private String id; private String id;

View File

@ -110,7 +110,7 @@ public class BpmTaskCandidateInvoker {
// 1.3 移除发起人的用户 // 1.3 移除发起人的用户
removeStartUserIfSkip(execution, userIds); removeStartUserIfSkip(execution, userIds);
// 2. 移除被禁用的用户 // 2. 移除被禁用的用户 TODO @芋艿 移除禁用的用户是否应该放在 1.1 之后
removeDisableUsers(userIds); removeDisableUsers(userIds);
return 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 cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
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.Collections;
import java.util.Set; import java.util.Set;
/** /**
* BPM 任务的候选人的策略接口 * BPM 任务的候选人的策略接口
* * <p>
* 例如说分配审批人 * 例如说分配审批人
* *
* @author 芋道源码 * @author 芋道源码
@ -38,27 +39,43 @@ public interface BpmTaskCandidateStrategy {
return true; return true;
} }
/**
* 基于候选人参数获得任务的候选用户们
*
* @param param 执行任务
* @return 用户编号集合
*/
default Set<Long> calculateUsers(String param) {
return Collections.emptySet();
}
/** /**
* 基于执行任务获得任务的候选用户们 * 基于执行任务获得任务的候选用户们
* *
* @param execution 执行任务 * @param execution 执行任务
* @return 用户编号集合 * @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 param 节点的参数 * @param processInstance 流程实例编号
* @param activityId 活动 Id (对应 Bpmn XML id)
* @param param 节点的参数
* @return 用户编号集合 * @return 用户编号集合
*/ */
default Set<Long> calculateUsers(String processInstanceId, String param) { default Set<Long> calculateUsers(Long startUserId, ProcessInstance processInstance, String activityId, String param) {
return Collections.emptySet(); return calculateUsers(param);
} }
// TODO @芋艿后续可以抽象一个 calculateUsers(String param)默认 calculateUsers calculateUsers 调用它 // 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.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 org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Set; import java.util.Set;
@ -37,7 +36,7 @@ public class BpmTaskCandidateDeptLeaderMultiStrategy extends BpmTaskCandidateAbs
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, 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])); 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.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
@ -37,7 +36,7 @@ public class BpmTaskCandidateDeptLeaderStrategy implements BpmTaskCandidateStrat
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) { public Set<Long> calculateUsers(String param) {
Set<Long> deptIds = StrUtils.splitToLongSet(param); Set<Long> deptIds = StrUtils.splitToLongSet(param);
List<DeptRespDTO> depts = deptApi.getDeptList(deptIds); List<DeptRespDTO> depts = deptApi.getDeptList(deptIds);
return convertSet(depts, DeptRespDTO::getLeaderUserId); 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.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 jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
@ -40,12 +39,7 @@ public class BpmTaskCandidateDeptMemberStrategy implements BpmTaskCandidateStrat
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) { public Set<Long> calculateUsers(String param) {
return calculateUsers((String) null, param);
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
Set<Long> deptIds = StrUtils.splitToLongSet(param); Set<Long> deptIds = StrUtils.splitToLongSet(param);
List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(deptIds); List<AdminUserRespDTO> users = adminUserApi.getUserListByDeptIds(deptIds);
return convertSet(users, AdminUserRespDTO::getId); 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.framework.flowable.core.enums.BpmTaskCandidateStrategyEnum;
import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService; import cn.iocoder.yudao.module.bpm.service.definition.BpmUserGroupService;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Collection; import java.util.Collection;
@ -38,7 +37,7 @@ public class BpmTaskCandidateGroupStrategy implements BpmTaskCandidateStrategy {
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) { public Set<Long> calculateUsers(String param) {
Set<Long> groupIds = StrUtils.splitToLongSet(param); Set<Long> groupIds = StrUtils.splitToLongSet(param);
List<BpmUserGroupDO> groups = userGroupService.getUserGroupList(groupIds); List<BpmUserGroupDO> groups = userGroupService.getUserGroupList(groupIds);
return convertSetByFlatMap(groups, BpmUserGroupDO::getUserIds, Collection::stream); 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.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 jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
@ -40,7 +39,7 @@ public class BpmTaskCandidatePostStrategy implements BpmTaskCandidateStrategy {
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) { public Set<Long> calculateUsers(String param) {
Set<Long> postIds = StrUtils.splitToLongSet(param); Set<Long> postIds = StrUtils.splitToLongSet(param);
List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(postIds); List<AdminUserRespDTO> users = adminUserApi.getUserListByPostIds(postIds);
return convertSet(users, AdminUserRespDTO::getId); 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.PermissionApi;
import cn.iocoder.yudao.module.system.api.permission.RoleApi; import cn.iocoder.yudao.module.system.api.permission.RoleApi;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.flowable.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.Set; import java.util.Set;
@ -36,16 +35,7 @@ public class BpmTaskCandidateRoleStrategy implements BpmTaskCandidateStrategy {
} }
@Override @Override
public Set<Long> calculateUsers(DelegateExecution execution, String param) { public Set<Long> calculateUsers(String param) {
return calculateUsersByParam(param);
}
@Override
public Set<Long> calculateUsers(String processInstanceId, String param) {
return calculateUsersByParam(param);
}
private Set<Long> calculateUsersByParam(String param) {
Set<Long> roleIds = StrUtils.splitToLongSet(param); Set<Long> roleIds = StrUtils.splitToLongSet(param);
return permissionApi.getUserRoleIdListByRoleIds(roleIds); return permissionApi.getUserRoleIdListByRoleIds(roleIds);
} }

View File

@ -58,7 +58,16 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends BpmTaskCan
// 获取发起人的 multi 部门负责人 // 获取发起人的 multi 部门负责人
DeptRespDTO dept = getStartUserDept(startUserId); DeptRespDTO dept = getStartUserDept(startUserId);
if (dept == null) { if (dept == null) {
return new HashSet<>(); return new HashSet<>();
}
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)); // 参数是部门的层级 return getMultiLevelDeptLeaderIds(toList(dept.getId()), Integer.valueOf(param)); // 参数是部门的层级
} }

View File

@ -56,11 +56,21 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends BpmTaskCandidat
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId()); ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId()); 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); DeptRespDTO dept = getStartUserDept(startUserId);
if (dept == null) { if (dept == null) {
return new HashSet<>(); return new HashSet<>();
} }
Long deptLeaderId = getAssignLevelDeptLeaderId(dept, Integer.valueOf(param)); // 参数是部门的层级 Long deptLeaderId = getAssignLevelDeptLeaderId(dept, Integer.valueOf(param)); // 参数是部门的层级
return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>(); return deptLeaderId != null ? asSet(deptLeaderId) : new HashSet<>();
} }

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ import lombok.Data;
import java.util.List; import java.util.List;
import java.util.Set; 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 * 已经进行中的审批节点 Response BO
@ -18,10 +18,10 @@ public class AlreadyRunApproveNodeRespBO {
/** /**
* 审批节点信息数组 * 审批节点信息数组
*/ */
private List<ApproveNodeInfo> approveNodes; private List<ApprovalNodeInfo> approveNodes;
/** /**
* 进行中的节点 ID 数组 * 已运行的节点 ID 数组
*/ */
private Set<String> runNodeIds; private Set<String> runNodeIds;