152 lines
3.6 KiB
JavaScript
152 lines
3.6 KiB
JavaScript
import { getQiniuUploadToken, uploadToQiniu } from '@/api/upload.js'
|
||
|
||
/**
|
||
* 七牛云图片上传服务
|
||
* 将临时文件路径转换为七牛云URL
|
||
* @param {string} tempFilePath - 临时文件路径
|
||
* @param {object} [options] - 配置选项
|
||
* @returns {Promise<string>} 七牛云文件URL
|
||
*/
|
||
export const tempUrlToRealUrl = async (tempFilePath, options = {}) => {
|
||
const {
|
||
maxSize = 10,
|
||
prefix = 'uploads/',
|
||
showToast = true,
|
||
domain = 'https://api.ccttiot.com',
|
||
} = options
|
||
|
||
try {
|
||
// 1. 检查文件大小
|
||
const fileInfo = await getFileInfo(tempFilePath)
|
||
const sizeInMB = fileInfo.size / (1024 * 1024)
|
||
|
||
if (sizeInMB > maxSize) {
|
||
throw new Error(`文件大小不能超过 ${maxSize}MB`)
|
||
}
|
||
|
||
// 2. 获取上传凭证
|
||
const token = await getQiniuToken()
|
||
if (!token) {
|
||
throw new Error('获取上传凭证失败')
|
||
}
|
||
|
||
// 3. 生成唯一文件名
|
||
const fileExt = getFileExtension(tempFilePath)
|
||
const key = generateUniqueKey(prefix, fileExt)
|
||
|
||
// 4. 上传到七牛云
|
||
const uploadResult = await uploadToQiniu(tempFilePath, token, key)
|
||
|
||
if (!uploadResult || !uploadResult.key) {
|
||
throw new Error('上传失败:未返回有效结果')
|
||
}
|
||
|
||
// 5. 构建完整URL
|
||
const qiniuUrl = `${domain}/${uploadResult.key}`
|
||
|
||
if (showToast) {
|
||
// console.log('签名上传成功')
|
||
// uni.showToast({ title: '签名上传成功', icon: 'success' })
|
||
}
|
||
|
||
return qiniuUrl
|
||
} catch (error) {
|
||
console.error('七牛云上传失败:', error)
|
||
if (showToast) {
|
||
uni.showToast({
|
||
title: error.message || '上传失败',
|
||
icon: 'none',
|
||
})
|
||
}
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 批量上传多张图片
|
||
* @param {string[]} tempFilePaths - 临时文件路径数组
|
||
* @returns {Promise<string[]>} 七牛云URL数组
|
||
*/
|
||
export const batchUploadToQiniu = async tempFilePaths => {
|
||
return Promise.all(
|
||
tempFilePaths.map(filePath => uploadToQiniuUrl(filePath, { showToast: false }))
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 获取文件信息
|
||
* @private
|
||
*/
|
||
const getFileInfo = filePath => {
|
||
return new Promise((resolve, reject) => {
|
||
uni.getFileInfo({
|
||
filePath,
|
||
success: resolve,
|
||
fail: reject,
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 获取七牛云上传token
|
||
* @private
|
||
*/
|
||
const getQiniuToken = async () => {
|
||
try {
|
||
const res = await getQiniuUploadToken()
|
||
|
||
if (res.code === 200) {
|
||
// 兼容不同返回格式
|
||
return res.data?.token || res.data
|
||
} else {
|
||
throw new Error(res.msg || '获取token失败')
|
||
}
|
||
} catch (error) {
|
||
console.error('获取七牛云token失败:', error)
|
||
throw error
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 获取文件扩展名
|
||
* @private
|
||
*/
|
||
const getFileExtension = filePath => {
|
||
const parts = filePath.split('.')
|
||
return parts.length > 1 ? parts.pop().toLowerCase() : 'jpg'
|
||
}
|
||
|
||
/**
|
||
* 生成唯一文件名
|
||
* @private
|
||
*/
|
||
const generateUniqueKey = (prefix, extension) => {
|
||
const timestamp = Date.now()
|
||
const randomStr = Math.random().toString(36).slice(2, 10)
|
||
return `${prefix}${timestamp}_${randomStr}.${extension}`
|
||
}
|
||
|
||
/**
|
||
* 工具函数:检查是否为临时路径
|
||
* @param {string} url - 要检查的URL
|
||
*/
|
||
export const isTempFilePath = url => {
|
||
return (
|
||
url &&
|
||
(url.startsWith('http://temp/') ||
|
||
url.startsWith('wxfile://') ||
|
||
url.includes('tmp/') ||
|
||
!url.startsWith('http'))
|
||
)
|
||
}
|
||
|
||
/**
|
||
* 工具函数:从七牛云URL提取文件key
|
||
* @param {string} qiniuUrl - 七牛云完整URL
|
||
*/
|
||
export const extractQiniuKey = qiniuUrl => {
|
||
if (!qiniuUrl) return null
|
||
const urlObj = new URL(qiniuUrl)
|
||
return urlObj.pathname.substring(1) // 去除开头的/
|
||
}
|