16 KiB
datai-scene-file 模块详细文档
模块概述
datai-scene-file 是 Datai 项目中的文件存储管理模块,提供统一的文件上传、下载、预览和管理功能。该模块支持多种存储方式,包括本地存储、MinIO 分布式存储和阿里云 OSS 对象存储。
模块结构
datai-scene-file/
├── datai-file-common/ # 公共依赖模块
├── datai-file-local/ # 本地文件存储
├── datai-file-minio/ # MinIO 分布式文件存储
├── datai-file-aliyun-oss/ # 阿里云 OSS 对象存储
└── datai-file-starter/ # 文件模块启动器
1. datai-file-common 模块
1.1 模块描述
公共依赖模块,定义了文件存储的核心接口、实体类、服务类和工具类。
1.2 核心类
1.2.1 实体类
SysFileInfo - 文件信息实体类
- 位置:
com.datai.file.domain.SysFileInfo - 字段:
fileId: 文件主键fileName: 原始文件名filePath: 统一逻辑路径(/开头)storageType: 存储类型(local/minio/oss)fileType: 文件类型/后缀fileSize: 文件大小(字节)md5: 文件MD5delFlag: 删除标志(0代表存在 2代表删除)
SysFilePartETag - 分片上传标识类
- 位置:
com.datai.file.domain.SysFilePartETag - 字段:
partNumber: 分片序号eTag: 分片ETagpartSize: 分片大小partCRC: 分片CRCfileSize: 文件大小filePath: 文件路径taskId: 任务ID
StorageEntity - 存储实体类
- 位置:
com.datai.file.storage.StorageEntity - 字段:
inputStream: 文件输入流byteCount: 字节数filePath: 文件路径
1.2.2 接口类
StorageBucket - 存储桶接口
- 位置:
com.datai.file.storage.StorageBucket - 核心方法:
get(String filepath): 获取文件实例put(String filePath, MultipartFile file): 上传文件remove(String filePath): 删除文件generatePresignedUrl(String filePath, int expireTime): 生成预签名URLgeneratePublicUrl(String filePath): 生成公开访问URLgetPermission(): 获取存储渠道权限initMultipartUpload(String filePath): 初始化分片上传uploadPart(...): 上传分片completeMultipartUpload(...): 完成分片上传
StorageFactory<P, S extends StorageBucket> - 存储工厂抽象类
- 位置:
com.datai.file.storage.StorageFactory - 核心方法:
createBucket(String name, P props): 创建存储桶(抽象方法)validateBucket(S bucket): 验证存储桶(抽象方法)getPrimaryBucket(): 获取主存储桶getBucket(String bucketName): 获取指定存储桶
1.2.3 服务类
StorageService - 存储操作业务类
- 位置:
com.datai.file.service.StorageService - 核心功能:
- 文件上传(支持MD5去重)
- 文件下载
- 文件删除
- 生成访问链接
- 分片上传管理
ISysFileInfoService - 文件信息服务接口
- 位置:
com.datai.file.service.ISysFileInfoService - 核心方法:
selectSysFileInfoByFileId(Long fileId): 查询文件selectSysFileInfoList(SysFileInfo sysFileInfo): 查询文件列表insertSysFileInfo(SysFileInfo sysFileInfo): 新增文件updateSysFileInfo(SysFileInfo sysFileInfo): 修改文件deleteSysFileInfoByFileIds(Long[] fileIds): 批量删除文件buildSysFileInfo(MultipartFile file): 构建文件信息
1.2.4 工具类
StorageUtils - 存储工具类
- 位置:
com.datai.file.utils.StorageUtils - 核心方法:
getPrimaryStorageType(): 获取主存储类型getPrimaryStorageBucket(): 获取主存储桶getStorageBucket(String storageType, String bucketName): 获取指定存储桶getClientList(): 获取所有可用存储渠道及其存储桶列表
FileOperateUtils - 文件操作工具类
- 位置:
com.datai.file.utils.FileOperateUtils - 核心方法:
upload(MultipartFile file): 上传文件(默认配置)upload(String filePath, MultipartFile file): 指定路径上传downLoad(String filePath, OutputStream outputStream): 下载文件downLoad(String filePath, HttpServletResponse response): 下载文件到响应deleteFile(String filePath): 删除文件getURL(String filePath): 获取文件访问链接
1.2.5 Mapper接口
SysFileInfoMapper - 文件Mapper接口
- 位置:
com.datai.file.mapper.SysFileInfoMapper - 方法:
selectSysFileInfoByFileId(Long fileId): 查询单个文件selectSysFileInfoList(SysFileInfo sysFileInfo): 查询文件列表insertSysFileInfo(SysFileInfo sysFileInfo): 新增文件updateSysFileInfo(SysFileInfo sysFileInfo): 修改文件deleteSysFileInfoByFileId(Long fileId): 删除单个文件deleteSysFileInfoByFileIds(Long[] fileIds): 批量删除文件
2. datai-file-local 模块
2.1 模块描述
本地文件存储实现,基于文件系统进行文件存储和管理。
2.2 核心类
2.2.1 配置类
LocalBucketFactory - 本地存储桶工厂
- 位置:
com.datai.file.local.config.LocalBucketFactory - 继承:
StorageFactory<LocalBucketProperties, LocalBucket> - 注解:
@Configuration("local"),@ConfigurationProperties("local") - 条件:
@ConditionalOnProperty(prefix = "local", name = "enable", havingValue = "true") - 功能:
- 创建本地存储桶
- 配置静态资源访问路径
LocalBucketProperties - 本地存储桶属性
- 位置:
com.datai.file.local.config.LocalBucketProperties - 字段:
path: 存储路径permission: 权限(public/private)api: API访问路径
2.2.2 实现类
LocalBucket - 本地存储桶实现
- 位置:
com.datai.file.local.domain.LocalBucket - 实现:
StorageBucket - 字段:
bucketName: 存储桶名称basePath: 基础路径permission: 权限api: API路径
- 核心功能:
- 文件上传到本地文件系统
- 从本地文件系统下载文件
- 删除本地文件
- 生成预签名URL(带MD5签名)
- 生成公开访问URL
- 分片上传支持(使用临时目录)
3. datai-file-minio 模块
3.1 模块描述
MinIO 分布式文件存储实现,基于 MinIO 对象存储服务。
3.2 核心类
3.2.1 配置类
MinioBucketFactory - MinIO存储桶工厂
- 位置:
com.datai.file.minio.config.MinioBucketFactory - 继承:
StorageFactory<MinioBucketProperties, MinioBucket> - 注解:
@Configuration("minio"),@ConfigurationProperties("minio") - 条件:
@ConditionalOnProperty(prefix = "minio", name = "enable", havingValue = "true") - 功能:
- 创建MinIO客户端
- 验证存储桶是否存在
MinioBucketProperties - MinIO存储桶属性
- 位置:
com.datai.file.minio.config.MinioBucketProperties - 字段:
permission: 权限url: MinIO服务地址accessKey: 访问密钥secretKey: 密钥bucketName: 存储桶名称
3.2.2 实现类
MinioBucket - MinIO存储桶实现
- 位置:
com.datai.file.minio.domain.MinioBucket - 实现:
StorageBucket - 字段:
url: 服务地址permission: 权限client: MinIO客户端bucketName: 存储桶名称
- 核心功能:
- 文件上传到MinIO
- 从MinIO下载文件
- 删除MinIO文件
- 生成预签名URL
- 生成公开访问URL
- 分片上传支持(使用MinIO分片API)
MinioEntityVO - MinIO实体VO
- 位置:
com.datai.file.minio.domain.MinioEntityVO - 继承:
StorageEntity - 字段:
object: 对象名称headers: 响应头bucket: 存储桶region: 区域
3.2.3 异常类
MinioClientErrorException - MinIO客户端错误异常 MinioClientNotFundException - MinIO客户端未找到异常
4. datai-file-aliyun-oss 模块
4.1 模块描述
阿里云 OSS 对象存储实现,基于阿里云对象存储服务。
4.2 核心类
4.2.1 配置类
AliOssBucketFactory - 阿里云OSS存储桶工厂
- 位置:
com.datai.file.aliyun.oss.config.AliOssBucketFactory - 继承:
StorageFactory<AliOssBucketProperties, AliOssBucket> - 注解:
@Configuration("oss"),@ConfigurationProperties(prefix = "oss") - 条件:
@ConditionalOnProperty(prefix = "oss", name = "enable", havingValue = "true") - 功能:
- 创建阿里云OSS客户端
- 验证存储桶是否存在
AliOssBucketProperties - 阿里云OSS存储桶属性
- 位置:
com.datai.file.aliyun.oss.config.AliOssBucketProperties - 字段:
permission: 权限endpoint: 服务端点accessKeyId: 访问密钥IDaccessKeySecret: 访问密钥bucketName: 存储桶名称
4.2.2 实现类
AliOssBucket - 阿里云OSS存储桶实现
- 位置:
com.datai.file.aliyun.oss.domain.AliOssBucket - 实现:
StorageBucket - 字段:
bucketName: 存储桶名称client: OSS客户端permission: 权限endpoint: 服务端点
- 核心功能:
- 文件上传到OSS
- 从OSS下载文件
- 删除OSS文件
- 生成预签名URL
- 生成公开访问URL
- 分片上传支持(使用OSS分片API)
AliOssEntityVO - 阿里云OSS实体VO
- 位置:
com.datai.file.aliyun.oss.domain.AliOssEntityVO - 继承:
StorageEntity - 字段:
key: 对象键bucketName: 存储桶名称metadata: 对象元数据
4.2.3 异常类
AliOssClientErrorException - 阿里云OSS客户端错误异常 AliOssClientNotFundException - 阿里云OSS客户端未找到异常
5. datai-file-starter 模块
5.1 模块描述
文件模块启动器,集成所有存储实现并提供统一的REST API接口。
5.2 核心类
5.2.1 Controller类
FileController - 文件操作控制器
- 位置:
com.datai.file.controller.FileController - 路径:
/file - 核心接口:
| 接口路径 | 方法 | 描述 |
|---|---|---|
/file/client-list |
GET | 获取所有可用存储渠道及其client列表 |
/file/upload |
POST | 统一上传接口(使用默认存储) |
/file/{storageType}/{bucketName}/upload |
POST | 指定存储上传接口 |
/file/download |
GET | 统一下载接口(使用默认存储) |
/file/{storageType}/{bucketName}/download |
GET | 指定存储下载接口 |
/file/preview |
GET | 统一预览接口(使用默认存储) |
/file/{storageType}/{bucketName}/preview |
GET | 指定存储预览接口 |
/file/resource |
GET | 本地资源通用下载 |
/file/initUpload |
POST | 初始化分片上传 |
/file/uploadChunk |
POST | 上传文件分片 |
/file/completeUpload |
POST | 完成分片上传并合并文件 |
SysFileInfoController - 文件信息管理控制器
- 位置:
com.datai.file.controller.SysFileInfoController - 路径:
/file/info - 核心接口:
| 接口路径 | 方法 | 描述 | 权限 |
|---|---|---|---|
/file/info/list |
GET | 查询文件列表 | system:file:list |
/file/info/export |
POST | 导出文件列表 | system:file:export |
/file/info/{fileId} |
GET | 获取文件详细信息 | system:file:query |
/file/info |
POST | 新增文件 | system:file:add |
/file/info |
PUT | 修改文件 | system:file:edit |
/file/info/{fileIds} |
DELETE | 删除文件 | system:file:remove |
6. 数据库设计
6.1 表结构
sys_file_info - 文件信息表
| 字段名 | 类型 | 描述 | 备注 |
|---|---|---|---|
| file_id | BIGINT | 文件主键 | 主键 |
| file_name | VARCHAR(255) | 原始文件名 | |
| file_path | VARCHAR(500) | 统一逻辑路径 | /开头 |
| storage_type | VARCHAR(50) | 存储类型 | local/minio/oss |
| file_type | VARCHAR(50) | 文件类型/后缀 | |
| file_size | BIGINT | 文件大小(字节) | |
| md5 | VARCHAR(32) | 文件MD5 | |
| create_by | VARCHAR(64) | 创建者 | |
| create_time | DATETIME | 创建时间 | |
| update_by | VARCHAR(64) | 更新者 | |
| update_time | DATETIME | 更新时间 | |
| remark | VARCHAR(500) | 备注 | |
| del_flag | CHAR(1) | 删除标志 | 0存在 2删除 |
7. 配置说明
7.1 本地存储配置
local:
enable: true
primary: default
buckets:
default:
path: /data/files
permission: public
api: /files
7.2 MinIO存储配置
minio:
enable: true
primary: default
buckets:
default:
url: http://localhost:9000
accessKey: minioadmin
secretKey: minioadmin
bucketName: datai-files
permission: private
7.3 阿里云OSS存储配置
oss:
enable: true
primary: default
buckets:
default:
endpoint: oss-cn-hangzhou.aliyuncs.com
accessKeyId: your-access-key-id
accessKeySecret: your-access-key-secret
bucketName: datai-files
permission: private
8. 核心功能说明
8.1 文件上传
-
普通上传
- 支持指定文件路径上传
- 支持MD5去重(通过缓存)
- 支持文件类型校验
- 支持文件大小限制(默认500MB)
-
分片上传
- 初始化分片上传:
initMultipartUpload() - 上传分片:
uploadPart() - 完成上传:
completeMultipartUpload() - 支持大文件上传
- 初始化分片上传:
8.2 文件下载
-
普通下载
- 支持下载到输出流
- 支持下载到HTTP响应
- 自动设置响应头
-
预览下载
- 支持在线预览
- 自动识别文件类型
8.3 文件访问
-
公开访问
- 直接通过URL访问
- 适用于public权限存储桶
-
预签名URL
- 带过期时间的临时访问链接
- 适用于private权限存储桶
8.4 存储切换
- 支持动态切换存储类型
- 支持指定存储桶
- 统一的API接口
9. 技术特性
9.1 设计模式
- 工厂模式:
StorageFactory用于创建不同类型的存储桶 - 策略模式:
StorageBucket接口定义统一的存储策略 - 模板方法:
StorageService封装通用存储操作
9.2 扩展性
- 通过实现
StorageBucket接口可以轻松添加新的存储类型 - 通过继承
StorageFactory可以创建新的存储工厂 - 配置化驱动,支持动态启用/禁用存储类型
9.3 性能优化
- MD5去重减少重复存储
- 分片上传支持大文件
- 缓存机制提升访问速度
10. 使用示例
10.1 普通上传
// 使用默认存储
String filePath = FileOperateUtils.upload(file);
// 指定路径上传
String filePath = FileOperateUtils.upload("upload/2024/01/01/file.jpg", file);
10.2 文件下载
// 下载到输出流
FileOperateUtils.downLoad(filePath, outputStream);
// 下载到HTTP响应
FileOperateUtils.downLoad(filePath, response);
10.3 获取访问链接
String url = FileOperateUtils.getURL(filePath);
10.4 分片上传
// 1. 初始化分片上传
String uploadId = fileService.initMultipartUpload(filePath, fileSize);
// 2. 上传分片
List<SysFilePartETag> partETags = new ArrayList<>();
for (int i = 1; i <= partCount; i++) {
String etag = fileService.uploadPart(filePath, uploadId, i, partSize, inputStream);
partETags.add(new SysFilePartETag(i, etag));
}
// 3. 完成分片上传
String finalPath = fileService.completeMultipartUpload(filePath, uploadId, partETags);
11. 依赖关系
datai-file-starter
├── datai-file-local
│ └── datai-file-common
├── datai-file-minio
│ └── datai-file-common
└── datai-file-aliyun-oss
└── datai-file-common
datai-file-common
└── datai-common
12. 总结
datai-scene-file 模块提供了一个灵活、可扩展的文件存储解决方案,具有以下特点:
- 多存储支持: 支持本地、MinIO、阿里云OSS等多种存储方式
- 统一接口: 提供统一的API接口,屏蔽底层存储差异
- 分片上传: 支持大文件分片上传
- MD5去重: 自动识别重复文件,避免重复存储
- 灵活配置: 支持动态配置和切换存储类型
- 易于扩展: 通过接口和工厂模式,易于添加新的存储类型