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