UniApp 对象存储实战:腾讯云 COS 集成与图片上传优化 (RuoYi-Vue + UniApp)
本文介绍了如何在UniApp电商应用中集成腾讯云对象存储(COS)实现高效图片上传。通过RuoYi-Vue后端封装TencentCosService提供统一上传接口,前端封装跨平台上传工具类,构建了一套高可用、低延迟的文件管理体系。方案采用服务端中转模式,既保证了安全性又实现了CDN加速,有效解决了传统本地存储的并发性能、带宽占用等问题。文章还提到了进阶的客户端直传优化方案(Presigned U
☁️ UniApp 对象存储实战:腾讯云 COS 集成与图片上传优化 (RuoYi-Vue + UniApp)
图片上传是电商 App 中最常见的交互之一(如评价晒单、头像修改)。传统的本地文件存储在并发性能、带宽占用和 CDN 加速方面存在天然劣势。
本文将深入解析如何将 RuoYi-Vue 后端与 腾讯云 COS (Cloud Object Storage) 进行深度集成,并在 UniApp 端实现高性能的图片上传组件。
1. 为什么选择对象存储 (COS)?
相比于将文件存储在服务器本地磁盘,COS 优势明显:
- 高可用性: 99.95% 的服务可用性,数据多重备份。
- CDN 加速: 配合 CDN,用户查看图片几乎零延迟。
- 带宽解耦: 上传/下载流量不占用应用服务器带宽,避免阻塞业务请求。
- 成本低廉: 按量付费,存储和流量成本远低于云服务器磁盘。
2. 后端架构设计与实现
2.1 依赖引入与配置
首先,在 ruoyi-common/pom.xml 或 ruoyi-system/pom.xml 中引入腾讯云 COS SDK:
<!-- 腾讯云 COS -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.89</version>
</dependency>
在 ruoyi-admin/src/main/resources/application.yml 中配置密钥信息:
# 腾讯云 COS 配置
cos:
access_key: 'AKID****************************' # 替换为你的 SecretId
secret_key: '********************************' # 替换为你的 SecretKey
region_name: 'ap-guangzhou' # 存储桶地域
bucket_name: 'ruoyi-vue-1250000000' # 存储桶名称
key_name: 'images' # 默认存储前缀
2.2 核心服务封装 (TencentCosService)
为了解耦业务,我们封装了 TencentCosService,屏蔽了底层的 SDK 细节,提供简洁的 uploadFile 接口。
// ruoyi-system/src/main/java/com/ruoyi/system/service/TencentCosService.java
@Service
public class TencentCosService {
// ... 注入配置项 ...
/**
* 上传文件到 COS
*/
public String uploadFile(MultipartFile file) throws IOException {
// 1. 生成唯一文件名 (UUID + 扩展名)
String originalFilename = file.getOriginalFilename();
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
String cosKey = keyName + "/" + UUID.randomUUID().toString().replace("-", "") + extension;
// 2. 初始化客户端
COSClient cosClient = initCOSClient();
try {
// 3. 转换文件流并上传
File tempFile = File.createTempFile("upload_", extension);
file.transferTo(tempFile);
PutObjectRequest request = new PutObjectRequest(bucketName, cosKey, tempFile);
cosClient.putObject(request);
// 4. 返回 CDN 访问链接
return String.format("https://%s.cos.%s.myqcloud.com/%s", bucketName, regionName, cosKey);
} finally {
cosClient.shutdown();
}
}
}
2.3 控制层接口暴露
在 CommonController 中扩展 /common/upload 接口,使其支持透明切换到 COS 上传。
// ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception {
try {
// 切换为 COS 上传服务
String fileUrl = tencentCosService.uploadFile(file);
AjaxResult ajax = AjaxResult.success();
ajax.put("url", fileUrl); // 返回完整 CDN 地址
ajax.put("fileName", fileUrl.substring(fileUrl.lastIndexOf("/") + 1));
return ajax;
} catch (Exception e) {
return AjaxResult.error(e.getMessage());
}
}
3. 前端 UniApp 实现
前端需要处理跨平台兼容性(H5/微信小程序/App),并封装统一的上传逻辑。
3.1 上传工具类封装 (utils/upload.js)
我们封装了 uni.uploadFile,自动携带 Token 并统一处理错误。
// utils/upload.js
import config from '@/config'
import { getToken } from '@/utils/auth'
const upload = config => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: config.baseUrl + config.url, // 完整后端地址
filePath: config.filePath, // 本地临时路径
name: config.name || 'file',
header: {
Authorization: 'Bearer ' + getToken() // 鉴权 Token
},
success: (res) => {
let result = JSON.parse(res.data)
if (result.code === 200) {
resolve(result)
} else {
reject(result.msg)
}
},
fail: (error) => {
reject('网络请求失败')
}
})
})
}
export default upload
3.2 使用示例:头像上传
在用户个人中心 (pages/mine/info/index.vue) 中调用:
// 选择图片
chooseAvatar() {
uni.chooseImage({
count: 1,
sizeType: ['compressed'], // 优先使用压缩图
success: (res) => {
const tempFilePath = res.tempFilePaths[0]
this.uploadImage(tempFilePath)
}
})
},
// 上传逻辑
async uploadImage(filePath) {
try {
uni.showLoading({ title: '上传中...' })
const res = await upload({
url: '/common/upload',
filePath: filePath
})
// 更新视图
this.user.avatar = res.url
// 提交到后端保存用户资料
await updateUserProfile({ avatar: res.url })
uni.showToast({ title: '上传成功' })
} catch (e) {
uni.showToast({ title: '上传失败', icon: 'none' })
} finally {
uni.hideLoading()
}
}
4. 进阶优化:客户端直传 (Presigned URL)
为了进一步减轻应用服务器压力,可以使用 预签名 URL (Presigned URL) 方案:
- 前端请求签名: 前端向后端请求一个临时的上传授权 URL。
- 后端生成签名: 后端使用 COS SDK 生成带有效期的
PUT请求签名。 - 前端直传 COS: 前端直接将文件
PUT到腾讯云,绕过应用服务器。
(注:本文展示的方案为服务端中转模式,适合中小规模应用,实现简单且便于权限控制。)
总结:通过引入腾讯云 COS,我们成功解决了应用服务器的存储瓶颈。后端封装通用服务,前端统一上传工具,构建了一套高效、可维护的文件管理体系。
更多推荐
所有评论(0)