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() .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() .eq(ApprovalTemplateNode::getTemplateId, instance.getTemplateId()) .eq(ApprovalTemplateNode::getLevelNo, currentLevel) .orderByAsc(ApprovalTemplateNode::getId) .last("LIMIT 1") ); if (templateNode == null) { throw new RuntimeException("未找到当前层级对应的审批模板节点"); } List approvers = approvalTemplateNodeApproverService.list( new LambdaQueryWrapper() .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 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() .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 getCurrentPendingTasks(Long instanceId) { if (instanceId == null) { return List.of(); } ApprovalInstanceNode currentNode = getCurrentNode(instanceId); if (currentNode == null) { return List.of(); } return approvalTaskService.list( new LambdaQueryWrapper() .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() .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 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() .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() .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() .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 getUserAllPendingTasks(Long userId) { if (userId == null) { return List.of(); } return approvalTaskService.list( new LambdaQueryWrapper() .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 ); } }