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 { 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 { 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}