chenhj
2026-04-25 2ec6b477938b95608873feefa819c687d69c4a88
src/main/java/com/ruoyi/basic/utils/FileUtil.java
@@ -55,9 +55,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("文件用途不能为空");
        }
@@ -69,6 +66,9 @@
        }
        // 删除旧附件信息
        deleteStorageAttachmentsByApplicationAndRecordTypeAndRecordId(application, recordType, recordId);
        if (CollectionUtils.isEmpty(storageBlobDTOS)) {
            return;
        }
        List<StorageAttachment> storageAttachments = new ArrayList<>();
        for (StorageBlobDTO storageBlobDTO : storageBlobDTOS) {
            StorageAttachment storageAttachment = new StorageAttachment();
@@ -608,8 +608,28 @@
        if (storageBlob == null || !StringUtils.hasText(storageBlob.getUidFilename())) {
            throw new IllegalArgumentException("文件信息不完整");
        }
        String domain = StringUtils.trimTrailingCharacter(properties.getDomain(), '/');
        String prefix = properties.getUrlPrefix().startsWith("/") ? properties.getUrlPrefix() : "/" + properties.getUrlPrefix();
        String normalizedActionPath = StringUtils.hasText(actionPath) ? actionPath : "/preview/";
        if (!normalizedActionPath.startsWith("/")) {
            normalizedActionPath = "/" + normalizedActionPath;
        }
        if (!normalizedActionPath.endsWith("/")) {
            normalizedActionPath = normalizedActionPath + "/";
        }
        String baseUrl = domain + prefix + normalizedActionPath + storageBlob.getUidFilename();
        // -1 表示永久有效,不生成 token,改为 publicKey 组合校验
        if (expired != null && BigDecimal.valueOf(-1L).compareTo(expired) == 0) {
            if (!StringUtils.hasText(storageBlob.getResourceKey())) {
                throw new IllegalArgumentException("公开链接缺少publicKey");
            }
            return baseUrl + "?publicKey=" + storageBlob.getResourceKey();
        }
        long now = System.currentTimeMillis();
        long expiredMillis = expired.multiply(new BigDecimal("60000")).longValue();
        BigDecimal expiredValue = expired == null ? new BigDecimal("120") : expired;
        long expiredMillis = expiredValue.multiply(new BigDecimal("60000")).longValue();
        if (expiredMillis <= 0L) {
            expiredMillis = 2L * 60L * 60L * 1000L;
        }
@@ -626,16 +646,7 @@
                .signWith(key)            // 重点:传入上面生成的 key 对象,而不是 String
                .compact();
        cacheTokenUsage(token, expiredMillis);
        String domain = StringUtils.trimTrailingCharacter(properties.getDomain(), '/');
        String prefix = properties.getUrlPrefix().startsWith("/") ? properties.getUrlPrefix() : "/" + properties.getUrlPrefix();
        String normalizedActionPath = StringUtils.hasText(actionPath) ? actionPath : "/preview/";
        if (!normalizedActionPath.startsWith("/")) {
            normalizedActionPath = "/" + normalizedActionPath;
        }
        if (!normalizedActionPath.endsWith("/")) {
            normalizedActionPath = normalizedActionPath + "/";
        }
        return domain + prefix + normalizedActionPath + storageBlob.getUidFilename() + "?token=" + token;
        return baseUrl + "?token=" + token;
    }
    private void cacheTokenUsage(String token, long expiredMillis) {