import { ref, watch } from 'vue' import { isArray, isEmptyVariableInDefault, isPromise, isString, } from '../../../../utils' import { isJsonString } from '../../../../utils/validator' import type { ImageUploadFile, ImageUploadListItem } from '../types' import type { ImageUploadProps } from '../image-upload' export default function useUploadHandleFunction(props: ImageUploadProps) { // 选择系统图片 const chooseImage = (count: number) => { return new Promise>((resolve, reject) => { uni.chooseImage({ count, sizeType: props.sizeType, // extension: props.extensions, sourceType: props.sourceType, success: (res) => { resolve(isArray(res.tempFiles) ? res.tempFiles : [res.tempFiles]) }, fail: (err) => { reject(err) }, }) }) } // 上传图片事件,调用接口 // 正在上传标识 const uploading = ref(false) watch( () => uploading.value, (val) => { if (props.showErrorTips) { if (val) uni.showLoading({ title: '上传中' }) else uni.hideLoading() } } ) const uploadProcess = (item: ImageUploadListItem): Promise => { const { customUploadHandler, customUploadCallback } = props if (uploading.value) return Promise.reject('有文件正在上传') return new Promise((resolve, reject) => { // 如果有自定义上传处理函数,则调用自定义上传处理函数 if (customUploadHandler) { const uploadHandlerResult = customUploadHandler(item.file!) const isUploadHandlePromiseOrString = [ isPromise(uploadHandlerResult), isString(uploadHandlerResult), ].includes(true) if (!isUploadHandlePromiseOrString) { console.error( '[TnImageUpload]自定义上传处理函数必须返回Promise和String' ) reject('自定义上传处理函数必须返回Promise和String') return } uploading.value = true item.status = 'uploading' if (isPromise(uploadHandlerResult)) { uploadHandlerResult .then((res) => { if (res) { item.url = res resolve(true) } else { resolve(false) } }) .catch((err) => { console.error('[TnImageUpload]上传文件发生错误', err) reject(err?.errMsg || '上传文件发生错误') }) .finally(() => { uploading.value = false }) } else { if (uploadHandlerResult) { item.url = uploadHandlerResult resolve(true) } else { resolve(false) } uploading.value = false } } else { // 内部集成图片上传 uploading.value = true item.status = 'uploading' // 创建上传对象 const task = uni.uploadFile({ url: props.action!, filePath: item.url, name: props.name, formData: props.formData, header: props.header, success: (res: UniApp.UploadFileSuccessCallbackResult) => { // 判断用户是否自己处理上传后服务器回传的结果 if (customUploadCallback) { const customUploadCallbackResult = customUploadCallback(res) const isCustomUploadCallbackPromiseOrString = [ isPromise(customUploadCallbackResult), isString(customUploadCallbackResult), ].includes(true) if (!isCustomUploadCallbackPromiseOrString) { console.error( '[TnImageUpload]自定义上传回调函数必须返回Promise和String' ) reject('自定义上传回调函数必须返回Promise和String') return } if (isPromise(customUploadCallbackResult)) { customUploadCallbackResult .then((res) => { if (res) { item.url = res resolve(true) } else { resolve(false) } }) .catch((err) => { console.error('[TnImageUpload]上传文件发生错误', err) reject(err?.errMsg || '上传文件发生错误') }) } else { if (customUploadCallbackResult) { item.url = customUploadCallbackResult resolve(true) } else { resolve(false) } } } else { // 使用集成的上传回调函数 const { statusCode, data: resData } = res if (![200, 201, 204].includes(statusCode)) { console.error('[TnImageUpload]上传文件发生错误', res) reject(res?.errMsg || '上传文件发生错误') return } else { const data = isJsonString(resData) ? JSON.parse(resData) : resData // 默认返回的格式为 { code: 200, data: { errorCode: 0, url: '' } } if (data.code === 200 && data.data.errCode === 0) { item.url = data.data.url resolve(true) } else { console.error('[TnImageUpload]上传文件发生错误', res) reject( isEmptyVariableInDefault( data?.message, data?.msg || '上传文件发生错误' ) ) } } } }, fail: (err) => { console.error('[TnImageUpload]上传文件发生错误', err) reject(err?.errMsg || '上传文件发生错误') }, complete: () => { uploading.value = false resolve(true) }, }) item.uploadTask = task // 监听上传进度 task.onProgressUpdate((res) => { if (res.progress > 0) { item.progress = res.progress } }) } }) } // 检查文件是否超过最大文件尺寸或者不符合上传文件类型 const checkFileSizeAndExtension = (files: Array) => { const { extensions, maxSize } = props // #ifdef MP-ALIPAY extensions.push('image') // #endif const extReg = /.+\./ return files.filter((item) => { // 获取文件后缀名 let fileExt = '' // #ifdef H5 fileExt = (item as File).name.replace(extReg, '').toLowerCase() // #endif // #ifndef H5 fileExt = (item as UniApp.ChooseImageSuccessCallbackResultFile).path .replace(extReg, '') .toLowerCase() // #endif return ( !extensions.some((ext) => ext.toLowerCase() === fileExt) || item.size > maxSize ) }) } // 是否显示错误提示 const showErrorTips = (msg: string) => { if (!props.showErrorTips) return uni.showToast({ icon: 'none', title: msg, }) } return { chooseImage, uploadProcess, checkFileSizeAndExtension, showErrorTips, } }