Modules

存储模块

文件存储模块文档,详细说明存储实现、支持的存储模式和核心功能。

存储 (Storage) 模块负责系统的文件上传、下载、预览和管理,支持多种存储模式,提供统一的文件操作接口。

1. 存储概述

存储模块采用抽象设计,支持多种存储模式,通过配置可以灵活切换,无需修改业务代码。

1.1 设计理念

  • 抽象统一接口: 定义统一的存储接口,屏蔽不同存储模式的实现差异
  • 模块化设计: 不同存储模式作为独立模块,便于扩展和维护
  • 配置驱动: 通过配置文件动态切换存储模式
  • 高性能: 支持文件缓存和异步操作
  • 高可靠性: 支持文件备份和恢复

1.2 支持的存储模式

存储模式描述适用场景
本地存储文件保存在服务器本地磁盘开发环境、小型应用
对象存储使用云厂商对象存储服务(如阿里云 OSS、腾讯云 COS、MinIO)生产环境、高并发应用

2. 数据模型

2.1 文件信息 (FileInfo)

属性:

  • 文件ID (file_id): 唯一标识符,使用 UUID 生成
  • 文件名 (file_name): 原始文件名
  • 文件大小 (file_size): 文件大小(字节)
  • 文件类型 (content_type): MIME 类型
  • 文件路径 (file_path): 存储路径
  • 访问URL (url): 文件访问地址
  • 存储模式 (storage_type): 存储模式,如 localminio
  • 上传人 (uploader_id): 上传人ID
  • 上传时间 (upload_time): 上传时间
  • 状态 (status): 文件状态,如正常、删除

2.2 存储配置 (StorageConfig)

属性:

  • 存储类型 (storage_type): 存储模式类型
  • 存储配置 (config): 具体存储模式的配置参数,JSON 格式
  • 状态 (status): 启用/禁用
  • 描述 (description): 配置描述

3. 核心功能

3.1 文件上传

支持多种文件上传方式,包括:

  • 单文件上传
  • 多文件上传
  • 分片上传
  • 断点续传

上传流程:

  1. 接收文件上传请求
  2. 验证文件类型和大小
  3. 生成唯一文件名
  4. 根据存储模式选择上传策略
  5. 执行文件上传
  6. 记录文件信息到数据库
  7. 返回上传结果(文件ID、访问URL等)

3.2 文件下载

支持文件下载功能,包括:

  • 直接下载
  • 预览下载
  • 批量下载

下载流程:

  1. 接收文件下载请求
  2. 验证文件存在性和访问权限
  3. 根据存储模式选择下载策略
  4. 执行文件下载
  5. 返回文件流给客户端

3.3 文件预览

支持常见文件类型的在线预览,包括:

  • 图片预览(JPG、PNG、GIF等)
  • 文档预览(PDF、Word、Excel、PPT等)
  • 音频视频预览

预览流程:

  1. 接收文件预览请求
  2. 验证文件存在性和访问权限
  3. 检查文件类型是否支持预览
  4. 根据文件类型选择预览方式
  5. 返回预览结果

3.4 文件管理

提供完整的文件管理功能,包括:

  • 文件列表查询
  • 文件详情查询
  • 文件删除
  • 文件重命名
  • 文件移动
  • 文件复制

3.5 存储配置管理

支持动态管理存储配置,包括:

  • 新增存储配置
  • 修改存储配置
  • 删除存储配置
  • 切换默认存储配置

4. 实现细节

4.1 抽象存储接口

定义统一的存储接口,所有存储模式都实现该接口:

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);
}

4.2 存储模式实现

4.2.1 本地存储实现

@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. 返回存储结果
    }
    
    // 其他方法实现...
}

4.2.2 对象存储实现

@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. 返回存储结果
    }
    
    // 其他方法实现...
}

4.3 配置示例

4.3.1 本地存储配置

# 本地存储配置
storage:
  type: local
  local:
    base-path: uploads       # 文件存储根目录
    domain: http://localhost:8080  # 文件访问域名
    max-size: 104857600      # 最大文件大小(100MB)
    allowed-types:           # 允许上传的文件类型
      - image/*
      - application/pdf
      - application/msword

4.3.2 MinIO 配置

# 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

5. 核心代码结构

5.1 后端代码结构

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

5.2 前端代码结构

frontend/apps/tagtag/src/views/modules/storage
├── file
│   ├── data.ts
│   └── index.vue
└── config
    ├── data.ts
    └── index.vue

6. 前端实现

前端相关代码位于 frontend/apps/tagtag/src/views/modules/storage

功能页面路径描述
文件管理/storage/file文件列表、上传、下载、预览、删除
存储配置/storage/config存储模式配置、切换

6.1 文件上传组件

<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>

7. API 参考

方法端点描述
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}设置默认存储配置

8. 最佳实践

8.1 文件命名

  • 使用 UUID 生成唯一文件名,避免文件名冲突
  • 保留原始文件名,存储在数据库中
  • 使用目录分级存储,避免单个目录文件过多

8.2 文件大小限制

  • 根据业务需求设置合理的文件大小限制
  • 在前端和后端同时进行文件大小验证
  • 对于大文件,使用分片上传和断点续传

8.3 文件类型验证

  • 限制允许上传的文件类型
  • 在前端和后端同时进行文件类型验证
  • 对于可执行文件和脚本文件,进行特殊处理

8.4 安全措施

  • 对上传文件进行病毒扫描
  • 设置合理的文件访问权限
  • 对于敏感文件,使用加密存储
  • 定期备份重要文件

8.5 性能优化

  • 使用 CDN 加速文件访问
  • 对热点文件进行缓存
  • 异步处理文件上传和下载
  • 定期清理过期文件

9. 扩展建议

9.1 支持更多存储模式

  • 添加对更多云厂商对象存储的支持
  • 支持分布式文件系统(如 FastDFS、GlusterFS)

9.2 增强文件管理功能

  • 支持文件版本管理
  • 支持文件分享功能
  • 支持文件评论和标签
  • 支持文件搜索功能

9.3 增强安全功能

  • 支持文件加密存储
  • 支持文件访问日志
  • 支持文件访问权限控制
  • 支持文件水印功能

9.4 增强性能功能

  • 支持文件压缩和转码
  • 支持智能缓存策略
  • 支持文件预加载
  • 支持文件分片下载

10. 总结

存储模块是 Tagtag Starter 系统的核心模块之一,负责系统的文件上传、下载、预览和管理。

通过存储模块,系统可以灵活支持多种存储模式,提供统一的文件操作接口,满足不同场景的需求。存储模块的设计和实现遵循了模块化、可扩展的原则,便于后续功能扩展和定制化开发。

存储模块的核心功能包括文件上传、下载、预览和管理,支持本地存储和对象存储两种模式。通过合理的配置和最佳实践,可以提高系统的性能、可靠性和安全性。