unibest/src/hooks/useUpload.ts

159 lines
4.2 KiB
TypeScript
Raw Normal View History

import { ref } from 'vue'
import { getEnvBaseUploadUrl } from '@/utils'
const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
2024-05-15 10:06:51 +08:00
2025-06-04 16:21:35 +08:00
type TfileType = 'image' | 'file'
type TImage = 'png' | 'jpg' | 'jpeg' | 'webp' | '*'
type TFile = 'doc' | 'docx' | 'ppt' | 'zip' | 'xls' | 'xlsx' | 'txt' | TImage
2025-06-20 12:12:21 +08:00
interface TOptions<T extends TfileType> {
2025-06-04 16:21:35 +08:00
formData?: Record<string, any>
maxSize?: number
accept?: T extends 'image' ? TImage[] : TFile[]
fileType?: T
success?: (params: any) => void
error?: (err: any) => void
}
export default function useUpload<T extends TfileType>(options: TOptions<T> = {} as TOptions<T>) {
const {
formData = {},
maxSize = 5 * 1024 * 1024,
accept = ['*'],
2025-06-04 16:21:35 +08:00
fileType = 'image',
success,
error: onError,
} = options
2024-05-03 14:13:22 +08:00
const loading = ref(false)
2025-06-04 16:21:35 +08:00
const error = ref<Error | null>(null)
const data = ref<any>(null)
2024-05-03 14:13:22 +08:00
const run = () => {
2025-06-20 12:12:21 +08:00
const handleFileChoose = ({ tempFilePath, size }: { tempFilePath: string, size: number }) => {
if (size > maxSize) {
uni.showToast({
title: `文件大小不能超过 ${maxSize / 1024 / 1024}MB`,
icon: 'none',
})
return
}
// const fileExtension = file?.tempFiles?.name?.split('.').pop()?.toLowerCase()
// const isTypeValid = accept.some((type) => type === '*' || type.toLowerCase() === fileExtension)
// if (!isTypeValid) {
// uni.showToast({
// title: `仅支持 ${accept.join(', ')} 格式的文件`,
// icon: 'none',
// })
// return
// }
loading.value = true
uploadFile({
tempFilePath,
formData,
onSuccess: (res) => {
const { data: _data } = JSON.parse(res)
data.value = _data
// console.log('上传成功', res)
success?.(_data)
},
onError: (err) => {
error.value = err
onError?.(err)
},
onComplete: () => {
loading.value = false
},
})
}
2024-05-03 14:13:22 +08:00
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
// 微信小程序在2023年10月17日之后使用本API需要配置隐私协议
2025-06-04 16:21:35 +08:00
const chooseFileOptions = {
2024-05-03 14:13:22 +08:00
count: 1,
2025-06-04 16:21:35 +08:00
success: (res: any) => {
console.log('File selected successfully:', res)
// h5中res:{errMsg: "chooseImage:ok", tempFilePaths: "blob:http://localhost:9000/f74ab6b8-a14d-4cb6-a10d-fcf4511a0de5", tempFiles: [File]}
// h5的File有一下字段{name: "girl.jpeg", size: 48976, type: "image/jpeg"}
// 小程序中res:{errMsg: "chooseImage:ok", tempFiles: [{fileType: "image", size: 48976, tempFilePath: "http://tmp/5iG1WpIxTaJf3ece38692a337dc06df7eb69ecb49c6b.jpeg"}]}
let tempFilePath = ''
let size = 0
// #ifdef H5
tempFilePath = res.tempFilePaths[0]
size = res.tempFiles[0].size
// #endif
// #ifdef MP-WEIXIN
tempFilePath = res.tempFiles[0].tempFilePath
size = res.tempFiles[0].size
// #endif
handleFileChoose({ tempFilePath, size })
2024-05-03 14:13:22 +08:00
},
2025-06-04 16:21:35 +08:00
fail: (err: any) => {
console.error('File selection failed:', err)
error.value = err
onError?.(err)
2024-05-03 14:13:22 +08:00
},
2025-06-04 16:21:35 +08:00
}
if (fileType === 'image') {
// #ifdef MP-WEIXIN
uni.chooseMedia({
...chooseFileOptions,
mediaType: ['image'],
})
// #endif
// #ifndef MP-WEIXIN
uni.chooseImage(chooseFileOptions)
// #endif
2025-06-20 12:12:21 +08:00
}
else {
2025-06-04 16:21:35 +08:00
uni.chooseFile({
...chooseFileOptions,
type: 'all',
})
}
}
2024-05-03 14:13:22 +08:00
return { loading, error, data, run }
}
2024-05-15 10:06:51 +08:00
2025-06-04 16:21:35 +08:00
async function uploadFile({
tempFilePath,
formData,
onSuccess,
onError,
onComplete,
}: {
tempFilePath: string
formData: Record<string, any>
onSuccess: (data: any) => void
onError: (err: any) => void
onComplete: () => void
}) {
2024-05-15 10:06:51 +08:00
uni.uploadFile({
url: VITE_UPLOAD_BASEURL,
filePath: tempFilePath,
name: 'file',
formData,
success: (uploadFileRes) => {
2025-06-04 16:21:35 +08:00
try {
const data = uploadFileRes.data
2025-06-04 16:21:35 +08:00
onSuccess(data)
2025-06-20 12:12:21 +08:00
}
catch (err) {
2025-06-04 16:21:35 +08:00
onError(err)
}
2024-05-15 10:06:51 +08:00
},
fail: (err) => {
2025-06-04 16:21:35 +08:00
console.error('Upload failed:', err)
onError(err)
2024-05-15 10:06:51 +08:00
},
2025-06-04 16:21:35 +08:00
complete: onComplete,
2024-05-15 10:06:51 +08:00
})
}