chenhj
2026-04-24 0cfc88a631024726ac9350db501fc83cab1757d4
src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -2,12 +2,15 @@
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.ruoyi.basic.constant.ApplicationType;
import com.ruoyi.basic.constant.RecordType;
import com.ruoyi.basic.dto.StorageAttachmentDTO;
import com.ruoyi.basic.dto.StorageAttachmentVO;
import com.ruoyi.basic.dto.StorageBlobDTO;
import com.ruoyi.basic.dto.StorageBlobVO;
import com.ruoyi.basic.enums.ApplicationTypeEnum;
import com.ruoyi.basic.enums.RecordTypeEnum;
import com.ruoyi.basic.mapper.StorageAttachmentMapper;
import com.ruoyi.basic.mapper.StorageBlobMapper;
import com.ruoyi.basic.pojo.StorageAttachment;
import com.ruoyi.basic.pojo.StorageBlob;
import com.ruoyi.common.config.FileProperties;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
@@ -34,6 +37,7 @@
    private final FileProperties properties;
    private final StorageAttachmentMapper storageAttachmentMapper;
    private final StringRedisTemplate stringRedisTemplate;
    private final StorageBlobMapper storageBlobMapper;
    private static final String TOKEN_USAGE_KEY_PREFIX = "file:token:usage:";
    private static final DateTimeFormatter YEAR_PATH_FORMATTER = DateTimeFormatter.ofPattern("yyyy");
