live-forum/前端/文档/README.md
2026-03-24 11:27:37 +08:00

360 lines
8.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 文件上传服务架构说明
## 📁 目录结构
```
utils/
├── IServer/
│ ├── IUploadService.js # 上传服务接口(抽象基类)
│ ├── UploadFactory.js # 工厂类(创建上传服务实例)
│ └── README.md # 本文档
├── CosUploadService.js # 腾讯云COS上传服务实现
└── CosUpload.js # 旧版(保留兼容性)
```
## 🎯 设计模式
采用 **策略模式 + 工厂模式**
- **策略模式**: 定义统一的上传接口IUploadService不同的上传方式实现该接口
- **工厂模式**: 通过工厂类UploadFactory创建具体的上传服务实例
## ✨ 优势
1. **易扩展**: 添加新的上传方式只需实现接口,无需修改现有代码
2. **易切换**: 通过工厂类切换不同的上传服务
3. **解耦合**: 业务代码不依赖具体的上传实现
4. **易测试**: 可以轻松mock上传服务进行测试
## 🚀 快速开始
### 方式一:使用工厂创建(推荐)
```javascript
import { AppServer } from '../../modules/api/AppServer.js'
import UploadFactory from '../../utils/IServer/UploadFactory.js'
// 创建上传服务
const appServer = new AppServer()
const uploadService = UploadFactory.create(
'cos', // 服务类型
async (key) => await appServer.GetCosSign(key), // 签名函数
{
// 可选配置
imageQuality: 80,
imageMaxSize: 10 * 1024 * 1024,
videoMaxSize: 100 * 1024 * 1024,
cosDomain: 'https://miaoyu-1308826010.cos.ap-shanghai.myqcloud.com'
}
)
// 上传文件
const result = await uploadService.uploadFile(filePath, 'images')
if (result.success) {
console.log('文件URL:', result.data)
}
```
### 方式二:直接创建实例
```javascript
import CosUploadService from '../../utils/CosUploadService.js'
const uploadService = new CosUploadService(
async (key) => await appServer.GetCosSign(key),
{ imageQuality: 90 }
)
```
## 📝 如何添加新的上传服务
### 1. 创建上传服务类
```javascript
// utils/MyUploadService.js
import IUploadService from './IServer/IUploadService.js'
class MyUploadService extends IUploadService {
constructor(config) {
super()
this.config = config
}
async uploadFile(filePath, folder = 'images') {
try {
// 实现你的上传逻辑
const fileUrl = await this.doUpload(filePath)
return {
success: true,
data: fileUrl
}
} catch (error) {
return {
success: false,
error: error.message
}
}
}
async uploadFiles(filePaths, folder = 'images') {
// 实现批量上传
const results = []
for (const path of filePaths) {
const result = await this.uploadFile(path, folder)
if (result.success) {
results.push(result.data)
}
}
return {
success: true,
data: results
}
}
async getFileInfo(filePath) {
// 实现获取文件信息
}
validateFile(fileType, fileSize) {
// 实现文件验证
return { success: true }
}
async doUpload(filePath) {
// 你的实际上传逻辑
}
}
export default MyUploadService
```
### 2. 注册服务
```javascript
import UploadFactory from './IServer/UploadFactory.js'
import MyUploadService from './MyUploadService.js'
// 注册新服务
UploadFactory.register('myupload', MyUploadService)
```
### 3. 使用新服务
```javascript
const uploadService = UploadFactory.create('myupload', config)
const result = await uploadService.uploadFile(filePath)
```
## 🔧 配置项说明
### CosUploadService 配置
| 配置项 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| imageMaxSize | Number | 10 * 1024 * 1024 | 图片最大大小(字节) |
| videoMaxSize | Number | 100 * 1024 * 1024 | 视频最大大小(字节) |
| imageQuality | Number | 80 | 图片压缩质量0-100 |
| cosDomain | String | miaoyu的COS域名 | COS访问域名 |
## 📖 接口规范
### IUploadService 接口方法
#### uploadFile(filePath, folder)
上传单个文件
**参数**:
- `filePath` (String): 本地文件路径
- `folder` (String): 文件夹名称,默认 'images'
**返回**: Promise<Object>
```javascript
{
success: true/false,
data: '文件URL', // 成功时
error: '错误信息' // 失败时
}
```
#### uploadFiles(filePaths, folder)
批量上传文件
**参数**:
- `filePaths` (Array<String>): 文件路径数组
- `folder` (String): 文件夹名称,默认 'images'
**返回**: Promise<Object>
```javascript
{
success: true/false,
data: ['URL1', 'URL2', ...], // 成功时
errors: [...], // 部分失败时的错误信息
error: '错误信息' // 完全失败时
}
```
## 🎨 使用场景示例
### 场景1: 发帖上传图片
```javascript
// 在 post-page.vue 中
created() {
const appServer = new AppServer()
this.uploadService = UploadFactory.create('cos',
async (key) => await appServer.GetCosSign(key)
)
}
async uploadImage(filePath) {
const result = await this.uploadService.uploadFile(filePath, 'images')
return result.success ? result.data : null
}
```
### 场景2: 用户认证上传视频
```javascript
async uploadCertVideo(videoPath) {
const result = await this.uploadService.uploadFile(videoPath, 'videos')
if (result.success) {
// 保存视频URL
this.certificationVideo = result.data
}
}
```
### 场景3: 切换上传服务
```javascript
// 从COS切换到服务器上传
// 只需要修改工厂创建代码,业务代码无需改动
// 之前使用COS
const uploadService = UploadFactory.create('cos', getSignFn, config)
// 现在:使用服务器上传
const uploadService = UploadFactory.create('server', { apiUrl: '/api/upload' })
// 业务代码完全不变
const result = await uploadService.uploadFile(filePath)
```
## 🔍 已注册的服务类型
当前可用的服务类型:
```javascript
UploadFactory.getRegisteredTypes()
// 返回: ['cos']
// 检查是否注册
UploadFactory.isRegistered('cos') // true
UploadFactory.isRegistered('aliyun') // false
```
## 📚 未来扩展示例
### 阿里云OSS上传服务
```javascript
// utils/AliyunOssUploadService.js
import IUploadService from './IServer/IUploadService.js'
class AliyunOssUploadService extends IUploadService {
constructor(getSignFunction, config) {
super()
this.getSignFunction = getSignFunction
this.config = config
}
async uploadFile(filePath, folder) {
// 实现阿里云OSS上传逻辑
}
}
// 注册
UploadFactory.register('aliyun', AliyunOssUploadService)
// 使用
const service = UploadFactory.create('aliyun', getSignFn, config)
```
### 服务器直接上传
```javascript
// utils/ServerUploadService.js
import IUploadService from './IServer/IUploadService.js'
class ServerUploadService extends IUploadService {
constructor(config) {
super()
this.apiUrl = config.apiUrl
}
async uploadFile(filePath, folder) {
// 使用 uni.uploadFile 直接上传到服务器
return new Promise((resolve) => {
uni.uploadFile({
url: this.apiUrl,
filePath: filePath,
name: 'file',
success: (res) => {
const data = JSON.parse(res.data)
resolve({
success: true,
data: data.fileUrl
})
},
fail: (err) => {
resolve({
success: false,
error: err.errMsg
})
}
})
})
}
}
// 注册
UploadFactory.register('server', ServerUploadService)
// 使用
const service = UploadFactory.create('server', { apiUrl: '/api/upload' })
```
## 💡 最佳实践
1. **统一使用工厂创建**: 保持代码风格一致
2. **配置外部化**: 将上传服务类型和配置放在配置文件中
3. **错误处理**: 始终检查 `result.success`
4. **日志记录**: 在关键步骤添加日志便于调试
## 🎯 迁移指南
### 从旧版 CosUpload 迁移
**旧代码**:
```javascript
import CosUpload from '../../utils/CosUpload.js'
const cosUpload = new CosUpload(getSignFn)
```
**新代码**:
```javascript
import UploadFactory from '../../utils/IServer/UploadFactory.js'
const uploadService = UploadFactory.create('cos', getSignFn)
```
## 📞 技术支持
如有问题,请参考:
- `IUploadService.js` - 接口定义
- `CosUploadService.js` - COS实现参考
- `UploadFactory.js` - 工厂使用方法