|
|
- 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中...' })
-
- // 上传文件到OSS
- const uploadResult = await uploadImage(file)
-
- uni.hideLoading()
-
- if (uploadResult.success) {
- uni.showToast({ title: 'OSS上传成功', 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
- }
|