chenhj
2026-04-25 2ff9d632821b70773d5c89e924779457b6377b2d
src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -52,9 +52,6 @@
     * @param storageBlobDTOS 文件信息
     */
    public void saveStorageAttachment(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, List<StorageBlobDTO> storageBlobDTOS) {
        if (CollectionUtils.isEmpty(storageBlobDTOS)) {
            throw new RuntimeException("文件信息不能为空");
        }
        if (application == null) {
            throw new RuntimeException("文件用途不能为空");
        }
@@ -66,6 +63,9 @@
        }
        // 删除旧附件信息
        deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageBlobDTOS)) {
            return;
        }
        List<StorageAttachment> storageAttachments = new ArrayList<>();
        for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
            StorageAttachment storageAttachment = new StorageAttachment();
@@ -104,10 +104,10 @@
     *
     * @param application 文件用途
     * @param recordType  关联记录类型
     * @param recordId    关联记录id
     * @param recordIds    关联记录id
     */
    public void deleteStorageBlobsByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        if (recordId == null || recordId <= 0) {
    public void deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(ApplicationTypeEnum application, RecordTypeEnum recordType, List<Long> recordIds) {
        if (recordIds == null || recordIds.isEmpty()) {
            throw new RuntimeException("关联记录id不能为空");
        }
        if (application == null) {
@@ -118,7 +118,7 @@
        }
        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)
@@ -137,6 +137,13 @@
        storageAttachmentMapper.deleteByIds(storageAttachmentIds);
    }
    /**
     * 删除文件关联信息
     *
     * @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不能为空");
@@ -147,10 +154,34 @@
        if (recordType == null) {
            throw new RuntimeException("关联记录类型不能为空");
        }
        deleteStorageBlobsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        deleteStorageBlobsByApplicationAndRecordTypeAndRecordIds(application, recordType, Arrays.asList(recordId));
        storageAttachmentMapper.delete(new LambdaQueryWrapper<StorageAttachment>()
                .eq(StorageAttachment::getRecordType, recordType.getType())
                .eq(StorageAttachment::getRecordId, recordId)
                .eq(StorageAttachment::getApplication, application.getType()));
    }
    /**
     * 批量删除文件关联信息 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()));
    }
@@ -450,6 +481,68 @@
        return res;
    }
    /**
     * 通过文件关联id获取文件预览地址
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     */
    public List<String> getFilePreviewURLByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        return getFilePreviewURLByStorageAttachmentIds(storageAttachments.stream().map(StorageAttachment::getId).collect(Collectors.toList()));
    }
    /**
     * 通过文件关联id获取文件预览地址存在过期时间
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     * @param expired     过期时间(分钟)
     */
    public List<String> getFilePreviewURLByApplicationAndRecordTypeAndRecordIdAndExpired(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        return getFilePreviewURLByStorageAttachmentIds(storageAttachments.stream().map(StorageAttachment::getId).collect(Collectors.toList()), expired);
    }
    /**
     * 通过文件关联id获取文件下载地址
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     */
    public List<String> getFileDownloadURLByApplicationAndRecordTypeAndRecordId(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        return getFileDownloadURLByStorageAttachmentIds(storageAttachments.stream().map(StorageAttachment::getId).collect(Collectors.toList()));
    }
    /**
     * 通过文件关联id获取文件下载地址存在过期时间
     *
     * @param application 应用
     * @param recordType  记录类型
     * @param recordId    记录id
     * @param expired     过期时间(分钟)
     */
    public List<String> getFileDownloadURLByApplicationAndRecordTypeAndRecordIdAndExpired(ApplicationTypeEnum application, RecordTypeEnum recordType, Long recordId, BigDecimal expired) {
        List<StorageAttachment> storageAttachments = getStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageAttachments)) {
            return new ArrayList<>();
        }
        return getFileDownloadURLByStorageAttachmentIds(storageAttachments.stream().map(StorageAttachment::getId).collect(Collectors.toList()), expired);
    }
    public String buildSignedPreviewUrl(StorageBlobVO storageBlob) {
        return buildSignedUrl(storageBlob, "/preview/", properties.getExpired());
    }