存储 (Storage) 模块负责系统的文件上传、下载、预览和管理,支持多种存储模式,提供统一的文件操作接口。
存储模块采用抽象设计,支持多种存储模式,通过配置可以灵活切换,无需修改业务代码。
| 存储模式 | 描述 | 适用场景 |
|---|---|---|
| 本地存储 | 文件保存在服务器本地磁盘 | 开发环境、小型应用 |
| 对象存储 | 使用云厂商对象存储服务(如阿里云 OSS、腾讯云 COS、MinIO) | 生产环境、高并发应用 |
属性:
local、minio属性:
支持多种文件上传方式,包括:
上传流程:
支持文件下载功能,包括:
下载流程:
支持常见文件类型的在线预览,包括:
预览流程:
提供完整的文件管理功能,包括:
支持动态管理存储配置,包括:
定义统一的存储接口,所有存储模式都实现该接口:
public interface StorageService {
/**
* 上传文件
* @param file 上传的文件
* @param prefix 文件前缀
* @return 存储结果
*/
StorageResult upload(MultipartFile file, String prefix);
/**
* 下载文件
* @param fileId 文件ID
* @param response 响应对象
*/
void download(String fileId, HttpServletResponse response);
/**
* 预览文件
* @param fileId 文件ID
* @param response 响应对象
*/
void preview(String fileId, HttpServletResponse response);
/**
* 删除文件
* @param fileId 文件ID
*/
void delete(String fileId);
/**
* 获取文件信息
* @param fileId 文件ID
* @return 文件信息
*/
FileInfo getFileInfo(String fileId);
}
@Service
@ConditionalOnProperty(name = "storage.type", havingValue = "local")
public class LocalStorageServiceImpl implements StorageService {
@Value("${storage.local.base-path}")
private String basePath;
@Value("${storage.local.domain}")
private String domain;
@Override
public StorageResult upload(MultipartFile file, String prefix) {
// 本地存储上传实现
// 1. 生成唯一文件名
// 2. 创建存储目录
// 3. 保存文件到本地磁盘
// 4. 记录文件信息
// 5. 返回存储结果
}
// 其他方法实现...
}
@Service
@ConditionalOnProperty(name = "storage.type", havingValue = "minio")
public class MinioStorageServiceImpl implements StorageService {
@Autowired
private MinioClient minioClient;
@Value("${storage.minio.bucket-name}")
private String bucketName;
@Value("${storage.minio.domain}")
private String domain;
@Override
public StorageResult upload(MultipartFile file, String prefix) {
// MinIO 上传实现
// 1. 生成唯一文件名
// 2. 上传文件到 MinIO
// 3. 记录文件信息
// 4. 返回存储结果
}
// 其他方法实现...
}
# 本地存储配置
storage:
type: local
local:
base-path: uploads # 文件存储根目录
domain: http://localhost:8080 # 文件访问域名
max-size: 104857600 # 最大文件大小(100MB)
allowed-types: # 允许上传的文件类型
- image/*
- application/pdf
- application/msword
# MinIO 配置
storage:
type: minio
minio:
endpoint: http://minio:9000 # MinIO 服务地址
access-key: minioadmin # 访问密钥
secret-key: minioadmin # 秘密密钥
bucket-name: tagtag # 存储桶名称
domain: http://minio:9000 # 文件访问域名
max-size: 104857600 # 最大文件大小(100MB)
allowed-types: # 允许上传的文件类型
- image/*
- application/pdf
tagtag-module-storage
└── src
└── main
├── java
│ └── dev
│ └── tagtag
│ └── module
│ └── storage
│ ├── config
│ │ ├── LocalStorageConfig.java
│ │ ├── MinioStorageConfig.java
│ │ └── StorageAutoConfiguration.java
│ ├── controller
│ │ └── StorageController.java
│ ├── entity
│ │ ├── FileInfoEntity.java
│ │ └── StorageConfigEntity.java
│ ├── mapper
│ │ ├── FileInfoMapper.java
│ │ └── StorageConfigMapper.java
│ ├── service
│ │ ├── StorageService.java
│ │ ├── impl
│ │ │ ├── LocalStorageServiceImpl.java
│ │ │ └── MinioStorageServiceImpl.java
│ │ └── FileInfoService.java
│ └── util
│ ├── FileUtil.java
│ └── StorageUtil.java
└── resources
├── db
│ ├── schema.sql
│ └── data
│ └── 01_storage_config.sql
└── mapper
└── storage
├── FileInfoMapper.xml
└── StorageConfigMapper.xml
frontend/apps/tagtag/src/views/modules/storage
├── file
│ ├── data.ts
│ └── index.vue
└── config
├── data.ts
└── index.vue
前端相关代码位于 frontend/apps/tagtag/src/views/modules/storage。
| 功能 | 页面路径 | 描述 |
|---|---|---|
| 文件管理 | /storage/file | 文件列表、上传、下载、预览、删除 |
| 存储配置 | /storage/config | 存储模式配置、切换 |
<template>
<div class="file-uploader">
<a-upload
:action="uploadUrl"
:headers="headers"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
>
<a-button>
<UploadOutlined /> 选择文件
</a-button>
</a-upload>
</div>
</template>
<script setup lang="ts">
import { UploadOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { useToken } from '@/hooks/useToken';
const emit = defineEmits<{
(e: 'success', file: any): void;
(e: 'error', error: any): void;
}>();
const { token } = useToken();
const uploadUrl = import.meta.env.VITE_API_BASE_URL + '/storage/upload';
const headers = {
'Authorization': `Bearer ${token.value}`
};
const beforeUpload = (file: File) => {
// 验证文件类型和大小
const isImage = file.type.startsWith('image/');
const isLt10M = file.size / 1024 / 1024 < 10;
if (!isImage) {
message.error('只允许上传图片文件!');
return false;
}
if (!isLt10M) {
message.error('文件大小不能超过 10MB!');
return false;
}
return true;
};
const handleSuccess = (response: any) => {
if (response.success) {
message.success('文件上传成功!');
emit('success', response.data);
} else {
message.error('文件上传失败:' + response.message);
emit('error', response);
}
};
const handleError = (error: any) => {
message.error('文件上传失败:' + error.message);
emit('error', error);
};
</script>
| 方法 | 端点 | 描述 |
|---|---|---|
| POST | /storage/upload | 上传文件 |
| GET | /storage/download/{fileId} | 下载文件 |
| GET | /storage/preview/{fileId} | 预览文件 |
| DELETE | /storage/{fileId} | 删除文件 |
| GET | /storage/list | 获取文件列表 |
| GET | /storage/{fileId} | 获取文件详情 |
| GET | /storage/config | 获取存储配置 |
| POST | /storage/config | 新增存储配置 |
| PUT | /storage/config | 更新存储配置 |
| DELETE | /storage/config/{configId} | 删除存储配置 |
| PUT | /storage/config/set-default/{configId} | 设置默认存储配置 |
存储模块是 Tagtag Starter 系统的核心模块之一,负责系统的文件上传、下载、预览和管理。
通过存储模块,系统可以灵活支持多种存储模式,提供统一的文件操作接口,满足不同场景的需求。存储模块的设计和实现遵循了模块化、可扩展的原则,便于后续功能扩展和定制化开发。
存储模块的核心功能包括文件上传、下载、预览和管理,支持本地存储和对象存储两种模式。通过合理的配置和最佳实践,可以提高系统的性能、可靠性和安全性。