package com.ruoyi.approve.utils;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.ruoyi.approve.pojo.ApprovalInstance;
|
import com.ruoyi.approve.pojo.ApprovalInstanceNode;
|
import com.ruoyi.approve.pojo.ApprovalRecord;
|
import com.ruoyi.approve.pojo.ApprovalTask;
|
import com.ruoyi.approve.pojo.ApprovalTemplateNode;
|
import com.ruoyi.approve.pojo.ApprovalTemplateNodeApprover;
|
import com.ruoyi.approve.service.ApprovalInstanceNodeService;
|
import com.ruoyi.approve.service.ApprovalRecordService;
|
import com.ruoyi.approve.service.ApprovalTaskService;
|
import com.ruoyi.approve.service.ApprovalTemplateNodeApproverService;
|
import com.ruoyi.approve.service.ApprovalTemplateNodeService;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Component;
|
import org.springframework.transaction.annotation.Transactional;
|
|
import java.time.LocalDateTime;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* 审批流程节点工具类
|
*/
|
@Component
|
@RequiredArgsConstructor
|
public class ApproveProcessConfigNodeUtils {
|
|
private final ApprovalInstanceNodeService instanceNodeService;
|
private final ApprovalTaskService approvalTaskService;
|
private final ApprovalRecordService approvalRecordService;
|
private final ApprovalTemplateNodeService approvalTemplateNodeService;
|
private final ApprovalTemplateNodeApproverService approvalTemplateNodeApproverService;
|
|
/**
|
* 按当前层级创建审批节点和审批任务。
|
* 该重载会同时写入一条发起审批记录。
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public ApprovalInstanceNode createCurrentNodeAndTasks(ApprovalInstance instance) {
|
return createCurrentNodeAndTasks(instance, true);
|
}
|
|
/**
|
* 按当前层级创建审批节点和审批任务。
|
*
|
* @param instance 审批实例
|
* @param createSubmitRecord 是否创建发起审批记录
|
* @return 创建出的当前节点实例
|
*/
|
@Transactional(rollbackFor = Exception.class)
|
public ApprovalInstanceNode createCurrentNodeAndTasks(ApprovalInstance instance, boolean createSubmitRecord) {
|
if (instance == null || instance.getId() == null) {
|
throw new RuntimeException("审批实例不能为空");
|
}
|
if (instance.getTemplateId() == null) {
|
throw new RuntimeException("审批模板不能为空");
|
}
|
|
Integer currentLevel = instance.getCurrentLevel() == null ? 1 : instance.getCurrentLevel();
|
|
ApprovalInstanceNode existsNode = instanceNodeService.getOne(
|
new LambdaQueryWrapper<ApprovalInstanceNode>()
|
.eq(ApprovalInstanceNode::getInstanceId, instance.getId())
|
.eq(ApprovalInstanceNode::getLevelNo, currentLevel)
|
.eq(ApprovalInstanceNode::getDeleted, 0)
|
.last("LIMIT 1")
|
);
|
if (existsNode != null) {
|
return existsNode;
|
}
|
|
ApprovalTemplateNode templateNode = approvalTemplateNodeService.getOne(
|
new LambdaQueryWrapper<ApprovalTemplateNode>()
|
.eq(ApprovalTemplateNode::getTemplateId, instance.getTemplateId())
|
.eq(ApprovalTemplateNode::getLevelNo, currentLevel)
|
.orderByAsc(ApprovalTemplateNode::getId)
|
.last("LIMIT 1")
|
);
|
if (templateNode == null) {
|
throw new RuntimeException("未找到当前层级对应的审批模板节点");
|
}
|
|
List<ApprovalTemplateNodeApprover> approvers = approvalTemplateNodeApproverService.list(
|
new LambdaQueryWrapper<ApprovalTemplateNodeApprover>()
|
.eq(ApprovalTemplateNodeApprover::getTemplateId, instance.getTemplateId())
|
.eq(ApprovalTemplateNodeApprover::getNodeId, templateNode.getId())
|
.eq(ApprovalTemplateNodeApprover::getDeleted, 0L)
|
.orderByAsc(ApprovalTemplateNodeApprover::getSortNo)
|
);
|
if (approvers == null || approvers.isEmpty()) {
|
throw new RuntimeException("当前审批节点未配置审批人");
|
}
|
|
ApprovalInstanceNode instanceNode = new ApprovalInstanceNode();
|
instanceNode.setInstanceId(instance.getId());
|
instanceNode.setLevelNo(templateNode.getLevelNo());
|
instanceNode.setApproveType(templateNode.getApproveType());
|
instanceNode.setStatus("PENDING");
|
instanceNode.setStartTime(LocalDateTime.now());
|
instanceNode.setDeleted((byte) 0);
|
instanceNodeService.save(instanceNode);
|
|
List<ApprovalTask> taskList = new ArrayList<>(approvers.size());
|
for (ApprovalTemplateNodeApprover approver : approvers) {
|
ApprovalTask task = new ApprovalTask();
|
task.setInstanceId(instance.getId());
|
task.setNodeId(instanceNode.getId());
|
task.setLevelNo(instanceNode.getLevelNo());
|
task.setApproverId(approver.getApproverId());
|
task.setApproverName(approver.getApproverName());
|
task.setTaskStatus("PENDING");
|
task.setIsRead((byte) 0);
|
task.setDeleted((byte) 0);
|
taskList.add(task);
|
}
|
approvalTaskService.saveBatch(taskList);
|
|
if (createSubmitRecord) {
|
ApprovalRecord record = new ApprovalRecord();
|
record.setInstanceId(instance.getId());
|
record.setNodeId(instanceNode.getId());
|
record.setOperatorId(instance.getApplicantId());
|
record.setOperatorName(instance.getApplicantName());
|
record.setAction("SUBMIT");
|
record.setComment("发起审批");
|
record.setDeleted((byte) 0);
|
approvalRecordService.save(record);
|
}
|
|
return instanceNode;
|
}
|
|
/**
|
* 查询当前待处理节点。
|
*/
|
public ApprovalInstanceNode getCurrentNode(Long instanceId) {
|
if (instanceId == null) {
|
return null;
|
}
|
|
return instanceNodeService.getOne(
|
new LambdaQueryWrapper<ApprovalInstanceNode>()
|
.eq(ApprovalInstanceNode::getInstanceId, instanceId)
|
.eq(ApprovalInstanceNode::getStatus, "PENDING")
|
.eq(ApprovalInstanceNode::getDeleted, 0)
|
.orderByAsc(ApprovalInstanceNode::getLevelNo)
|
.last("LIMIT 1")
|
);
|
}
|
|
/**
|
* 查询当前审批层级。
|
*/
|
public Integer getCurrentLevel(Long instanceId) {
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
return currentNode != null ? currentNode.getLevelNo() : null;
|
}
|
|
/**
|
* 查询当前节点下的待审批任务。
|
*/
|
public List<ApprovalTask> getCurrentPendingTasks(Long instanceId) {
|
if (instanceId == null) {
|
return List.of();
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return List.of();
|
}
|
|
return approvalTaskService.list(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getInstanceId, instanceId)
|
.eq(ApprovalTask::getNodeId, currentNode.getId())
|
.eq(ApprovalTask::getTaskStatus, "PENDING")
|
.eq(ApprovalTask::getDeleted, 0)
|
.orderByAsc(ApprovalTask::getLevelNo)
|
);
|
}
|
|
/**
|
* 查询当前用户在当前节点上的待审批任务。
|
*/
|
public ApprovalTask getCurrentUserTask(Long instanceId, Long userId) {
|
if (instanceId == null || userId == null) {
|
return null;
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return null;
|
}
|
|
return approvalTaskService.getOne(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getInstanceId, instanceId)
|
.eq(ApprovalTask::getNodeId, currentNode.getId())
|
.eq(ApprovalTask::getApproverId, userId)
|
.eq(ApprovalTask::getTaskStatus, "PENDING")
|
.eq(ApprovalTask::getDeleted, 0)
|
.last("LIMIT 1")
|
);
|
}
|
|
/**
|
* 判断当前用户是否是当前审批人。
|
*/
|
public boolean isCurrentApprover(Long instanceId, Long userId) {
|
return getCurrentUserTask(instanceId, userId) != null;
|
}
|
|
/**
|
* 查询当前节点的审批人 ID 列表。
|
*/
|
public List<Long> getCurrentNodeApproverIds(Long instanceId) {
|
return getCurrentPendingTasks(instanceId).stream()
|
.map(ApprovalTask::getApproverId)
|
.distinct()
|
.collect(Collectors.toList());
|
}
|
|
/**
|
* 查询当前节点剩余待审批人数。
|
*/
|
public int getRemainingApproverCount(Long instanceId) {
|
return getCurrentPendingTasks(instanceId).size();
|
}
|
|
/**
|
* 查询当前节点已同意人数。
|
*/
|
public int getApprovedCount(Long instanceId) {
|
if (instanceId == null) {
|
return 0;
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return 0;
|
}
|
|
return Math.toIntExact(approvalTaskService.count(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getInstanceId, instanceId)
|
.eq(ApprovalTask::getNodeId, currentNode.getId())
|
.eq(ApprovalTask::getTaskStatus, "APPROVED")
|
.eq(ApprovalTask::getDeleted, 0)
|
));
|
}
|
|
/**
|
* 查询当前节点已拒绝人数。
|
*/
|
public int getRejectedCount(Long instanceId) {
|
if (instanceId == null) {
|
return 0;
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return 0;
|
}
|
|
return Math.toIntExact(approvalTaskService.count(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getInstanceId, instanceId)
|
.eq(ApprovalTask::getNodeId, currentNode.getId())
|
.eq(ApprovalTask::getTaskStatus, "REJECTED")
|
.eq(ApprovalTask::getDeleted, 0)
|
));
|
}
|
|
/**
|
* 判断当前节点是否可以流转到下一层。
|
*/
|
public boolean canProceedToNextLevel(Long instanceId, String approveType) {
|
if (instanceId == null || approveType == null) {
|
return false;
|
}
|
|
if (getRejectedCount(instanceId) > 0) {
|
return false;
|
}
|
|
int totalApproverCount = getCurrentPendingTasks(instanceId).size() + getApprovedCount(instanceId);
|
int approvedCount = getApprovedCount(instanceId);
|
|
if ("AND".equalsIgnoreCase(approveType)) {
|
return approvedCount > 0 && approvedCount == totalApproverCount;
|
}
|
if ("OR".equalsIgnoreCase(approveType)) {
|
return approvedCount > 0;
|
}
|
return false;
|
}
|
|
/**
|
* 查询当前用户在当前节点上的任务状态。
|
*/
|
public String getUserTaskStatus(Long instanceId, Long userId) {
|
if (instanceId == null || userId == null) {
|
return null;
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return null;
|
}
|
|
ApprovalTask task = approvalTaskService.getOne(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getInstanceId, instanceId)
|
.eq(ApprovalTask::getNodeId, currentNode.getId())
|
.eq(ApprovalTask::getApproverId, userId)
|
.eq(ApprovalTask::getDeleted, 0)
|
.last("LIMIT 1")
|
);
|
|
return task != null ? task.getTaskStatus() : null;
|
}
|
|
/**
|
* 查询指定用户的全部待审批任务。
|
*/
|
public List<ApprovalTask> getUserAllPendingTasks(Long userId) {
|
if (userId == null) {
|
return List.of();
|
}
|
|
return approvalTaskService.list(
|
new LambdaQueryWrapper<ApprovalTask>()
|
.eq(ApprovalTask::getApproverId, userId)
|
.eq(ApprovalTask::getTaskStatus, "PENDING")
|
.eq(ApprovalTask::getDeleted, 0)
|
.orderByDesc(ApprovalTask::getCreateTime)
|
);
|
}
|
|
/**
|
* 查询审批实例的进度摘要。
|
*/
|
public String getApprovalProgress(Long instanceId) {
|
if (instanceId == null) {
|
return "无效的审批实例";
|
}
|
|
ApprovalInstanceNode currentNode = getCurrentNode(instanceId);
|
if (currentNode == null) {
|
return "审批已完成或尚未开始";
|
}
|
|
int approvedCount = getApprovedCount(instanceId);
|
int rejectedCount = getRejectedCount(instanceId);
|
int pendingCount = getRemainingApproverCount(instanceId);
|
int totalCount = approvedCount + rejectedCount + pendingCount;
|
|
return String.format(
|
"第%d级审批:总人数=%d,已同意=%d,已拒绝=%d,待审批=%d",
|
currentNode.getLevelNo(),
|
totalCount,
|
approvedCount,
|
rejectedCount,
|
pendingCount
|
);
|
}
|
}
|