| import config from '@/config' | |
| import Crypto from '@/utils/oss-upload/common/crypto/crypto.js.js' | |
| import '@/utils/oss-upload/common/crypto/hmac.js' | |
| import '@/utils/oss-upload/common/crypto/sha1.js' | |
| import { Base64 } from '@/utils/oss-upload/common/crypto/base64.js' | |
| 
 | |
| /** | |
|  * 生成随机Key | |
|  */ | |
| function storeKey() { | |
|   let s = []; | |
|   let hexDigits = "0123456789abcdef"; | |
|   for (let i = 0; i < 36; i++) { | |
|     s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); | |
|   } | |
|   s[14] = "4"; | |
|   s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); | |
|   s[8] = s[13] = s[18] = s[23] = "-"; | |
|   return s.join(""); | |
| } | |
| 
 | |
| /** | |
|  * 生成OSS签名配置 | |
|  */ | |
| function generateOSSConfig() { | |
|   // 设置1小时后过期 | |
|   let date = new Date() | |
|   date = date.setHours(date.getHours() + 1) | |
|   let extime = "" + new Date(date).toISOString() | |
|    | |
|   let policyText = { | |
|     "expiration": extime, | |
|     "conditions": [ | |
|       ["content-length-range", 0, 1024 * 1024 * 100] // 设置上传文件的大小限制100MB | |
|     ] | |
|   }; | |
|    | |
|   const policyBase64 = Base64.encode(JSON.stringify(policyText)) | |
|    | |
|   // 生成签名 | |
|   let bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, config.aliOSS_secretKey, { | |
|     asBytes: true | |
|   }); | |
|   let signature = Crypto.util.bytesToBase64(bytes); | |
|    | |
|   return { | |
|     accessid: config.aliOSS_accessKey, | |
|     // host: `https://${config.aliOSS_bucketName}.${config.endpoint}`, | |
|     host: config.staticDomain, | |
|     signature: signature, | |
|     policyBase64: policyBase64, | |
|   } | |
| } | |
| 
 | |
| /** | |
|  * OSS上传功能(使用签名认证) | |
|  * @param {Object} file - 文件对象(uni.chooseImage返回的文件) | |
|  * @returns {Promise<Object>} 返回上传结果 | |
|  */ | |
| const uploadImage = async (file) => { | |
|   try { | |
|     // 生成OSS配置和签名 | |
|     const ossConfig = generateOSSConfig() | |
|      | |
|     // 生成唯一文件名 | |
|     const timestamp = Date.now() | |
|     const randomStr = Math.random().toString(36).substring(2, 8) | |
|     const fileExtension = getFileExtension(file.name || file.path || '.jpg') | |
|     const fileName = `avatars/${timestamp}_${randomStr}${fileExtension}` | |
| 
 | |
|     const result = await uni.uploadFile({ | |
|       url: ossConfig.host, | |
|       filePath: file.path || file.tempFilePath, | |
|       name: 'file', | |
|       formData: { | |
|         key: fileName, | |
|         policy: ossConfig.policyBase64, | |
|         OSSAccessKeyId: ossConfig.accessid, | |
|         success_action_status: '200', | |
|         signature: ossConfig.signature, | |
|       } | |
|     }) | |
| 
 | |
|     console.log('OSS上传结果:', result) | |
|      | |
|     // 检查上传是否成功 | |
|     if (result.errMsg && result.errMsg.includes("uploadFile:ok")) { | |
|       const fileUrl = `${config.staticDomain}${fileName}` | |
|       return { | |
|         success: true, | |
|         url: fileUrl, | |
|         fileName: fileName | |
|       } | |
|     } else { | |
|       throw new Error(`OSS上传失败,状态码: ${result.statusCode}, 错误信息: ${result.errMsg}`) | |
|     } | |
|   } catch (error) { | |
|     console.error('OSS上传失败:', error) | |
|     return { | |
|       success: false, | |
|       error: error.message || 'OSS上传失败' | |
|     } | |
|   } | |
| } | |
| 
 | |
| /** | |
|  * 获取文件扩展名 | |
|  */ | |
| const getFileExtension = (fileName) => { | |
|   if (!fileName) return '.jpg' | |
|   const lastDot = fileName.lastIndexOf('.') | |
|   return lastDot !== -1 ? fileName.substring(lastDot) : '.jpg' | |
| } | |
| 
 | |
| /** | |
|  * 选择并上传图片到OSS(一步到位) | |
|  */ | |
| const chooseAndUpload = async () => { | |
|   try { | |
|     // 选择图片 | |
|     const chooseResult = await uni.chooseImage({ | |
|       count: 1, | |
|       sizeType: ['compressed'], | |
|       sourceType: ['album', 'camera'] | |
|     }) | |
| 
 | |
|     if (chooseResult.tempFilePaths && chooseResult.tempFilePaths.length > 0) { | |
|       const file = { | |
|         path: chooseResult.tempFilePaths[0], | |
|         tempFilePath: chooseResult.tempFilePaths[0] | |
|       } | |
| 
 | |
|       // 显示加载提示 | |
|       uni.showLoading({ title: '上传中...' }) | |
| 
 | |
|       // 上传文件到OSS | |
|       const uploadResult = await uploadImage(file) | |
|        | |
|       uni.hideLoading() | |
| 
 | |
|       if (uploadResult.success) { | |
|         uni.showToast({ title: '上传成功!', icon: 'success' }) | |
|         return uploadResult | |
|       } else { | |
|         uni.showToast({ title: uploadResult.error, icon: 'error' }) | |
|         return null | |
|       } | |
|     } | |
|   } catch (error) { | |
|     uni.hideLoading() | |
|     uni.showToast({ title: 'OSS上传失败', icon: 'error' }) | |
|     console.error('OSS上传失败:', error) | |
|     return null | |
|   } | |
| } | |
| 
 | |
| export { | |
|   uploadImage, | |
|   chooseAndUpload, | |
|   getFileExtension | |
| }
 |