# 上传模块架构改造 本模块已从 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 或兼容的对象存储服务 ### 环境变量配置 #### 本地存储配置 ```bash STORAGE_TYPE=local UPLOAD_DIR=./uploads UPLOAD_EXPIRATION_MS=0 # 0 表示不自动过期(推荐设置) ``` #### S3 存储配置 ```bash 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 使用示例 ### 获取存储类型统计 ```javascript 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 } // } ``` ### 查询特定存储类型的资源 ```javascript const response = await fetch('/api/upload/resources/storage/s3'); const s3Resources = await response.json(); ``` ### 迁移存储类型标记 ```javascript 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 } ``` ### 手动清理特定状态的资源 ```javascript const response = await fetch('/api/upload/cleanup/by-status', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ status: 'UPLOADING', olderThanDays: 7, }), }); ``` ## 🆕 存储管理示例 ### 获取存储信息 ```javascript const response = await fetch('/api/upload/storage/info'); const storageInfo = await response.json(); // { type: 'local', config: { directory: './uploads' } } ``` ### 切换到 S3 存储 ```javascript 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), }); ``` ### 验证存储配置 ```javascript 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 更新数据库标记 无需代码修改,仅通过环境变量即可实现存储后端的无感切换。