mi-assessment/uniapp/utils/upload.js
zpc 3f179e5682 feat(upload): 头像直传COS + 修复用户资料接口404
后端:
- Model层新增UploadSetting配置模型
- Core层新增IUploadConfigService/UploadConfigService,从Admin库读取COS配置生成预签名URL
- Api层新增UploadController,提供POST /api/upload/presignedUrl接口
- ServiceModule注册UploadConfigService服务

前端:
- api/user.js修复接口路径:updateProfileupdate_userinfo,upload/imageupload/presignedUrl
- 新增utils/upload.js COS直传工具(获取预签名URL直传COS返回文件URL)
- 个人资料页改为:选图直传COS保存时提交headimg URL到update_userinfo
2026-02-20 23:21:56 +08:00

75 lines
2.2 KiB
JavaScript
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.

/**
* COS直传工具
* 通过预签名URL将文件直传到腾讯云COS
*/
import { getPresignedUploadUrl } from '@/api/user.js'
/**
* 选择图片并上传到COS
* @param {Object} [options] - 选项
* @param {number} [options.count=1] - 选择数量
* @param {string[]} [options.sourceType] - 来源类型
* @returns {Promise<string>} 上传后的文件URL
*/
export async function chooseAndUploadImage(options = {}) {
const { count = 1, sourceType = ['album', 'camera'] } = options
// 1. 选择图片
const chooseRes = await new Promise((resolve, reject) => {
uni.chooseImage({
count,
sizeType: ['compressed'],
sourceType,
success: resolve,
fail: (err) => {
if (err.errMsg && err.errMsg.includes('cancel')) {
reject(new Error('用户取消选择'))
} else {
reject(new Error('选择图片失败'))
}
}
})
})
const tempFilePath = chooseRes.tempFilePaths[0]
const fileName = tempFilePath.split('/').pop() || 'image.png'
// 判断文件类型
const ext = fileName.split('.').pop()?.toLowerCase() || 'png'
const mimeMap = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', gif: 'image/gif', webp: 'image/webp' }
const contentType = mimeMap[ext] || 'image/png'
// 2. 获取预签名URL
const presignedRes = await getPresignedUploadUrl(fileName, contentType)
if (!presignedRes || presignedRes.code !== 0 || !presignedRes.data) {
throw new Error(presignedRes?.message || '获取上传地址失败')
}
const { uploadUrl, fileUrl } = presignedRes.data
// 3. 直传COS使用PUT请求
await new Promise((resolve, reject) => {
uni.uploadFile({
url: uploadUrl,
filePath: tempFilePath,
name: 'file',
header: {
'Content-Type': contentType
},
success: (res) => {
// COS PUT上传成功返回200
if (res.statusCode >= 200 && res.statusCode < 300) {
resolve(res)
} else {
reject(new Error(`上传失败,状态码: ${res.statusCode}`))
}
},
fail: (err) => reject(new Error(err.errMsg || '上传失败'))
})
})
// 4. 返回文件访问URL
return fileUrl
}