@@ -45,16 +49,16 @@
     * @param application     文件用途
     * @param recordType      关联记录类型
     * @param recordId        关联记录id
     * @param storageBlobVOS 文件信息
     * @param storageBlobDTOS 文件信息
     */
    public void saveStorageAttachment(ApplicationType application, RecordType recordType, Long recordId, List<StorageBlobVO> storageBlobVOS) {
        if (CollectionUtils.isEmpty(storageBlobVOS)) {
    public void saveStorageAttachment(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, List<StorageBlobDTO> storageBlobDTOS) {
        if (CollectionUtils.isEmpty(storageBlobDTOS)) {
            throw new RuntimeException("文件信息不能为空");
        }
        if (!application.isValid()) {
        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (!recordType.isValid()) {
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        if (recordId == null || recordId <= 0) {
@@ -63,16 +67,16 @@
        // 删除旧附件信息
        deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        List<StorageAttachment> storageAttachments = new ArrayList<>();
        for (StorageBlobVO storageBlobVO : storageBlobVOS) {
        for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
            StorageAttachment storageAttachment = new StorageAttachment();
            storageAttachment.setApplication(application.getType());
            storageAttachment.setRecordType(recordType.getType());
            storageAttachment.setRecordId(recordId);
            storageAttachment.setStorageBlobId(storageBlobVO.getId());
            storageAttachment.setStorageBlobId(storageBlobDTO.getId());
            storageAttachment.setDeleted(0L);
            storageAttachments.add(storageAttachment);
        }
        // todo fileChange
//        storageAttachmentMapper.insert(storageAttachments);
        storageAttachmentMapper.insert(storageAttachments);
    }
    /**
@@ -81,8 +85,7 @@
     * @param storageBlobIds 文件id
     */
    public void deleteStorageBlobs(List<Long> storageBlobIds) {
        // todo fileChange
//        storageBlobMapper.deleteByIds(storageBlobIds);
        storageBlobMapper.deleteByIds(storageBlobIds);
    }
    /**
@@ -91,10 +94,9 @@
     * @param storageAttachmentIds 文件id
     */
    public void deleteStorageBlobsByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        // todo fileChange
//        List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectByIds(storageAttachmentIds);
//        List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
//        deleteStorageBlobs(storageBlobIds);
        List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectByIds(storageAttachmentIds);
        List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
        deleteStorageBlobs(storageBlobIds);
    }
    /**
@@ -102,21 +104,21 @@
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     * @param recordIds    关联记录id
     */
    public void deleteStorageBlobsByApplicationAndRecordTypeAndRecordId(ApplicationType application, RecordType recordType, Long recordId) {
        if (!application.isValid()) {
    public void deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum application, RecordTypeEnum recordType, List<Long> recordIds) {
        if (recordIds == null || recordIds.isEmpty()) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (!recordType.isValid()) {
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }
        List<StorageAttachment> storageAttachments = storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId)
                .in(StorageAttachment::getRecordId, recordIds)
                .eq(StorageAttachment::getApplication, application.getType()));
        if (CollectionUtils.isNotEmpty(storageAttachments)) {
            List<Long> storageAttachmentIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId)
@@ -132,21 +134,27 @@
     */
    public void deleteStorageAttachmentsByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        deleteStorageBlobsByStorageAttachmentIds(storageAttachmentIds);
        // todo fileChange
//        storageAttachmentMapper.deleteByIds(storageAttachmentIds);
        storageAttachmentMapper.deleteByIds(storageAttachmentIds);
    }
    public void deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationType application, RecordType recordType, Long recordId) {
        if (!application.isValid()) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (!recordType.isValid()) {
            throw new RuntimeException("关联记录类型不能为空");
        }
    /**
     * 删除文件关联信息
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public void deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }
        deleteStorageBlobsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(application, recordType, Arrays.asList(recordId));
        storageAttachmentMapper.delete(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId)
@@ -154,7 +162,31 @@
    }
    /**
     * 通过文件关联id获取文件信息
     * 批量删除文件关联信息 attachment
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordIds   关联记录id
     */
    public void deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum application, RecordTypeEnum recordType, List<Long> recordIds) {
        if (recordIds == null || recordIds.isEmpty()) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(application, recordType, recordIds);
        storageAttachmentMapper.delete(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .in(StorageAttachment::getRecordId, recordIds)
                .eq(StorageAttachment::getApplication, application.getType()));
    }
    /**
     * 通过文件关联id获取文件信息 attachment
     *
     * @param storageAttachmentIds 文件id
     */
@@ -162,27 +194,24 @@
        if (CollectionUtils.isEmpty(storageAttachmentIds)) {
            throw new RuntimeException("文件id不能为空");
        }
        // todo fileChange
//        return storageAttachmentMapper.selectByIds(storageAttachmentIds);
        return new ArrayList<>();
        return storageAttachmentMapper.selectByIds(storageAttachmentIds);
    }
    /**
     * 通过文件用途、关联记录类型、关联记录id获取文件关联信息
     * 通过文件用途、关联记录类型、关联记录id获取文件关联信息 attachment
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public List<StorageAttachment> getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationType application, RecordType recordType, Long recordId) {
        if (!application.isValid()) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (!recordType.isValid()) {
            throw new RuntimeException("关联记录类型不能为空");
        }
    public List<StorageAttachment> getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
            throw new RuntimeException("关联记录id不能为空");
        }        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        return storageAttachmentMapper.selectList(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
@@ -191,159 +220,207 @@
    }
    /**
     * 通过文件关联id获取文件信息
     * 通过文件关联id获取文件信息 blob
     *
     * @param storageAttachmentIds 文件id
     */
    public List<StorageBlobVO> getStorageBlobDTOsByStorageAttachmentIds(List<Long> storageAttachmentIds) {
    public List<StorageBlobVO> getStorageBlobVOsByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByStorageAttachmentIds(storageAttachmentIds);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return null;
        }
        List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
        // todo fileChange
//        List<StorageBlob> storageBlobs = storageBlobMapper.selectByIds(storageBlobIds);
//        List<StorageBlobDTO> storageBlobDTOS = new ArrayList<>();
//        for (StorageBlob storageBlob : storageBlobs) {
//            StorageBlobDTO storageBlobDTO = new StorageBlobDTO();
//            BeanUtils.copyProperties(storageBlob, storageBlobDTO);
//            storageBlobDTO.setPreviewURL(buildSignedPreviewUrl(storageBlobDTO));
//            storageBlobDTO.setDownloadURL(buildSignedDownloadUrl(storageBlobDTO));
//            storageBlobDTOS.add(storageBlobDTO);
//        }
        return new ArrayList<>();
        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获取文件信息存在过期时间
     * 通过文件用途、关联记录类型、关联记录id获取文件信息 blob
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     */
    public List<StorageBlobVO> getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, 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 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     * @param expired     过期时间
     */
    public List<StorageBlobVO> getStorageBlobVOsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, 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(buildSignedUrl(storageBlobVO, "/preview/", expired));
            storageBlobVO.setDownloadURL(buildSignedUrl(storageBlobVO, "/download/", expired));
            storageBlobDTOS.add(storageBlobVO);
        }
        return storageBlobDTOS;
    }
    /**
     * 通过文件关联id获取文件信息存在过期时间 自定义过期时间(分钟) blob
     *
     * @param storageAttachmentIds 文件id
     * @param expired              过期时间
     */
    public List<StorageBlobVO> getStorageBlobDTOsByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
    public List<StorageBlobVO> getStorageBlobVOsByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByStorageAttachmentIds(storageAttachmentIds);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return null;
        }
        List<Long> storageBlobIds = storageAttachments.stream().map(StorageAttachment::getStorageBlobId).collect(Collectors.toList());
        // todo fileChange
