2026-04-27 f8a1b2069044f16707eedaa22b57d542081d5e26
src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -1,7 +1,10 @@
package com.ruoyi.basic.utils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basic.dto.StorageAttachmentDTO;
import com.ruoyi.basic.dto.StorageAttachmentVO;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.dto.StorageBlobVO;
@@ -80,6 +83,47 @@
    }
    /**
     * 保存附件信息
     *
     * @param recordType      关联记录类型
     * @param recordId        关联记录id
     * @param storageBlobDTOS 文件信息
     */
    public void saveStorageAttachmentByRecordTypeAndRecordId(String application,RecordTypeEnum recordType, Long recordId, List<StorageBlobDTO> storageBlobDTOS) {
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        if (recordId == null) {
            throw new RuntimeException("关联记录id不能为空");
        }
        // 删除旧附件信息
        if (application == null) {
            for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
                deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.getByType(storageBlobDTO.getApplication()), recordType, recordId);
            }
        } else {
            deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum.getByType(application), recordType, recordId);
        }
        if (CollectionUtils.isEmpty(storageBlobDTOS)) {
            deleteStorageAttachmentsByRecordTypeAndRecordId(recordType, recordId);
        }
        List<StorageAttachment> storageAttachments = new ArrayList<>();
        for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
            StorageAttachment storageAttachment = new StorageAttachment();
            storageAttachment.setApplication(Objects.requireNonNullElseGet(application, () -> ApplicationTypeEnum.getByType(storageBlobDTO.getApplication()).getType()));
            storageAttachment.setRecordType(recordType.getType());
            storageAttachment.setRecordId(recordId);
            storageAttachment.setStorageBlobId(storageBlobDTO.getId());
            storageAttachment.setDeleted(0L);
            storageAttachments.add(storageAttachment);
        }
        storageAttachmentMapper.insert(storageAttachments);
    }
    /**
     * 删除文件信息
     *
     * @param storageBlobIds 文件id
@@ -128,6 +172,29 @@
    }
    /**
     * 通过关联记录类型、关联记录id删除文件信息
     *
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public void deleteStorageBlobsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId));
        if (CollectionUtils.isNotEmpty(storageAttachments)) {
            List<Long> storageAttachmentIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId)
                    .collect(Collectors.toList());
            deleteStorageBlobsByStorageAttachmentIds(storageAttachmentIds);
        }
    }
    /**
     * 删除文件关联信息
     *
     * @param storageAttachmentIds 文件关联id
@@ -159,6 +226,25 @@
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId)
                .eq(StorageAttachment::getApplication, application.getType()));
    }
    /**
     * 删除文件关联信息
     *
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public void deleteStorageAttachmentsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        deleteStorageBlobsByRecordTypeAndRecordId(recordType, recordId);
        storageAttachmentMapper.delete(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId));
    }
    /**
@@ -195,6 +281,46 @@
            throw new RuntimeException("文件id不能为空");
        }
        return storageAttachmentMapper.selectByIds(storageAttachmentIds);
    }
    /**
     * 通过记录类型获取文件信息 attachment(分页)
     *
     * @param page       分页参数
     * @param storageAttachmentDTO 关联记录信息
     */
    public IPage<StorageAttachmentVO> getStorageAttachmentVosPageListByApplicationAndRecordTypeAndRecordId(Page page, StorageAttachmentDTO storageAttachmentDTO) {
        // 分页查询符合条件的 StorageAttachment 记录
        LambdaQueryWrapper<StorageAttachment> queryWrapper = new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, storageAttachmentDTO.getRecordType())
                .eq(StorageAttachment::getRecordId, storageAttachmentDTO.getRecordId());
        if (storageAttachmentDTO.getApplication() != null) {
            queryWrapper.eq(StorageAttachment::getApplication, storageAttachmentDTO.getApplication());
        }
        IPage<StorageAttachmentVO> storageAttachmentIPage = storageAttachmentMapper.selectPage(page, queryWrapper);
        // 转换为 StorageAttachmentVO 并获取对应的 StorageBlobVO
        List<StorageAttachmentVO> storageAttachmentVOS = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(storageAttachmentIPage.getRecords())) {
            for (StorageAttachment storageAttachment : storageAttachmentIPage.getRecords()) {
                StorageAttachmentVO storageAttachmentVO = new StorageAttachmentVO();
                BeanUtils.copyProperties(storageAttachment, storageAttachmentVO);
                List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()));
                if (CollectionUtils.isEmpty(storageBlobVOS)) {
                    storageAttachmentVO.setStorageBlobVOS(new ArrayList<>());
                } else {
                    storageAttachmentVO.setStorageBlobVOS(storageBlobVOS);
                }
                storageAttachmentVOS.add(storageAttachmentVO);
            }
        }
        // 构建分页结果
        IPage<StorageAttachmentVO> resultPage = new Page<>();
        BeanUtils.copyProperties(storageAttachmentIPage, resultPage);
        resultPage.setRecords(storageAttachmentVOS);
        return resultPage;
    }
    /**
@@ -243,6 +369,24 @@
    }
    /**
     * 通过文件用途、关联记录类型、关联记录id获取文件关联信息 attachment
     *
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public List<StorageAttachment> getStorageAttachmentsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        return storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId));
    }
    /**
     * 通过文件用途、关联记录类型、关联记录id获取文件信息 blob
     *
     * @param application 文件用途
@@ -268,6 +412,30 @@
    }
    /**
     * 通过文件用途、关联记录类型、关联记录id获取文件信息 blob
     *
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public List<StorageBlobVO> getStorageBlobVOsByRecordTypeAndRecordId(RecordTypeEnum recordType, Long recordId) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByRecordTypeAndRecordId(recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return null;
        }
        List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
        List<StorageBlob> storageBlobs = storageBlobMapper.selectByIds(storageBlobIds);
        List<StorageBlobVO> storageBlobDTOS = new ArrayList<>();
        for (StorageBlob storageBlob : storageBlobs) {
            StorageBlobVO storageBlobVO = new StorageBlobVO();
            BeanUtils.copyProperties(storageBlob, storageBlobVO);
            storageBlobVO.setPreviewURL(buildSignedPreviewUrl(storageBlobVO));
            storageBlobVO.setDownloadURL(buildSignedDownloadUrl(storageBlobVO));
            storageBlobDTOS.add(storageBlobVO);
        }
        return storageBlobDTOS;
    }
    /**
     * 通过文件用途、关联记录类型、关联记录id获取文件信息 自定义过期时间(分钟) blob
     *
     * @param application 文件用途