chuangte_bike_newxcx/common/qiniuUploadUtil.js

203 lines
4.7 KiB
JavaScript
Raw Normal View History

2026-05-25 17:13:15 +08:00
import {
showQiniuUploadProgress,
hideQiniuUploadProgress,
updateQiniuUploadProgress,
resetQiniuUploadProgress,
qiniuUploadProgressState
} from './qiniuUploadProgress.js'
export const QINIU_UPLOAD_URL = 'https://up-z2.qiniup.com'
export const QINIU_CDN_PREFIX = 'https://api.ccttiot.com/'
export function fetchQiniuToken($u) {
return $u.get('/common/qiniuToken').then((res) => {
if (res.code == 200 && res.data) {
return res.data
}
return null
}).catch(() => null)
}
export function parseQiniuUploadKey(res) {
if (!res || res.statusCode !== 200 || res.data == null || res.data === '') {
return ''
}
try {
const body = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
if (!body || body.error) {
return ''
}
const key = body.key
if (typeof key !== 'string' || !key.trim()) {
return ''
}
return key.trim()
} catch (e) {
return ''
}
}
export function parseQiniuUploadUrl(res, cdnPrefix = QINIU_CDN_PREFIX) {
const key = parseQiniuUploadKey(res)
return key ? cdnPrefix + key : ''
}
/** 校验上传结果,不合法则抛错 */
export function assertValidUploadResult(result, returnKey = false) {
if (result == null || result === '') {
throw new Error('upload result empty')
}
const value = String(result).trim()
if (!value || value === 'undefined' || value.indexOf('undefined') !== -1) {
throw new Error('upload result invalid')
}
if (returnKey) {
return value
}
if (!/^https?:\/\//.test(value)) {
throw new Error('upload url invalid')
}
return value
}
function doUploadQiniuFile(options = {}) {
const {
filePath,
token,
key,
cdnPrefix = QINIU_CDN_PREFIX,
returnKey = false,
onProgress
} = options
return new Promise((resolve, reject) => {
if (!filePath) {
reject(new Error('missing filePath'))
return
}
if (!token) {
reject(new Error('missing token'))
return
}
if (!key) {
reject(new Error('missing key'))
return
}
const uploadTask = uni.uploadFile({
url: QINIU_UPLOAD_URL,
filePath,
name: 'file',
formData: {
token,
key
},
success: (res) => {
const uploadKey = parseQiniuUploadKey(res)
if (!uploadKey) {
reject(new Error('upload parse failed'))
return
}
try {
const result = returnKey ? uploadKey : cdnPrefix + uploadKey
resolve(assertValidUploadResult(result, returnKey))
} catch (e) {
reject(e)
}
},
fail: (err) => {
reject(err || new Error('upload request failed'))
}
})
if (uploadTask && uploadTask.onProgressUpdate && onProgress) {
uploadTask.onProgressUpdate(onProgress)
}
})
}
export function uploadQiniuFile(options = {}) {
const {
title = '上传中',
showProgress = true
} = options
if (showProgress) {
showQiniuUploadProgress(title)
}
return doUploadQiniuFile({
...options,
onProgress: showProgress ? updateQiniuUploadProgress : options.onProgress
}).then((result) => {
if (showProgress) {
qiniuUploadProgressState.progress = 100
qiniuUploadProgressState.speedText = '完成'
setTimeout(() => hideQiniuUploadProgress(), 200)
}
return result
}).catch((err) => {
if (showProgress) {
hideQiniuUploadProgress()
}
throw err
})
}
/**
* token 刷新与失败重试的上传默认最多 3 首次 + 重试 2
* 仅在上传结果校验通过后才 resolve调用方可放心展示
*/
export async function uploadQiniuFileWithRetry($u, options = {}) {
const maxRetry = options.maxRetry != null ? options.maxRetry : 2
const showProgress = options.showProgress !== false
const title = options.title || '上传中'
const returnKey = !!options.returnKey
let token = options.token || null
let lastError = null
if (showProgress) {
showQiniuUploadProgress(title)
}
for (let attempt = 0; attempt <= maxRetry; attempt++) {
try {
if (!token) {
token = await fetchQiniuToken($u)
}
if (!token) {
throw new Error('no token')
}
if (attempt > 0 && showProgress) {
resetQiniuUploadProgress()
qiniuUploadProgressState.title = maxRetry > 0
? `${title}(重试 ${attempt}/${maxRetry}`
: title
}
const result = await doUploadQiniuFile({
...options,
token,
onProgress: showProgress ? updateQiniuUploadProgress : options.onProgress
})
const validResult = assertValidUploadResult(result, returnKey)
if (showProgress) {
qiniuUploadProgressState.progress = 100
qiniuUploadProgressState.speedText = '完成'
setTimeout(() => hideQiniuUploadProgress(), 200)
}
return validResult
} catch (e) {
lastError = e
token = null
if (attempt < maxRetry) {
token = await fetchQiniuToken($u)
}
}
}
if (showProgress) {
hideQiniuUploadProgress()
}
throw lastError || new Error('upload failed')
}