fenghuo/apps/backend/src/upload/README.md

7.3 KiB
Raw Blame History

上传模块架构改造

本模块已从 NestJS 架构成功改造为 Hono + Bun 架构,并支持多种存储后端的无感切换。

文件结构

src/upload/
├── tus.ts                  # TUS 协议服务核心实现
├── upload.index.ts         # 资源管理相关函数
├── upload.rest.ts          # Hono REST API 路由
├── storage.adapter.ts      # 存储适配器系统 🆕
├── storage.utils.ts        # 存储工具类 🆕
├── scheduler.ts            # 定时清理任务
├── utils.ts               # 工具函数
├── types.ts               # 类型定义
└── README.md              # 本文档

存储适配器系统

支持的存储类型

  1. 本地存储 (Local) - 文件存储在本地文件系统
  2. S3 存储 (S3) - 文件存储在 AWS S3 或兼容的对象存储服务

环境变量配置

本地存储配置

STORAGE_TYPE=local
UPLOAD_DIR=./uploads
UPLOAD_EXPIRATION_MS=0  # 0 表示不自动过期(推荐设置)

S3 存储配置

STORAGE_TYPE=s3
S3_BUCKET=your-bucket-name
S3_REGION=us-east-1
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_ENDPOINT=https://s3.amazonaws.com          # 可选,支持其他 S3 兼容服务
S3_FORCE_PATH_STYLE=false                     # 可选,路径风格
S3_PART_SIZE=8388608                          # 可选,分片大小 (8MB)
S3_MAX_CONCURRENT_UPLOADS=60                  # 可选,最大并发上传数
UPLOAD_EXPIRATION_MS=0                        # 0 表示不自动过期(推荐设置)

存储类型记录

  • 数据库支持: 每个资源记录都包含 storageType 字段,标识文件使用的存储后端
  • 自动记录: 上传时自动记录当前的存储类型
  • 迁移支持: 支持批量更新现有资源的存储类型标记

不过期设置

  • 默认行为: 过期时间默认设为 0表示文件不会自动过期
  • 手动清理: 提供多种手动清理选项
  • 灵活控制: 可根据需要设置过期时间,或完全禁用自动清理

无感切换机制

  1. 单例模式管理: StorageManager 使用单例模式确保全局一致性
  2. 自动配置检测: 启动时根据环境变量自动选择存储类型
  3. 统一接口: 所有存储类型都实现相同的 TUS DataStore 接口
  4. 运行时切换: 支持运行时切换存储配置(需要重启生效)

API 端点

资源管理

  • GET /api/upload/resource/:fileId - 获取文件资源信息
  • GET /api/upload/resources - 获取所有资源
  • GET /api/upload/resources/storage/:storageType - 🆕 根据存储类型获取资源
  • GET /api/upload/resources/status/:status - 🆕 根据状态获取资源
  • GET /api/upload/resources/uploading - 🆕 获取正在上传的资源
  • GET /api/upload/stats - 🆕 获取资源统计信息
  • DELETE /api/upload/resource/:id - 删除资源
  • PATCH /api/upload/resource/:id - 更新资源
  • POST /api/upload/cleanup - 手动触发清理
  • POST /api/upload/cleanup/by-status - 🆕 根据状态清理资源
  • POST /api/upload/migrate-storage - 🆕 迁移资源存储类型标记

存储管理

  • GET /api/upload/storage/info - 获取当前存储配置信息
  • POST /api/upload/storage/switch - 切换存储类型
  • POST /api/upload/storage/validate - 验证存储配置

TUS 协议

  • OPTIONS /api/upload/* - TUS 协议选项请求
  • HEAD /api/upload/* - TUS 协议头部请求
  • POST /api/upload/* - TUS 协议创建上传
  • PATCH /api/upload/* - TUS 协议上传数据
  • GET /api/upload/* - TUS 协议获取状态

新增 API 使用示例

获取存储类型统计

const response = await fetch('/api/upload/stats');
const stats = await response.json();
// {
//   total: 150,
//   byStatus: { "UPLOADED": 120, "UPLOADING": 5, "PROCESSED": 25 },
//   byStorageType: { "local": 80, "s3": 70 }
// }

查询特定存储类型的资源

const response = await fetch('/api/upload/resources/storage/s3');
const s3Resources = await response.json();

迁移存储类型标记

const response = await fetch('/api/upload/migrate-storage', {
	method: 'POST',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify({ from: 'local', to: 's3' }),
});
// { success: true, message: "Migrated 50 resources from local to s3", count: 50 }

手动清理特定状态的资源

const response = await fetch('/api/upload/cleanup/by-status', {
	method: 'POST',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify({
		status: 'UPLOADING',
		olderThanDays: 7,
	}),
});

🆕 存储管理示例

获取存储信息

const response = await fetch('/api/upload/storage/info');
const storageInfo = await response.json();
// { type: 'local', config: { directory: './uploads' } }

切换到 S3 存储

const newConfig = {
	type: 's3',
	s3: {
		bucket: 'my-bucket',
		region: 'us-west-2',
		accessKeyId: 'YOUR_ACCESS_KEY',
		secretAccessKey: 'YOUR_SECRET_KEY',
	},
};

const response = await fetch('/api/upload/storage/switch', {
	method: 'POST',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify(newConfig),
});

验证存储配置

const response = await fetch('/api/upload/storage/validate', {
	method: 'POST',
	headers: { 'Content-Type': 'application/json' },
	body: JSON.stringify(newConfig),
});
const validation = await response.json();
// { valid: true, message: 'Storage configuration is valid' }

特性保留

  1. TUS 协议支持 - 完全保留原有的断点续传功能
  2. 文件命名 - 保留安全的文件命名策略
  3. 资源状态管理 - 保留完整的上传状态跟踪
  4. 自动清理 - 保留过期文件清理功能(默认禁用)
  5. 数据库集成 - 保留 Prisma ORM 数据库操作

🆕 新增特性

  1. 多存储后端支持 - 支持本地存储和 S3 存储
  2. 无感切换 - 运行时可切换存储类型
  3. 配置验证 - 提供存储配置验证功能
  4. 存储信息查询 - 可查询当前存储配置
  5. 统一日志 - 存储操作统一日志记录
  6. 🆕 存储类型记录 - 数据库记录每个资源的存储类型
  7. 🆕 灵活清理 - 支持按状态、时间等条件清理
  8. 🆕 统计分析 - 提供详细的资源统计信息
  9. 🆕 不过期设置 - 默认不自动过期,避免意外删除

运行

服务启动时会自动:

  1. 根据环境变量初始化存储适配器
  2. 初始化 TUS 服务器
  3. 注册 REST API 路由
  4. 启动定时清理任务(如果启用)

支持的存储切换场景:

  • 开发环境使用本地存储
  • 生产环境使用 S3 存储
  • 混合云部署灵活切换
  • 存储迁移时批量更新资源标记

💡 最佳实践

  1. 过期设置: 推荐设置 UPLOAD_EXPIRATION_MS=0 避免文件意外过期
  2. 存储记录: 利用数据库中的 storageType 字段追踪文件位置
  3. 定期清理: 使用手动清理 API 定期清理不需要的资源
  4. 监控统计: 使用统计 API 监控存储使用情况
  5. 迁移策略: 在存储迁移时先更新环境变量,再使用迁移 API 更新数据库标记

无需代码修改,仅通过环境变量即可实现存储后端的无感切换。