# 管理端OSS文件上传接口文档 ## 📋 概述 管理端OSS文件上传接口提供了完整的文件管理功能,包括文件上传签名生成、文件删除、批量删除和文件信息查询。**管理端和用户端的文件存储在同一目录下**(`user_img/`),便于统一管理。 ### 基础信息 - **基础路径**: `/admin/oss` - **权限要求**: 需要管理员或工作人员JWT Token - **文件存储**: 与用户端共享同一目录 (`user_img/`) - **最大文件**: 500MB - **有效期**: 2小时 --- ## 🔐 认证方式 所有管理端接口都需要在请求头中携带JWT Token: ```http Authorization: Bearer {your_admin_jwt_token} ``` --- ## 📡 API接口列表 ### 1. 生成OSS POST签名 **接口地址**: `POST /admin/oss/post-signature` **功能描述**: 生成管理端文件上传的OSS POST签名,支持多种文件格式和大文件上传。 #### 请求参数 ```json { "fileName": "banner.jpg", "directory": "banners", "description": "Banner图片", "fileCategory": "image", "maxSizeMB": 50 } ``` | 字段 | 类型 | 必填 | 说明 | |------|------|------|------| | fileName | string | ✅ | 文件名,包含扩展名 | | directory | string | ❌ | 子目录名称(不包含user_img前缀) | | description | string | ❌ | 文件描述 | | fileCategory | string | ❌ | 文件分类:image/document/compressed/video/audio/other | | maxSizeMB | integer | ❌ | 最大文件大小(MB),默认50MB,最大500MB | #### 响应示例 ```json { "code": 200, "message": "管理端POST签名生成成功", "data": { "version": "OSS4-HMAC-SHA256", "policy": "eyJleHBpcmF0aW9uIjoiMjAyNC0xMi0yNVQxNDowMDowMC4wMDBaIi...", "x_oss_credential": "LTAI5t7Cn8mLa9K8NQy7S9Vj/20241225/cn-hangzhou/oss/aliyun_v4_request", "x_oss_date": "20241225T120000Z", "signature": "a1b2c3d4e5f6789...", "security_token": "", "dir": "user_img/banners/", "host": "https://oss-1818ai-user-img.oss-cn-hangzhou.aliyuncs.com", "accessKeyId": "LTAI5t7Cn8mLa9K8NQy7S9Vj", "adminId": "123", "fileName": "banner.jpg", "fileType": "image", "maxFileSize": 52428800, "maxFileSizeMB": 50, "supportedFormats": [ "图片: jpg, jpeg, png, gif, bmp, webp, svg, ico, tiff", "文档: pdf, txt, md, json, xml, csv, doc, docx, xls, xlsx, ppt, pptx", "压缩包: zip, rar, 7z, tar, gz, bz2, xz", "音频: mp3, wav, flac, aac, ogg, wma", "视频: mp4, avi, mov, wmv, flv, mkv, webm", "其他: html, css, js, sql, log" ], "uploadTips": "支持常见图片格式,建议使用JPG/PNG格式以获得更好的兼容性。" } } ``` --- ### 2. 删除文件 **接口地址**: `DELETE /admin/oss/file` **功能描述**: 删除指定的OSS文件。 #### 请求参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | objectKey | string | ✅ | 文件的完整路径,如:user_img/banners/banner.jpg | #### 请求示例 ```http DELETE /admin/oss/file?objectKey=user_img/banners/banner.jpg Authorization: Bearer {admin_jwt_token} ``` #### 响应示例 ```json { "code": 200, "message": "操作成功", "data": "文件删除成功" } ``` --- ### 3. 批量删除文件 **接口地址**: `POST /admin/oss/batch-delete` **功能描述**: 批量删除多个OSS文件。 #### 请求参数 ```json [ "user_img/banners/banner1.jpg", "user_img/banners/banner2.jpg", "user_img/documents/file.pdf" ] ``` #### 响应示例 ```json { "code": 200, "message": "批量删除操作完成", "data": { "success": [ "user_img/banners/banner1.jpg", "user_img/banners/banner2.jpg" ], "failed": [ "user_img/documents/file.pdf" ], "total": 3, "successCount": 2, "failedCount": 1 } } ``` --- ### 4. 获取文件信息 **接口地址**: `GET /admin/oss/file-info` **功能描述**: 获取OSS文件的详细信息。 #### 请求参数 | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | objectKey | string | ✅ | 文件的完整路径 | #### 请求示例 ```http GET /admin/oss/file-info?objectKey=user_img/banners/banner.jpg Authorization: Bearer {admin_jwt_token} ``` #### 响应示例 ```json { "code": 200, "message": "获取文件信息成功", "data": { "objectKey": "user_img/banners/banner.jpg", "size": 1024000, "lastModified": "2024-12-25T12:00:00.000Z", "contentType": "image/jpeg" } } ``` --- ### 5. 获取上传配置 **接口地址**: `GET /admin/oss/upload-config` **功能描述**: 获取管理端文件上传的配置信息。 #### 响应示例 ```json { "code": 200, "message": "获取上传配置成功", "data": { "maxFileSize": 524288000, "maxFileSizeMB": 500, "supportedFormats": [ "图片: jpg, jpeg, png, gif, bmp, webp, svg, ico, tiff", "文档: pdf, txt, md, json, xml, csv, doc, docx, xls, xlsx, ppt, pptx", "压缩包: zip, rar, 7z, tar, gz, bz2, xz", "音频: mp3, wav, flac, aac, ogg, wma", "视频: mp4, avi, mov, wmv, flv, mkv, webm", "其他: html, css, js, sql, log" ], "uploadDirectories": [ "banners", "images", "documents", "videos", "audios", "uploads" ], "tips": "管理端支持多种文件格式,最大支持500MB文件上传。文件将与用户端文件存储在同一目录下,建议根据用途选择合适的子目录。" } } ``` --- ## 💻 前端使用示例 ### JavaScript/Vue.js 示例 ```javascript class AdminOssUploader { constructor(baseURL, token) { this.baseURL = baseURL; this.token = token; } // 获取上传签名 async getUploadSignature(fileName, directory = 'uploads', maxSizeMB = 50) { const response = await fetch(`${this.baseURL}/admin/oss/post-signature`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.token}` }, body: JSON.stringify({ fileName, directory, fileCategory: this.getFileCategory(fileName), maxSizeMB }) }); const result = await response.json(); if (result.code === 200) { return result.data; } throw new Error(result.message); } // 上传文件到OSS async uploadFile(file, directory = 'uploads') { try { // 1. 获取签名 const signature = await this.getUploadSignature(file.name, directory); // 2. 构建FormData const formData = new FormData(); formData.append('key', `${signature.dir}${this.generateFileName(file.name)}`); formData.append('policy', signature.policy); formData.append('x-oss-credential', signature.x_oss_credential); formData.append('x-oss-date', signature.x_oss_date); formData.append('x-oss-signature-version', signature.x_oss_signature_version); formData.append('x-oss-signature', signature.x_oss_signature); formData.append('success_action_status', '200'); formData.append('file', file); // 3. 上传到OSS const uploadResponse = await fetch(signature.host, { method: 'POST', body: formData }); if (uploadResponse.ok) { const uploadedUrl = `${signature.host}/${formData.get('key')}`; return { success: true, url: uploadedUrl, key: formData.get('key') }; } throw new Error('Upload failed'); } catch (error) { console.error('Upload error:', error); return { success: false, error: error.message }; } } // 删除文件 async deleteFile(objectKey) { const response = await fetch(`${this.baseURL}/admin/oss/file?objectKey=${encodeURIComponent(objectKey)}`, { method: 'DELETE', headers: { 'Authorization': `Bearer ${this.token}` } }); const result = await response.json(); return result.code === 200; } // 批量删除文件 async batchDeleteFiles(objectKeys) { const response = await fetch(`${this.baseURL}/admin/oss/batch-delete`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.token}` }, body: JSON.stringify(objectKeys) }); const result = await response.json(); return result.data; } // 生成唯一文件名 generateFileName(originalName) { const timestamp = Date.now(); const random = Math.random().toString(36).substring(2); const ext = originalName.substring(originalName.lastIndexOf('.')); return `${timestamp}_${random}${ext}`; } // 获取文件分类 getFileCategory(fileName) { const ext = fileName.substring(fileName.lastIndexOf('.')).toLowerCase(); if (['.jpg', '.jpeg', '.png', '.gif', '.bmp', '.webp', '.svg'].includes(ext)) { return 'image'; } else if (['.mp4', '.avi', '.mov', '.wmv', '.flv', '.mkv'].includes(ext)) { return 'video'; } else if (['.mp3', '.wav', '.flac', '.aac', '.ogg'].includes(ext)) { return 'audio'; } else if (['.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx'].includes(ext)) { return 'document'; } else if (['.zip', '.rar', '.7z', '.tar', '.gz'].includes(ext)) { return 'compressed'; } return 'other'; } } // 使用示例 const uploader = new AdminOssUploader('https://your-api.com', 'your-admin-token'); // 上传Banner图片 document.getElementById('bannerInput').addEventListener('change', async (e) => { const file = e.target.files[0]; if (file) { const result = await uploader.uploadFile(file, 'banners'); if (result.success) { console.log('上传成功:', result.url); } else { console.error('上传失败:', result.error); } } }); ``` ### React Hook 示例 ```jsx import { useState, useCallback } from 'react'; const useAdminOssUpload = (token) => { const [uploading, setUploading] = useState(false); const [progress, setProgress] = useState(0); const uploadFile = useCallback(async (file, directory = 'uploads') => { setUploading(true); setProgress(0); try { // 获取签名 const response = await fetch('/admin/oss/post-signature', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` }, body: JSON.stringify({ fileName: file.name, directory, maxSizeMB: Math.ceil(file.size / (1024 * 1024)) }) }); const { data: signature } = await response.json(); // 上传到OSS const formData = new FormData(); const fileKey = `${signature.dir}${Date.now()}_${file.name}`; formData.append('key', fileKey); formData.append('policy', signature.policy); formData.append('x-oss-credential', signature.x_oss_credential); formData.append('x-oss-date', signature.x_oss_date); formData.append('x-oss-signature-version', signature.x_oss_signature_version); formData.append('x-oss-signature', signature.x_oss_signature); formData.append('success_action_status', '200'); formData.append('file', file); const uploadResponse = await fetch(signature.host, { method: 'POST', body: formData }); if (uploadResponse.ok) { setProgress(100); return { success: true, url: `${signature.host}/${fileKey}`, key: fileKey }; } throw new Error('Upload failed'); } catch (error) { return { success: false, error: error.message }; } finally { setUploading(false); } }, [token]); return { uploadFile, uploading, progress }; }; // 使用示例 const AdminFileUpload = () => { const token = localStorage.getItem('adminToken'); const { uploadFile, uploading } = useAdminOssUpload(token); const handleUpload = async (e) => { const file = e.target.files[0]; if (file) { const result = await uploadFile(file, 'banners'); if (result.success) { alert('上传成功: ' + result.url); } else { alert('上传失败: ' + result.error); } } }; return (
上传中...
}