platform-vue/docs/七牛云直传配置.md
2026-04-09 18:07:55 +08:00

444 lines
9.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.

# 七牛云直传配置说明
## 概述
新的上传机制实现了前端直接上传到七牛云,不再通过后端中转,大幅提升大文件上传效率。
## 上传流程对比
### 旧流程(低效)
```
前端 → 后端服务器 → 七牛云
(中转暂存)
```
问题:
- 大文件需要先上传到服务器,再由服务器上传到七牛云
- 占用服务器带宽和磁盘空间
- 上传时间翻倍
- 服务器压力大
### 新流程(高效)
```
前端 → 七牛云(直传)
后端 → 数据库(仅保存记录)
```
优势:
- 前端直接上传到七牛云,不经过服务器
- 节省服务器资源
- 上传速度快
- 支持断点续传
## 安装依赖
### 前端安装七牛云 SDK
```bash
cd platform
npm install qiniu-js
```
或使用 yarn
```bash
yarn add qiniu-js
```
## 后端 API
### 1. 获取存储配置
**接口**: `GET /platform/storage/config`
**响应**:
```json
{
"code": 200,
"data": {
"storageType": "qiniu", // 或 "local"
"qiniuDomain": "http://7colud.yunzer.cn",
"qiniuRegion": "z0"
}
}
```
### 2. 获取上传凭证
**接口**: `GET /platform/qiniu/token`
**响应**:
```json
{
"code": 200,
"data": {
"token": "七牛云上传token",
"domain": "http://7colud.yunzer.cn",
"bucket": "your-bucket",
"region": "z0",
"keyPrefix": "2026/04/09/1775722615052606500",
"expires": 1712654400,
"uploadUrl": "https://up-z0.qiniup.com"
}
}
```
### 3. 保存文件记录
**接口**: `POST /platform/qiniu/save`
**请求**:
```json
{
"key": "2026/04/09/1775722615052606500.png",
"hash": "FhGxwBzoLwO_RGws...",
"size": 1024000,
"name": "screenshot.png",
"mimeType": "image/png",
"cate": 0
}
```
**响应**:
```json
{
"code": 200,
"data": {
"url": "http://7colud.yunzer.cn/2026/04/09/1775722615052606500.png",
"id": 123,
"name": "screenshot.png",
"key": "2026/04/09/1775722615052606500.png"
}
}
```
## 前端使用
### 基础用法
```javascript
import { smartUpload } from '@/utils/qiniuUpload';
// 自动选择上传方式(本地或七牛云)
const result = await smartUpload(file, {
cate: 0, // 文件分类
onProgress: (progress) => {
console.log('上传进度:', progress.percent + '%');
console.log('已上传:', progress.loaded);
console.log('总大小:', progress.total);
},
});
console.log('上传成功:', result);
// { url: '...', id: 123, name: '...', key: '...' }
```
### 在组件中使用
```vue
<template>
<el-upload
:http-request="handleUpload"
:on-progress="handleProgress"
>
<el-button>上传文件</el-button>
</el-upload>
<el-progress v-if="uploading" :percentage="uploadPercent" />
</template>
<script setup>
import { ref } from 'vue';
import { smartUpload } from '@/utils/qiniuUpload';
import { ElMessage } from 'element-plus';
const uploading = ref(false);
const uploadPercent = ref(0);
async function handleUpload(options) {
const file = options.file?.raw || options.file;
uploading.value = true;
try {
const result = await smartUpload(file, {
cate: 0,
onProgress: (progress) => {
uploadPercent.value = progress.percent;
},
});
ElMessage.success('上传成功');
options.onSuccess?.(result);
} catch (error) {
ElMessage.error(error.message || '上传失败');
options.onError?.(error);
} finally {
uploading.value = false;
}
}
</script>
```
### 批量上传
```javascript
import { batchUpload } from '@/utils/qiniuUpload';
const files = [file1, file2, file3];
const results = await batchUpload(files, {
cate: 0,
onFileProgress: (file, progress) => {
console.log(`${file.name}: ${progress.percent}%`);
},
onFileComplete: (file, result) => {
console.log(`${file.name} 上传成功:`, result);
},
onFileError: (file, error) => {
console.error(`${file.name} 上传失败:`, error);
},
});
console.log('所有文件上传完成:', results);
```
## 工作原理
### 1. 智能选择上传方式
`smartUpload` 函数会自动检测后端配置:
```javascript
// 1. 获取存储配置
const config = await getStorageConfig();
// 2. 根据配置选择上传方式
if (config.storageType === 'qiniu') {
// 七牛云直传
return uploadToQiniu(file, options);
} else {
// 本地上传(通过后端)
return uploadToLocal(file, options);
}
```
### 2. 七牛云直传流程
```javascript
// 1. 获取上传凭证
const tokenRes = await getQiniuToken();
const { token, keyPrefix } = tokenRes.data;
// 2. 生成文件 key
const key = `${keyPrefix}.${ext}`;
// 3. 使用七牛云 SDK 直接上传
const observable = qiniu.upload(file, key, token);
// 4. 监听上传进度
observable.subscribe({
next(res) {
// 进度回调
onProgress(res.total.percent);
},
complete(res) {
// 上传完成,保存记录到数据库
await saveFileRecord({
key: res.key,
hash: res.hash,
size: file.size,
name: file.name,
});
},
});
```
### 3. 本地上传流程
```javascript
// 通过后端中转(兼容本地存储)
const formData = new FormData();
formData.append('file', file);
const res = await request({
url: '/platform/uploadfile',
method: 'post',
data: formData,
onUploadProgress: (e) => {
onProgress(e.loaded / e.total * 100);
},
});
```
## 配置说明
### 七牛云区域配置
| 区域代码 | 区域名称 | 上传地址 |
|---------|---------|---------|
| z0 | 华东 | https://up-z0.qiniup.com |
| z1 | 华北 | https://up-z1.qiniup.com |
| z2 | 华南 | https://up-z2.qiniup.com |
| na0 | 北美 | https://up-na0.qiniup.com |
| as0 | 新加坡 | https://up-as0.qiniup.com |
| cn-east-2 | 华东-浙江2 | https://up-cn-east-2.qiniup.com |
### 上传策略配置
后端生成 token 时的策略:
```go
putPolicy := storage.PutPolicy{
Scope: cfg.QiniuBucket,
ReturnBody: `{"key":"$(key)","hash":"$(etag)","size":$(fsize),"mimeType":"$(mimeType)"}`,
Expires: 3600, // 1小时有效期
}
```
## 安全性
### 1. Token 有效期
上传 token 有效期为 1 小时,过期后需要重新获取。
### 2. 权限验证
- 获取 token 需要登录认证
- 保存文件记录需要登录认证
- 文件记录关联到当前用户和租户
### 3. 文件去重
通过 MD5 检查文件是否已存在,避免重复上传。
## 性能优化
### 1. 断点续传
七牛云 SDK 支持断点续传(大文件自动分片):
```javascript
const config = {
useCdnDomain: true,
region: qiniu.region.z0,
chunkSize: 4, // 分片大小MB
concurrentRequestLimit: 3, // 并发上传数
};
const observable = qiniu.upload(file, key, token, putExtra, config);
```
### 2. CDN 加速
启用 CDN 域名加速上传:
```javascript
const config = {
useCdnDomain: true, // 使用 CDN 加速
};
```
### 3. 并发上传
批量上传时可以控制并发数:
```javascript
// 限制同时上传 3 个文件
const concurrency = 3;
const results = [];
for (let i = 0; i < files.length; i += concurrency) {
const batch = files.slice(i, i + concurrency);
const batchResults = await Promise.all(
batch.map(file => smartUpload(file, options))
);
results.push(...batchResults);
}
```
## 故障排查
### 1. 上传失败:获取 token 失败
**错误**: "当前未配置七牛云存储"
**解决**:
- 检查数据库存储配置
- 确认 `storage_type``'qiniu'`
- 确认七牛云配置完整
### 2. 上传失败token 无效
**错误**: "401 Unauthorized"
**解决**:
- 检查 AccessKey 和 SecretKey 是否正确
- 检查 token 是否过期1小时有效期
- 重新获取 token
### 3. 上传失败bucket 不存在
**错误**: "no such bucket"
**解决**:
- 检查 bucket 名称是否正确
- 检查 bucket 是否在对应区域
- 登录七牛云控制台确认
### 4. 保存记录失败
**错误**: "保存文件记录失败"
**解决**:
- 检查数据库连接
- 检查文件信息是否完整
- 查看后端日志
## 迁移指南
### 从旧版本迁移
1. **安装依赖**:
```bash
npm install qiniu-js
```
2. **更新导入**:
```javascript
// 旧版本
import { uploadFile } from '@/api/file';
// 新版本
import { smartUpload } from '@/utils/qiniuUpload';
```
3. **更新上传代码**:
```javascript
// 旧版本
const formData = new FormData();
formData.append('file', file);
const res = await uploadFile(formData, { cate: 0 });
// 新版本
const result = await smartUpload(file, { cate: 0 });
```
4. **兼容性**:
- `smartUpload` 会自动检测存储配置
- 如果配置为本地存储,会自动使用旧的上传方式
- 无需修改其他代码
## 相关文件
### 后端
- `go/controllers/qiniu_upload.go` - 七牛云上传控制器
- `go/routers/platform/platform.go` - 路由配置
- `go/services/storage_service.go` - 存储服务
### 前端
- `platform/src/utils/qiniuUpload.js` - 七牛云上传工具
- `platform/src/views/platform/softwareupgrade/components/edit.vue` - 软件升级组件(示例)
## 更新日期
2026-04-09