package com.ruoyi.approve.service.impl; import cn.hutool.core.collection.CollUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.ruoyi.approve.bean.dto.ApprovalTemplateDto; import com.ruoyi.approve.bean.vo.ApprovalTemplateNodeApproverVo; import com.ruoyi.approve.bean.vo.ApprovalTemplateNodeVo; import com.ruoyi.approve.bean.vo.ApprovalTemplateVo; import com.ruoyi.approve.mapper.ApprovalTemplateMapper; import com.ruoyi.approve.mapper.ApprovalTemplateNodeApproverMapper; import com.ruoyi.approve.pojo.ApprovalTemplate; import com.ruoyi.approve.pojo.ApprovalTemplateNode; import com.ruoyi.approve.pojo.ApprovalTemplateNodeApprover; import com.ruoyi.approve.service.ApprovalTemplateNodeService; import com.ruoyi.approve.service.ApprovalTemplateService; import lombok.RequiredArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** *

* 审批模板服务实现类 *

* * @since 2026-05-18 11:20:08 */ @Service @RequiredArgsConstructor public class ApprovalTemplateServiceImpl extends ServiceImpl implements ApprovalTemplateService { private final ApprovalTemplateMapper approvalTemplateMapper; private final ApprovalTemplateNodeService approvalTemplateNodeService; private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper; @Override public IPage listPage(Page page, ApprovalTemplateDto approvalTemplateDto) { IPage approvalTemplateVoIPage = approvalTemplateMapper.listPage(page, approvalTemplateDto); fillTemplateVoNodes(approvalTemplateVoIPage.getRecords()); return approvalTemplateVoIPage; } @Override @Transactional(rollbackFor = Exception.class) public Boolean saveApprovalTemplateDto(ApprovalTemplateDto approvalTemplateDto) { approvalTemplateMapper.insert(approvalTemplateDto); approvalTemplateNodeService.remove( new LambdaQueryWrapper() .eq(ApprovalTemplateNode::getTemplateId, approvalTemplateDto.getId()) ); approvalTemplateNodeApproverMapper.delete( new LambdaQueryWrapper() .eq(ApprovalTemplateNodeApprover::getTemplateId, approvalTemplateDto.getId()) ); return approvalTemplateNodeService.saveApprovalTemplateNode( approvalTemplateDto.getId(), approvalTemplateDto.getNodes() ); } @Override public Boolean updateApprovalTemplateDto(ApprovalTemplateDto approvalTemplateDto) { approvalTemplateMapper.updateById(approvalTemplateDto); approvalTemplateNodeService.remove( new LambdaQueryWrapper() .eq(ApprovalTemplateNode::getTemplateId, approvalTemplateDto.getId()) ); approvalTemplateNodeApproverMapper.delete( new LambdaQueryWrapper() .eq(ApprovalTemplateNodeApprover::getTemplateId, approvalTemplateDto.getId()) ); return approvalTemplateNodeService.saveApprovalTemplateNode( approvalTemplateDto.getId(), approvalTemplateDto.getNodes() ); } @Transactional(rollbackFor = Exception.class) public Boolean delete(List ids) { if (ids == null || ids.isEmpty()) { return false; } ApprovalTemplate updateEntity = new ApprovalTemplate(); updateEntity.setDeleted(1); LambdaUpdateWrapper updateWrapper = Wrappers.lambdaUpdate(); updateWrapper.in(ApprovalTemplate::getId, ids) .eq(ApprovalTemplate::getDeleted, 0); int rows = approvalTemplateMapper.update(updateEntity, updateWrapper); return rows == ids.size(); } @Override public List listApprovalTemplateVo(Integer type) { List templateList = this.list( new LambdaQueryWrapper() .eq(ApprovalTemplate::getDeleted, 0) .eq(ApprovalTemplate::getEnabled, 1) .orderByDesc(ApprovalTemplate::getTemplateType) .orderByDesc(ApprovalTemplate::getId) ); if (CollUtil.isEmpty(templateList)) { return Collections.emptyList(); } List templateVos = templateList.stream() .map(template -> { ApprovalTemplateVo templateVo = new ApprovalTemplateVo(); BeanUtils.copyProperties(template, templateVo); return templateVo; }) .collect(Collectors.toList()); fillTemplateVoNodes(templateVos); return templateVos; } @Override public ApprovalTemplateVo getApprovalTemplateVoById(Long id) { if (id == null) { throw new IllegalArgumentException("参数 id 不能为空"); } ApprovalTemplate template = this.getOne( new LambdaQueryWrapper() .eq(ApprovalTemplate::getId, id) .eq(ApprovalTemplate::getDeleted, 0) ); if (template == null) { throw new IllegalArgumentException("模板不存在"); } List nodeList = approvalTemplateNodeService.list( new LambdaQueryWrapper() .eq(ApprovalTemplateNode::getTemplateId, id) .orderByAsc(ApprovalTemplateNode::getLevelNo) ); List approverList = approvalTemplateNodeApproverMapper.selectList( new LambdaQueryWrapper() .eq(ApprovalTemplateNodeApprover::getTemplateId, id) .eq(ApprovalTemplateNodeApprover::getDeleted, 0L) ); Map> nodeMap = nodeList.stream() .collect(Collectors.groupingBy(ApprovalTemplateNode::getTemplateId)); Map> approverMap = approverList.stream() .collect(Collectors.groupingBy(ApprovalTemplateNodeApprover::getNodeId)); return buildTemplateVo(template, nodeMap, approverMap); } /** * 批量填充模板节点及节点审批人,避免循环查库。 */ private void fillTemplateVoNodes(List templateVos) { if (CollUtil.isEmpty(templateVos)) { return; } List templateIds = templateVos.stream() .map(ApprovalTemplateVo::getId) .collect(Collectors.toList()); List nodeList = approvalTemplateNodeService.list( new LambdaQueryWrapper() .in(ApprovalTemplateNode::getTemplateId, templateIds) .orderByAsc(ApprovalTemplateNode::getLevelNo) ); List approverList = approvalTemplateNodeApproverMapper.selectList( new LambdaQueryWrapper() .in(ApprovalTemplateNodeApprover::getTemplateId, templateIds) .eq(ApprovalTemplateNodeApprover::getDeleted, 0L) ); Map> nodeMap = nodeList.stream() .collect(Collectors.groupingBy(ApprovalTemplateNode::getTemplateId)); Map> approverMap = approverList.stream() .collect(Collectors.groupingBy(ApprovalTemplateNodeApprover::getNodeId)); templateVos.forEach(templateVo -> templateVo.setNodes( nodeMap.getOrDefault(templateVo.getId(), Collections.emptyList()) .stream() .sorted(Comparator.comparing( ApprovalTemplateNode::getLevelNo, Comparator.nullsLast(Integer::compareTo) )) .map(node -> buildNodeVo(node, approverMap)) .collect(Collectors.toList()) )); } private ApprovalTemplateVo buildTemplateVo(ApprovalTemplate template, Map> nodeMap, Map> approverMap) { ApprovalTemplateVo templateVo = new ApprovalTemplateVo(); BeanUtils.copyProperties(template, templateVo); List nodeVos = nodeMap .getOrDefault(template.getId(), Collections.emptyList()) .stream() .sorted(Comparator.comparing( ApprovalTemplateNode::getLevelNo, Comparator.nullsLast(Integer::compareTo) )) .map(node -> buildNodeVo(node, approverMap)) .collect(Collectors.toList()); templateVo.setNodes(nodeVos); return templateVo; } private ApprovalTemplateNodeVo buildNodeVo(ApprovalTemplateNode node, Map> approverMap) { ApprovalTemplateNodeVo nodeVo = new ApprovalTemplateNodeVo(); BeanUtils.copyProperties(node, nodeVo); List approverVos = approverMap .getOrDefault(node.getId(), Collections.emptyList()) .stream() .sorted(Comparator.comparing( ApprovalTemplateNodeApprover::getSortNo, Comparator.nullsLast(Integer::compareTo) )) .map(this::buildApproverVo) .collect(Collectors.toList()); nodeVo.setApprovers(approverVos); return nodeVo; } private ApprovalTemplateNodeApproverVo buildApproverVo(ApprovalTemplateNodeApprover approver) { ApprovalTemplateNodeApproverVo approverVo = new ApprovalTemplateNodeApproverVo(); BeanUtils.copyProperties(approver, approverVo); return approverVo; } }