| ¶Ô±ÈÐÂÎļþ |
| | |
| | | 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.mapper.ApprovalInstanceMapper; |
| | | import com.ruoyi.approve.pojo.ApprovalInstance; |
| | | 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 com.ruoyi.basic.dto.StorageBlobDTO; |
| | | import com.ruoyi.basic.enums.ApplicationTypeEnum; |
| | | import com.ruoyi.basic.enums.RecordTypeEnum; |
| | | import com.ruoyi.basic.utils.FileUtil; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.beans.BeanUtils; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.util.CollectionUtils; |
| | | |
| | | import java.util.Collections; |
| | | import java.util.Comparator; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * <p> |
| | | * å®¡æ¹æ¨¡æ¿æå¡å®ç°ç±» |
| | | * </p> |
| | | * |
| | | * @since 2026-05-18 11:20:08 |
| | | */ |
| | | @Service |
| | | @RequiredArgsConstructor |
| | | public class ApprovalTemplateServiceImpl extends ServiceImpl<ApprovalTemplateMapper, ApprovalTemplate> implements ApprovalTemplateService { |
| | | |
| | | private final ApprovalTemplateMapper approvalTemplateMapper; |
| | | private final ApprovalTemplateNodeService approvalTemplateNodeService; |
| | | private final ApprovalTemplateNodeApproverMapper approvalTemplateNodeApproverMapper; |
| | | private final ApprovalInstanceMapper approvalInstanceMapper; |
| | | private final FileUtil fileUtil; |
| | | |
| | | @Override |
| | | public IPage<ApprovalTemplateVo> listPage(Page<ApprovalTemplateVo> page, ApprovalTemplateDto approvalTemplateDto) { |
| | | IPage<ApprovalTemplateVo> 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<ApprovalTemplateNode>() |
| | | .eq(ApprovalTemplateNode::getTemplateId, approvalTemplateDto.getId()) |
| | | ); |
| | | approvalTemplateNodeApproverMapper.delete( |
| | | new LambdaQueryWrapper<ApprovalTemplateNodeApprover>() |
| | | .eq(ApprovalTemplateNodeApprover::getTemplateId, approvalTemplateDto.getId()) |
| | | ); |
| | | // ä¿åéä»¶ |
| | | List<StorageBlobDTO> storageBlobDTOs = approvalTemplateDto.getStorageBlobDTOs(); |
| | | if (!CollectionUtils.isEmpty(storageBlobDTOs)) { |
| | | fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.APPROVAL_TEMPLATE, approvalTemplateDto.getId(), storageBlobDTOs); |
| | | } |
| | | return approvalTemplateNodeService.saveApprovalTemplateNode( |
| | | approvalTemplateDto.getId(), |
| | | approvalTemplateDto.getNodes() |
| | | ); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean updateApprovalTemplateDto(ApprovalTemplateDto approvalTemplateDto) { |
| | | // æ£æ¥æ¨¡æ¿æ¯å¦è¢«å®¡æ¹å®ä¾å¼ç¨ |
| | | if (isTemplateReferenced(approvalTemplateDto.getId())) { |
| | | throw new RuntimeException("è¯¥å®¡æ¹æ¨¡æ¿å·²è¢«å®¡æ¹æµç¨å¼ç¨ï¼æ æ³ç¼è¾"); |
| | | } |
| | | approvalTemplateMapper.updateById(approvalTemplateDto); |
| | | approvalTemplateNodeService.remove( |
| | | new LambdaQueryWrapper<ApprovalTemplateNode>() |
| | | .eq(ApprovalTemplateNode::getTemplateId, approvalTemplateDto.getId()) |
| | | ); |
| | | approvalTemplateNodeApproverMapper.delete( |
| | | new LambdaQueryWrapper<ApprovalTemplateNodeApprover>() |
| | | .eq(ApprovalTemplateNodeApprover::getTemplateId, approvalTemplateDto.getId()) |
| | | ); |
| | | // ä¿åéä»¶ï¼ä¼å
å 餿§éä»¶ï¼ |
| | | List<StorageBlobDTO> storageBlobDTOs = approvalTemplateDto.getStorageBlobDTOs(); |
| | | if (!CollectionUtils.isEmpty(storageBlobDTOs)) { |
| | | fileUtil.saveStorageAttachment(ApplicationTypeEnum.FILE, RecordTypeEnum.APPROVAL_TEMPLATE, approvalTemplateDto.getId(), storageBlobDTOs); |
| | | } else { |
| | | // 妿åç«¯ä¼ ç©ºæ°ç»ï¼å 餿§éä»¶ |
| | | fileUtil.deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId( |
| | | ApplicationTypeEnum.FILE, RecordTypeEnum.APPROVAL_TEMPLATE, approvalTemplateDto.getId() |
| | | ); |
| | | } |
| | | return approvalTemplateNodeService.saveApprovalTemplateNode( |
| | | approvalTemplateDto.getId(), |
| | | approvalTemplateDto.getNodes() |
| | | ); |
| | | } |
| | | |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Boolean delete(List<Long> ids) { |
| | | if (ids == null || ids.isEmpty()) { |
| | | return false; |
| | | } |
| | | // æ£æ¥æ¨¡æ¿æ¯å¦è¢«å®¡æ¹å®ä¾å¼ç¨ |
| | | for (Long id : ids) { |
| | | if (isTemplateReferenced(id)) { |
| | | throw new RuntimeException("å®¡æ¹æ¨¡æ¿ï¼ID: " + id + "ï¼å·²è¢«å®¡æ¹æµç¨å¼ç¨ï¼æ æ³å é¤"); |
| | | } |
| | | } |
| | | ApprovalTemplate updateEntity = new ApprovalTemplate(); |
| | | updateEntity.setDeleted(1); |
| | | LambdaUpdateWrapper<ApprovalTemplate> 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<ApprovalTemplateVo> listApprovalTemplateVo(Integer type) { |
| | | List<ApprovalTemplate> templateList = this.list( |
| | | new LambdaQueryWrapper<ApprovalTemplate>() |
| | | .eq(ApprovalTemplate::getDeleted, 0) |
| | | .eq(ApprovalTemplate::getEnabled, 1) |
| | | .notIn(ApprovalTemplate::getBusinessType, List.of(5L, 6L, 7L)) |
| | | .orderByDesc(ApprovalTemplate::getTemplateType) |
| | | .orderByDesc(ApprovalTemplate::getId) |
| | | ); |
| | | if (CollUtil.isEmpty(templateList)) { |
| | | return Collections.emptyList(); |
| | | } |
| | | |
| | | List<ApprovalTemplateVo> 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<ApprovalTemplate>() |
| | | .eq(ApprovalTemplate::getId, id) |
| | | .eq(ApprovalTemplate::getDeleted, 0) |
| | | ); |
| | | if (template == null) { |
| | | throw new IllegalArgumentException("模æ¿ä¸åå¨"); |
| | | } |
| | | |
| | | List<ApprovalTemplateNode> nodeList = approvalTemplateNodeService.list( |
| | | new LambdaQueryWrapper<ApprovalTemplateNode>() |
| | | .eq(ApprovalTemplateNode::getTemplateId, id) |
| | | .orderByAsc(ApprovalTemplateNode::getLevelNo) |
| | | ); |
| | | |
| | | List<ApprovalTemplateNodeApprover> approverList = approvalTemplateNodeApproverMapper.selectList( |
| | | new LambdaQueryWrapper<ApprovalTemplateNodeApprover>() |
| | | .eq(ApprovalTemplateNodeApprover::getTemplateId, id) |
| | | .eq(ApprovalTemplateNodeApprover::getDeleted, 0L) |
| | | ); |
| | | |
| | | Map<Long, List<ApprovalTemplateNode>> nodeMap = nodeList.stream() |
| | | .collect(Collectors.groupingBy(ApprovalTemplateNode::getTemplateId)); |
| | | |
| | | Map<Long, List<ApprovalTemplateNodeApprover>> approverMap = approverList.stream() |
| | | .collect(Collectors.groupingBy(ApprovalTemplateNodeApprover::getNodeId)); |
| | | |
| | | return buildTemplateVo(template, nodeMap, approverMap); |
| | | } |
| | | |
| | | /** |
| | | * æ¹éå¡«å
模æ¿èç¹åèç¹å®¡æ¹äººï¼é¿å
å¾ªç¯æ¥åºã |
| | | */ |
| | | private void fillTemplateVoNodes(List<ApprovalTemplateVo> templateVos) { |
| | | if (CollUtil.isEmpty(templateVos)) { |
| | | return; |
| | | } |
| | | |
| | | List<Long> templateIds = templateVos.stream() |
| | | .map(ApprovalTemplateVo::getId) |
| | | .collect(Collectors.toList()); |
| | | |
| | | List<ApprovalTemplateNode> nodeList = approvalTemplateNodeService.list( |
| | | new LambdaQueryWrapper<ApprovalTemplateNode>() |
| | | .in(ApprovalTemplateNode::getTemplateId, templateIds) |
| | | .orderByAsc(ApprovalTemplateNode::getLevelNo) |
| | | ); |
| | | |
| | | List<ApprovalTemplateNodeApprover> approverList = approvalTemplateNodeApproverMapper.selectList( |
| | | new LambdaQueryWrapper<ApprovalTemplateNodeApprover>() |
| | | .in(ApprovalTemplateNodeApprover::getTemplateId, templateIds) |
| | | .eq(ApprovalTemplateNodeApprover::getDeleted, 0L) |
| | | ); |
| | | |
| | | Map<Long, List<ApprovalTemplateNode>> nodeMap = nodeList.stream() |
| | | .collect(Collectors.groupingBy(ApprovalTemplateNode::getTemplateId)); |
| | | |
| | | Map<Long, List<ApprovalTemplateNodeApprover>> 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<Long, List<ApprovalTemplateNode>> nodeMap, |
| | | Map<Long, List<ApprovalTemplateNodeApprover>> approverMap) { |
| | | ApprovalTemplateVo templateVo = new ApprovalTemplateVo(); |
| | | BeanUtils.copyProperties(template, templateVo); |
| | | |
| | | List<ApprovalTemplateNodeVo> 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); |
| | | // æ¥è¯¢éä»¶ |
| | | templateVo.setStorageBlobDTOs( |
| | | fileUtil.getStorageBlobVOsByApplicationAndRecordTypeAndRecordId( |
| | | ApplicationTypeEnum.FILE, RecordTypeEnum.APPROVAL_TEMPLATE, template.getId() |
| | | ) |
| | | ); |
| | | return templateVo; |
| | | } |
| | | |
| | | private ApprovalTemplateNodeVo buildNodeVo(ApprovalTemplateNode node, |
| | | Map<Long, List<ApprovalTemplateNodeApprover>> approverMap) { |
| | | ApprovalTemplateNodeVo nodeVo = new ApprovalTemplateNodeVo(); |
| | | BeanUtils.copyProperties(node, nodeVo); |
| | | |
| | | List<ApprovalTemplateNodeApproverVo> 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; |
| | | } |
| | | |
| | | /** |
| | | * æ£æ¥å®¡æ¹æ¨¡æ¿æ¯å¦è¢«å®¡æ¹å®ä¾å¼ç¨ |
| | | * @param templateId 模æ¿ID |
| | | * @return true 表示被å¼ç¨ï¼false 表示æªè¢«å¼ç¨ |
| | | */ |
| | | private boolean isTemplateReferenced(Long templateId) { |
| | | if (templateId == null) { |
| | | return false; |
| | | } |
| | | Long count = approvalInstanceMapper.selectCount( |
| | | new LambdaQueryWrapper<ApprovalInstance>() |
| | | .eq(ApprovalInstance::getTemplateId, templateId) |
| | | .eq(ApprovalInstance::getDeleted, 0) |
| | | ); |
| | | return count != null && count > 0; |
| | | } |
| | | } |