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