9 小时以前 9bad721754fe8bbe2e5f459d0706e0fefac569f3
yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/storage/SystemStorageBlobServiceImpl.java
@@ -20,6 +20,7 @@
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@@ -84,6 +85,43 @@
            result.add(blobRespVO);
        }
        return result;
    }
    @Override
    public SystemStorageBlobRespVO saveBlob(byte[] content, String originalFileName, String contentType, Boolean isPublic) {
        if (content == null || content.length == 0) {
            throw exception(STORAGE_FILE_EMPTY);
        }
        // 文件名来自调用方,仍要 cleanPath:它会拼进落盘文件名,不能带出目录层级
        String safeName = StringUtils.hasText(originalFileName)
                ? StringUtils.cleanPath(originalFileName)
                : UUID.randomUUID().toString();
        String fileName = UUID.randomUUID() + "_" + safeName;
        String relativePath = fileUtil.buildRelativePath();
        File targetDirectory = new File(properties.getPath(), relativePath);
        if (!targetDirectory.exists() && !targetDirectory.mkdirs()) {
            throw exception(STORAGE_BLOB_UPLOAD_FAILED);
        }
        File dest = new File(targetDirectory, fileName);
        try {
            Files.write(dest.toPath(), content);
            SystemStorageBlobRespVO blobRespVO = persistBlob(contentType, safeName, fileName,
                    relativePath, content.length, isPublic);
            if (blobRespVO == null || blobRespVO.getId() == null) {
                throw exception(STORAGE_BLOB_UPLOAD_FAILED);
            }
            return blobRespVO;
        } catch (RuntimeException e) {
            if (dest.exists()) {
                dest.delete();
            }
            throw e;
        } catch (IOException e) {
            if (dest.exists()) {
                dest.delete();
            }
            throw exception(STORAGE_BLOB_UPLOAD_FAILED);
        }
    }
    @Override
@@ -157,12 +195,24 @@
    private SystemStorageBlobRespVO createStorageBlob(MultipartFile file, String originalFileName,
                                                      String fileName, String relativePath, Boolean isPublic) {
        return persistBlob(file.getContentType(), originalFileName, fileName,
                relativePath, file.getSize(), isPublic);
    }
    /**
     * 落库 + 拼预览/下载地址。
     * <p>
     * 两条上传路径({@link #upload} 的 MultipartFile、{@link #saveBlob} 的 byte[])共用这一步,
     * 只在这里维护签名 URL 的拼法,避免两处各写一遍后地址格式走偏。
     */
    private SystemStorageBlobRespVO persistBlob(String contentType, String originalFileName, String fileName,
                                                String relativePath, long byteSize, Boolean isPublic) {
        SystemStorageBlobDO blob = new SystemStorageBlobDO();
        blob.setResourceKey(UUID.randomUUID().toString().replace("-", ""));
        blob.setContentType(file.getContentType());
        blob.setContentType(contentType);
        blob.setOriginalFilename(originalFileName);
        blob.setUidFilename(fileName);
        blob.setByteSize(file.getSize());
        blob.setByteSize(byteSize);
        blob.setPath(relativePath);
        storageBlobMapper.insert(blob);