scaffold-file 文件存储模块

模块概述

scaffold-file 提供统一的文件上传、存储和管理能力,采用可插拔的存储策略设计。内置本地文件存储实现,可通过实现 FileStorageService 接口扩展 MinIO、OSS 等存储方式。上传的文件按日期目录自动归档,支持文件分类、分页查询和批量删除。

功能列表

  • 文件上传:支持单文件上传,可指定文件分类
  • 文件下载:通过 HTTP 资源映射直接访问已上传文件
  • 文件管理:分页查询、按 ID 查询、单个删除、批量删除
  • 多存储策略:通过 FileStorageService 接口支持本地/MinIO/OSS 等存储后端
  • 本地文件映射FileWebConfig 自动将 URL 路径映射到本地文件目录
  • 物理文件同步删除:删除文件记录时同时删除物理文件

核心组件

类名 职责
Controller FileController 文件管理接口,路径 /v1/system/file
Service SysFileService 文件业务逻辑,协调上传、存储、记录
Storage FileStorageService 文件存储策略接口(SPI)
Storage LocalFileStorageService 本地文件存储实现
Entity SysFile 文件记录实体
Config FileProperties 文件存储配置属性
Config FileWebConfig 本地存储的 URL 到目录映射配置

配置参数

配置前缀:scaffold.file

参数 类型 默认值 说明
storage String local 存储方式:local(本地)、miniooss
maxFileSize long 52428800(50MB) 上传文件大小限制(字节)
urlPrefix String /files 文件访问 URL 前缀
local.path String ./uploads 本地存储根路径
local.urlPrefix String - 本地文件访问 URL 前缀(如 http://localhost:8080/api/files

API 接口列表

文件管理 /v1/system/file

方法 路径 说明
POST /upload 上传文件(multipart/form-data,可选参数 category 指定分类)
GET /get/{id} 根据ID查询文件信息
GET /page 分页查询文件列表
POST /delete/{id} 删除文件(同时删除物理文件)
POST /batchDelete 批量删除文件

SPI 扩展点

FileStorageService 接口

实现此接口可扩展新的存储方式(如 MinIO、OSS)。实现类使用 @ConditionalOnProperty 控制激活条件。

public interface FileStorageService {
    /** 存储文件,返回存储路径 */
    String store(MultipartFile file, String target) throws Exception;

    /** 删除文件 */
    boolean delete(String filePath);

    /** 获取存储类型标识(local/minio/oss) */
    String getStorageType();
}

扩展示例(MinIO):

@Service
@RequiredArgsConstructor
@ConditionalOnProperty(prefix = "scaffold.file", name = "storage", havingValue = "minio")
public class MinioFileStorageService implements FileStorageService {
    // 实现 store / delete / getStorageType 方法
}

使用示例

上传文件

// 前端上传文件
const formData = new FormData()
formData.append('file', file)
formData.append('category', 'avatar')
const { data } = await post('/v1/system/file/upload', formData)
// data = { id: '1234567890', fileName: 'photo.jpg', fileUrl: '/files/2026/04/26/uuid.jpg', ... }

在 Service 中使用文件上传

@Service
@RequiredArgsConstructor
public class SomeBusinessService {
    private final SysFileService sysFileService;

    public void processWithFile(MultipartFile file) {
        FileVO fileVO = sysFileService.upload(file, "contract");
        // fileVO.getFileUrl() 可用于业务记录
    }
}

本地文件访问

上传到本地存储的文件通过 FileWebConfig 映射的 URL 直接访问:

http://localhost:8080/api/files/2026/04/26/uuid.jpg

URL 路径 /files/**FileWebConfig 映射到 scaffold.file.local.path 指定的本地目录。

注意事项

  • 文件上传接口使用 multipart/form-data 格式,参数名为 file
  • category 参数为可选的文件分类标识,用于业务区分,不影响存储路径。
  • 本地存储模式下,FileWebConfig 自动注册资源处理器,将 URL 映射到本地文件目录。
  • 删除文件记录时会同步删除物理文件,不可恢复。
  • 扩展 MinIO/OSS 存储需实现 FileStorageService 接口,并通过 @ConditionalOnProperty 绑定到对应的 scaffold.file.storage 值。
  • 文件存储路径按日期自动归档:{local.path}/{yyyy/MM/dd}/{uuid}.{ext}
  • 生产环境建议使用 MinIO 或 OSS,避免本地存储的单机限制。