203 lines
4.7 KiB
JavaScript
203 lines
4.7 KiB
JavaScript
|
|
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')
|
|||
|
|
}
|