//        List<StorageBlob> storageBlobs = storageBlobMapper.selectByIds(storageBlobIds);
//        List<StorageBlobDTO> storageBlobDTOS = new ArrayList<>();
//        for (StorageBlob storageBlob : storageBlobs) {
//            StorageBlobDTO storageBlobDTO = new StorageBlobDTO();
//            BeanUtils.copyProperties(storageBlob, storageBlobDTO);
//            storageBlobDTO.setPreviewURL(buildSignedUrl(storageBlobDTO, "/preview/", expired));
//            storageBlobDTO.setDownloadURL(buildSignedUrl(storageBlobDTO, "/download/", expired));
//            storageBlobDTOS.add(storageBlobDTO);
//        }
//        return storageBlobDTOS;
        return new ArrayList<>();
        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(buildSignedUrl(storageBlobVO, "/preview/", expired));
            storageBlobVO.setDownloadURL(buildSignedUrl(storageBlobVO, "/download/", expired));
            storageBlobDTOS.add(storageBlobVO);
        }
        return storageBlobDTOS;
    }
    /**
     * 通过文件关联id获取文件信息
     * 通过文件关联id获取文件信息 attachment
     *
     * @param storageAttachmentIds 文件id
     */
    public List<StorageAttachmentDTO> getStorageAttachmentDTOsByStorageAttachmentIds(List<Long> storageAttachmentIds) {
    public List<StorageAttachmentVO> getStorageAttachmentVOSByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByStorageAttachmentIds(storageAttachmentIds);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        List<StorageAttachmentDTO> storageAttachmentDTOS = new ArrayList<>();
        List<StorageAttachmentVO> storageAttachmentVOS = new ArrayList<>();
        for (StorageAttachment storageAttachment : storageAttachments) {
            StorageAttachmentDTO storageAttachmentDTO = new StorageAttachmentDTO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentDTO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()));
            StorageAttachmentVO storageAttachmentVO = new StorageAttachmentVO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentVO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()));
            if (CollectionUtils.isEmpty(storageBlobVOS)) {
                storageAttachmentDTO.setStorageBlobVOS(new ArrayList<>());
                storageAttachmentVO.setStorageBlobVOS(new ArrayList<>());
            } else {
                storageAttachmentDTO.setStorageBlobVOS(storageBlobVOS);
                storageAttachmentVO.setStorageBlobVOS(storageBlobVOS);
            }
            storageAttachmentDTOS.add(storageAttachmentDTO);
            storageAttachmentVOS.add(storageAttachmentVO);
        }
        return storageAttachmentDTOS;
        return storageAttachmentVOS;
    }
    /**
     * 通过文件关联id获取文件信息存在过期时间
     * 通过文件关联id获取文件信息存在过期时间 自定义过期时间(分钟) attachment
     *
     * @param storageAttachmentIds 文件id
     * @param expired              过期时间
     */
    public List<StorageAttachmentDTO> getStorageAttachmentDTOsByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
    public List<StorageAttachmentVO> getStorageAttachmentVOSByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByStorageAttachmentIds(storageAttachmentIds);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        List<StorageAttachmentDTO> storageAttachmentDTOS = new ArrayList<>();
        List<StorageAttachmentVO> storageAttachmentVOS = new ArrayList<>();
        for (StorageAttachment storageAttachment : storageAttachments) {
            StorageAttachmentDTO storageAttachmentDTO = new StorageAttachmentDTO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentDTO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()), expired);
            StorageAttachmentVO storageAttachmentVO = new StorageAttachmentVO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentVO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()), expired);
            if (CollectionUtils.isEmpty(storageBlobVOS)) {
                storageAttachmentDTO.setStorageBlobVOS(new ArrayList<>());
                storageAttachmentVO.setStorageBlobVOS(new ArrayList<>());
            } else {
                storageAttachmentDTO.setStorageBlobVOS(storageBlobVOS);
                storageAttachmentVO.setStorageBlobVOS(storageBlobVOS);
            }
            storageAttachmentDTOS.add(storageAttachmentDTO);
            storageAttachmentVOS.add(storageAttachmentVO);
        }
        return storageAttachmentDTOS;
        return storageAttachmentVOS;
    }
    /**
     * 通过文件关联id获取文件信息
     * 通过文件关联id获取文件信息 attachment
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     */
    public List<StorageAttachmentDTO> getStorageAttachmentDTOsByApplicationAndRecordTypeAndRecordId(ApplicationType application, RecordType recordType, Long recordId) {
    public List<StorageAttachmentVO> getStorageAttachmentVOSByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        List<StorageAttachmentDTO> storageAttachmentDTOS = new ArrayList<>();
        List<StorageAttachmentVO> storageAttachmentVOS = new ArrayList<>();
        for (StorageAttachment storageAttachment : storageAttachments) {
            StorageAttachmentDTO storageAttachmentDTO = new StorageAttachmentDTO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentDTO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()));
            StorageAttachmentVO storageAttachmentVO = new StorageAttachmentVO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentVO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()));
            if (CollectionUtils.isEmpty(storageBlobVOS)) {
                storageAttachmentDTO.setStorageBlobVOS(new ArrayList<>());
                storageAttachmentVO.setStorageBlobVOS(new ArrayList<>());
            } else {
                storageAttachmentDTO.setStorageBlobVOS(storageBlobVOS);
                storageAttachmentVO.setStorageBlobVOS(storageBlobVOS);
            }
            storageAttachmentDTOS.add(storageAttachmentDTO);
            storageAttachmentVOS.add(storageAttachmentVO);
        }
        return storageAttachmentDTOS;
        return storageAttachmentVOS;
    }
    /**
     * 通过文件关联id获取文件信息存在过期时间
     * 通过文件关联id获取文件信息存在过期时间 自定义过期时间(分钟) attachment
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     * @param expired     过期时间
     */
    public List<StorageAttachmentDTO> getStorageAttachmentDTOsByApplicationAndRecordTypeAndRecordId(ApplicationType application, RecordType recordType, Long recordId, BigDecimal expired) {
    public List<StorageAttachmentVO> getStorageAttachmentVOSByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        List<StorageAttachmentDTO> storageAttachmentDTOS = new ArrayList<>();
        List<StorageAttachmentVO> storageAttachmentVOS = new ArrayList<>();
        for (StorageAttachment storageAttachment : storageAttachments) {
            StorageAttachmentDTO storageAttachmentDTO = new StorageAttachmentDTO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentDTO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()), expired);
            StorageAttachmentVO storageAttachmentVO = new StorageAttachmentVO();
            BeanUtils.copyProperties(storageAttachment, storageAttachmentVO);
            List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(Collections.singletonList(storageAttachment.getId()), expired);
            if (CollectionUtils.isEmpty(storageBlobVOS)) {
                storageAttachmentDTO.setStorageBlobVOS(new ArrayList<>());
                storageAttachmentVO.setStorageBlobVOS(new ArrayList<>());
            } else {
                storageAttachmentDTO.setStorageBlobVOS(storageBlobVOS);
                storageAttachmentVO.setStorageBlobVOS(storageBlobVOS);
            }
            storageAttachmentDTOS.add(storageAttachmentDTO);
            storageAttachmentVOS.add(storageAttachmentVO);
        }
        return storageAttachmentDTOS;
        return storageAttachmentVOS;
    }
    /**
@@ -353,7 +430,7 @@
     */
    public List<String> getFilePreviewURLByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        List<String> res = new ArrayList<>();
        List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(storageAttachmentIds);
        List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(storageAttachmentIds);
        for (StorageBlobVO storageBlobVO : storageBlobVOS) {
            res.add(buildSignedPreviewUrl(storageBlobVO));
        }
