147 lines
5.0 KiB
TypeScript
147 lines
5.0 KiB
TypeScript
import {i18n} from '@/locale'
|
||
const baseUrl = import.meta.env.VITE_SERVER_BASEURL
|
||
|
||
const UPLOAD_ENDPOINT = '/resource/oss/upload'
|
||
const CLIENT_ID = 'e5cd7e4891bf95d1d19206ce24a7b32e'
|
||
|
||
|
||
function parseUploadResponse(data: any): string {
|
||
const parsed = typeof data === 'string' ? JSON.parse(data || '{}') : (data || {})
|
||
if (parsed.code && parsed.code !== 200) {
|
||
throw new Error(parsed.msg || 'upload failed')
|
||
}
|
||
return parsed?.data?.url || parsed?.data || parsed?.url || ''
|
||
}
|
||
|
||
// === 图片压缩函数 ===
|
||
function compressImageIfNeeded(filePath: string, size: number): Promise<string> {
|
||
return new Promise((resolve, reject) => {
|
||
// #ifdef APP-PLUS
|
||
if (size > 3 * 1024 * 1024) {
|
||
uni.compressImage({
|
||
src: filePath,
|
||
quality: 70,
|
||
success: res => {
|
||
uni.getFileInfo({
|
||
filePath: res.tempFilePath,
|
||
success: info => resolve(res.tempFilePath),
|
||
fail: () => resolve(res.tempFilePath),
|
||
})
|
||
},
|
||
fail: err => reject(err),
|
||
})
|
||
} else {
|
||
resolve(filePath)
|
||
}
|
||
// #endif
|
||
|
||
// #ifdef H5
|
||
if (size > 3 * 1024 * 1024) {
|
||
const img = new Image()
|
||
img.crossOrigin = 'Anonymous'
|
||
img.onload = function () {
|
||
const canvas = document.createElement('canvas')
|
||
canvas.width = img.width
|
||
canvas.height = img.height
|
||
const ctx = canvas.getContext('2d')
|
||
ctx?.drawImage(img, 0, 0, img.width, img.height)
|
||
canvas.toBlob(
|
||
blob => {
|
||
if (blob) {
|
||
const url = URL.createObjectURL(blob)
|
||
resolve(url)
|
||
} else {
|
||
reject(new Error('图片压缩失败'))
|
||
}
|
||
},
|
||
'image/jpeg',
|
||
0.7
|
||
)
|
||
}
|
||
img.onerror = () => reject(new Error('图片加载失败'))
|
||
img.src = filePath
|
||
} else {
|
||
resolve(filePath)
|
||
}
|
||
// #endif
|
||
|
||
// #ifndef APP-PLUS || H5
|
||
resolve(filePath)
|
||
// #endif
|
||
})
|
||
}
|
||
|
||
// 上传文件到后端接口
|
||
const uploadToS3 = async function (filePath: string, suffix = '.jpg', dir = 'cheflink/'): Promise<string> {
|
||
if (!filePath) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.picture-wrong-please-try-again')})
|
||
return Promise.reject(new Error('filePath is empty'))
|
||
}
|
||
|
||
// 获取文件信息
|
||
let fileInfo: UniApp.GetFileInfoSuccessCallbackResult
|
||
try {
|
||
fileInfo = await new Promise((resolve, reject) => {
|
||
uni.getFileInfo({
|
||
filePath,
|
||
success: resolve,
|
||
fail: reject,
|
||
})
|
||
})
|
||
} catch (err) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.request-incorrect')})
|
||
return Promise.reject(err)
|
||
}
|
||
|
||
// 压缩图片(如果大于 3MB)
|
||
let uploadPath: string
|
||
try {
|
||
uploadPath = await compressImageIfNeeded(filePath, fileInfo.size)
|
||
} catch (err) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.request-incorrect')})
|
||
return Promise.reject(err)
|
||
}
|
||
|
||
return new Promise((resolve, reject) => {
|
||
uni.uploadFile({
|
||
url:baseUrl+ UPLOAD_ENDPOINT,
|
||
filePath: uploadPath,
|
||
name: 'file',
|
||
header: {
|
||
clientid: CLIENT_ID,
|
||
},
|
||
formData: {},
|
||
success: res => {
|
||
if (res.statusCode !== 200) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.up-failed')})
|
||
reject(new Error(`上传失败,状态码: ${res.statusCode}`))
|
||
return
|
||
}
|
||
try {
|
||
const uploadedUrl = parseUploadResponse(res.data)
|
||
if (!uploadedUrl) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.up-failed')})
|
||
reject(new Error('上传失败,返回地址为空'))
|
||
return
|
||
}
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.operation-success')})
|
||
resolve(uploadedUrl)
|
||
} catch (error) {
|
||
uni.showToast({icon: 'none', title: i18n.global.t('common.prompt.up-failed')})
|
||
reject(error)
|
||
}
|
||
},
|
||
fail: err => {
|
||
uni.showToast({
|
||
icon: 'none',
|
||
title: i18n.global.t('common.prompt.request-failed-please-try-again-later')
|
||
})
|
||
reject(err)
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
export {uploadToS3}
|
||
|