Auto merge base into main
This commit is contained in:
commit
57e81b20f7
@ -1,69 +1,144 @@
|
|||||||
// TODO: 别忘加更改环境变量的 VITE_UPLOAD_BASEURL 地址。
|
import { ref, Ref } from 'vue'
|
||||||
import { getEnvBaseUploadUrl } from '@/utils'
|
import { getEnvBaseUploadUrl } from '@/utils'
|
||||||
|
|
||||||
const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
|
const VITE_UPLOAD_BASEURL = `${getEnvBaseUploadUrl()}`
|
||||||
|
|
||||||
/**
|
type TfileType = 'image' | 'file'
|
||||||
* useUpload 是一个定制化的请求钩子,用于处理上传图片。
|
type TImage = 'png' | 'jpg' | 'jpeg' | 'webp' | '*'
|
||||||
* @param formData 额外传递给后台的数据,如{name: '菲鸽'}。
|
type TFile = 'doc' | 'docx' | 'ppt' | 'zip' | 'xls' | 'xlsx' | 'txt' | TImage
|
||||||
* @returns 返回一个对象{loading, error, data, run},包含请求的加载状态、错误信息、响应数据和手动触发请求的函数。
|
|
||||||
*/
|
type TOptions<T extends TfileType> = {
|
||||||
export default function useUpload<T = string>(formData: Record<string, any> = {}) {
|
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 = ['*'],
|
||||||
|
fileType = 'image',
|
||||||
|
success,
|
||||||
|
error: onError,
|
||||||
|
} = options
|
||||||
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const error = ref(false)
|
const error = ref<Error | null>(null)
|
||||||
const data = ref<T>()
|
const data = ref<any>(null)
|
||||||
|
|
||||||
const run = () => {
|
const run = () => {
|
||||||
// #ifdef MP-WEIXIN
|
// #ifdef MP-WEIXIN
|
||||||
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
|
// 微信小程序从基础库 2.21.0 开始, wx.chooseImage 停止维护,请使用 uni.chooseMedia 代替。
|
||||||
// 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
|
// 微信小程序在2023年10月17日之后,使用本API需要配置隐私协议
|
||||||
|
const chooseFileOptions = {
|
||||||
|
count: 1,
|
||||||
|
success: (res: any) => {
|
||||||
|
handleFileChoose({ tempFilePath: res.tempFilePaths[0], tempFiles: res.tempFiles[0] })
|
||||||
|
},
|
||||||
|
fail: (err: any) => {
|
||||||
|
console.error('File selection failed:', err)
|
||||||
|
error.value = err
|
||||||
|
onError?.(err)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fileType === 'image') {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
uni.chooseMedia({
|
uni.chooseMedia({
|
||||||
count: 1,
|
...chooseFileOptions,
|
||||||
mediaType: ['image'],
|
mediaType: ['image'],
|
||||||
success: (res) => {
|
|
||||||
loading.value = true
|
|
||||||
const tempFilePath = res.tempFiles[0].tempFilePath
|
|
||||||
uploadFile<T>({ tempFilePath, formData, data, error, loading })
|
|
||||||
},
|
|
||||||
fail: (err) => {
|
|
||||||
console.error('uni.chooseMedia err->', err)
|
|
||||||
error.value = true
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// #ifndef MP-WEIXIN
|
// #ifndef MP-WEIXIN
|
||||||
uni.chooseImage({
|
uni.chooseImage(chooseFileOptions)
|
||||||
count: 1,
|
// #endif
|
||||||
success: (res) => {
|
} else {
|
||||||
|
uni.chooseFile({
|
||||||
|
...chooseFileOptions,
|
||||||
|
type: 'all',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFileChoose = (file: {
|
||||||
|
tempFilePath: string
|
||||||
|
tempFiles?: { size?: number; name?: string }
|
||||||
|
}) => {
|
||||||
|
if (file?.tempFiles?.size && file.tempFiles.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
|
loading.value = true
|
||||||
const tempFilePath = res.tempFilePaths[0]
|
uploadFile({
|
||||||
uploadFile<T>({ tempFilePath, formData, data, error, loading })
|
tempFilePath: file.tempFilePath,
|
||||||
|
formData,
|
||||||
|
onSuccess: (res) => {
|
||||||
|
data.value = res
|
||||||
|
success?.(res)
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
onError: (err) => {
|
||||||
console.error('uni.chooseImage err->', err)
|
error.value = err
|
||||||
error.value = true
|
onError?.(err)
|
||||||
|
},
|
||||||
|
onComplete: () => {
|
||||||
|
loading.value = false
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// #endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return { loading, error, data, run }
|
return { loading, error, data, run }
|
||||||
}
|
}
|
||||||
|
|
||||||
function uploadFile<T>({ tempFilePath, formData, data, error, loading }) {
|
async function uploadFile({
|
||||||
|
tempFilePath,
|
||||||
|
formData,
|
||||||
|
onSuccess,
|
||||||
|
onError,
|
||||||
|
onComplete,
|
||||||
|
}: {
|
||||||
|
tempFilePath: string
|
||||||
|
formData: Record<string, any>
|
||||||
|
onSuccess: (data: any) => void
|
||||||
|
onError: (err: any) => void
|
||||||
|
onComplete: () => void
|
||||||
|
}) {
|
||||||
uni.uploadFile({
|
uni.uploadFile({
|
||||||
url: VITE_UPLOAD_BASEURL,
|
url: VITE_UPLOAD_BASEURL,
|
||||||
filePath: tempFilePath,
|
filePath: tempFilePath,
|
||||||
name: 'file',
|
name: 'file',
|
||||||
formData,
|
formData,
|
||||||
success: (uploadFileRes) => {
|
success: (uploadFileRes) => {
|
||||||
data.value = uploadFileRes.data as T
|
try {
|
||||||
|
const data = JSON.parse(uploadFileRes.data)
|
||||||
|
onSuccess(data)
|
||||||
|
} catch (err) {
|
||||||
|
onError(err)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
fail: (err) => {
|
fail: (err) => {
|
||||||
console.error('uni.uploadFile err->', err)
|
console.error('Upload failed:', err)
|
||||||
error.value = true
|
onError(err)
|
||||||
},
|
|
||||||
complete: () => {
|
|
||||||
loading.value = false
|
|
||||||
},
|
},
|
||||||
|
complete: onComplete,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user