@@ -361,14 +438,14 @@
    }
    /**
     * 通过文件关联id获取文件预览地址存在过期时间
     * 通过文件关联id获取文件预览地址存在过期时间 自定义过期时间(分钟)
     *
     * @param storageAttachmentIds 文件关联id
     * @param expired              过期时间
     */
    public List<String> getFilePreviewURLByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
        List<String> res = new ArrayList<>();
        List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(storageAttachmentIds);
        List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(storageAttachmentIds);
        for (StorageBlobVO storageBlobVO : storageBlobVOS) {
            res.add(buildSignedUrl(storageBlobVO, "/preview/", expired));
        }
@@ -382,7 +459,7 @@
     */
    public List<String> getFileDownloadURLByStorageAttachmentIds(List<Long> storageAttachmentIds) {
        List<String> res = new ArrayList<>();
        List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(storageAttachmentIds);
        List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(storageAttachmentIds);
        for (StorageBlobVO storageBlobVO : storageBlobVOS) {
            res.add(buildSignedDownloadUrl(storageBlobVO));
        }
@@ -390,14 +467,14 @@
    }
    /**
     * 通过文件关联id获取文件下载地址存在过期时间
     * 通过文件关联id获取文件下载地址存在过期时间 自定义过期时间(分钟)
     *
     * @param storageAttachmentIds 文件关联id
     * @param expired              过期时间
     */
    public List<String> getFileDownloadURLByStorageAttachmentIds(List<Long> storageAttachmentIds, BigDecimal expired) {
        List<String> res = new ArrayList<>();
        List<StorageBlobVO> storageBlobVOS = getStorageBlobDTOsByStorageAttachmentIds(storageAttachmentIds);
        List<StorageBlobVO> storageBlobVOS = getStorageBlobVOsByStorageAttachmentIds(storageAttachmentIds);
        for (StorageBlobVO storageBlobVO : storageBlobVOS) {
            res.add(buildSignedUrl(storageBlobVO, "/download/", expired));
        }
@@ -496,7 +573,7 @@
    }
    /**
     * 压缩文件
     * 压缩文件 图片
     *
     * @param file 文件
     * @return 压缩后的文件