style:上传控件-适配新接口响应格式/已上传显示文件名称/最大限制改为100MB

main
黄伟杰 5 days ago
parent 063b328844
commit 4463f257ba

@ -84,7 +84,7 @@ const emit = defineEmits(['update:modelValue'])
const props = defineProps({ const props = defineProps({
modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired, modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired,
fileType: propTypes.array.def(['png', 'jpg', 'jpeg', 'doc', 'xls', 'ppt', 'txt', 'pdf']), // , ['png', 'jpg', 'jpeg'] fileType: propTypes.array.def(['png', 'jpg', 'jpeg', 'doc', 'xls', 'ppt', 'txt', 'pdf']), // , ['png', 'jpg', 'jpeg']
fileSize: propTypes.number.def(5), // (MB) fileSize: propTypes.number.def(100), // (MB)
limit: propTypes.number.def(5), // limit: propTypes.number.def(5), //
autoUpload: propTypes.bool.def(true), // autoUpload: propTypes.bool.def(true), //
drag: propTypes.bool.def(false), // drag: propTypes.bool.def(false), //
@ -97,6 +97,7 @@ const uploadRef = ref<UploadInstance>()
const uploadList = ref<UploadUserFile[]>([]) const uploadList = ref<UploadUserFile[]>([])
const fileList = ref<UploadUserFile[]>([]) const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0) const uploadNumber = ref<number>(0)
const nameMap = ref<Record<string, string>>({})
const { uploadUrl, httpRequest } = useUpload() const { uploadUrl, httpRequest } = useUpload()
@ -130,14 +131,41 @@ const beforeUpload: UploadProps['beforeUpload'] = (file: UploadRawFile) => {
// const handleFileChange = (uploadFile: UploadFile): void => { // const handleFileChange = (uploadFile: UploadFile): void => {
// uploadRef.value.data.path = uploadFile.name // uploadRef.value.data.path = uploadFile.name
// } // }
// const getUrlFromRes = (res: any): string => {
const handleFileSuccess: UploadProps['onSuccess'] = (res: any): void => { if (!res) return ''
if (typeof res === 'string') return res
if (typeof res.data === 'string') return res.data
const data = res.data || res
if (typeof data === 'string') return data
if (data.fileUrl) return data.fileUrl
return ''
}
const getNameFromRes = (res: any, url: string): string => {
const data = res && res.data ? res.data : res
if (data && typeof data === 'object' && data.fileName) return data.fileName
if (!url) return ''
const idx = url.lastIndexOf('/')
return idx !== -1 ? url.substring(idx + 1) : url
}
const handleFileSuccess: UploadProps['onSuccess'] = (res: any, uploadFile): void => {
const url = getUrlFromRes(res)
if (!url) {
message.error('上传返回数据异常')
return
}
const name = getNameFromRes(res, url)
if (url && name) {
nameMap.value[url] = name
}
message.success('上传成功') message.success('上传成功')
// const index = fileList.value.findIndex((item) => item.uid === uploadFile.uid)
const index = fileList.value.findIndex((item) => item.response?.data === res.data) if (index > -1) {
fileList.value.splice(index, 1) fileList.value.splice(index, 1)
uploadList.value.push({ name: res.data, url: res.data }) }
if (uploadList.value.length == uploadNumber.value) { uploadList.value.push({ name, url })
if (uploadList.value.length === uploadNumber.value) {
fileList.value.push(...uploadList.value) fileList.value.push(...uploadList.value)
uploadList.value = [] uploadList.value = []
uploadNumber.value = 0 uploadNumber.value = 0
@ -156,7 +184,10 @@ const excelUploadError: UploadProps['onError'] = (): void => {
const handleRemove = (file: UploadFile) => { const handleRemove = (file: UploadFile) => {
const index = fileList.value.map((f) => f.name).indexOf(file.name) const index = fileList.value.map((f) => f.name).indexOf(file.name)
if (index > -1) { if (index > -1) {
fileList.value.splice(index, 1) const removed = fileList.value.splice(index, 1)[0]
if (removed && removed.url && nameMap.value[removed.url]) {
delete nameMap.value[removed.url]
}
emitUpdateModelValue() emitUpdateModelValue()
} }
} }
@ -164,6 +195,13 @@ const handlePreview: UploadProps['onPreview'] = (uploadFile) => {
console.log(uploadFile) console.log(uploadFile)
} }
const getDisplayNameByUrl = (url: string): string => {
const cached = nameMap.value[url]
if (cached) return cached
const idx = url.lastIndexOf('/')
return idx !== -1 ? url.substring(idx + 1) : url
}
// //
watch( watch(
() => props.modelValue, () => props.modelValue,
@ -176,14 +214,13 @@ watch(
fileList.value = [] // fileList.value = [] //
// 1 // 1
if (isString(val)) { if (isString(val)) {
fileList.value.push( const urls = val.split(',').filter((u) => !!u)
...val.split(',').map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url })) fileList.value.push(...urls.map((url) => ({ name: getDisplayNameByUrl(url), url })))
)
return return
} }
// 2 // 2
fileList.value.push( fileList.value.push(
...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url })) ...(val as string[]).map((url) => ({ name: getDisplayNameByUrl(url), url }))
) )
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }

@ -73,7 +73,7 @@ const props = defineProps({
modelValue: propTypes.string.def(''), modelValue: propTypes.string.def(''),
drag: propTypes.bool.def(true), // ==> true drag: propTypes.bool.def(true), // ==> true
disabled: propTypes.bool.def(false), // ==> false disabled: propTypes.bool.def(false), // ==> false
fileSize: propTypes.number.def(5), // ==> 5M fileSize: propTypes.number.def(100), // ==> 5M
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"] fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"]
height: propTypes.string.def('150px'), // ==> 150px height: propTypes.string.def('150px'), // ==> 150px
width: propTypes.string.def('150px'), // ==> 150px width: propTypes.string.def('150px'), // ==> 150px
@ -115,10 +115,24 @@ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
return imgType.includes(rawFile.type as FileTypes) && imgSize return imgType.includes(rawFile.type as FileTypes) && imgSize
} }
// const getUrlFromRes = (res: any): string => {
if (!res) return ''
if (typeof res === 'string') return res
if (typeof res.data === 'string') return res.data
const data = res.data || res
if (typeof data === 'string') return data
if (data.fileUrl) return data.fileUrl
return ''
}
const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
const url = getUrlFromRes(res)
if (!url) {
message.notifyError('上传返回数据异常')
return
}
message.success('上传成功') message.success('上传成功')
emit('update:modelValue', res.data) emit('update:modelValue', url)
} }
// //

@ -77,7 +77,7 @@ const props = defineProps({
drag: propTypes.bool.def(true), // ==> true drag: propTypes.bool.def(true), // ==> true
disabled: propTypes.bool.def(false), // ==> false disabled: propTypes.bool.def(false), // ==> false
limit: propTypes.number.def(5), // ==> 5 limit: propTypes.number.def(5), // ==> 5
fileSize: propTypes.number.def(5), // ==> 5M fileSize: propTypes.number.def(100), // ==> 5M
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"] fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // ==> ["image/jpeg", "image/png", "image/gif"]
height: propTypes.string.def('150px'), // ==> 150px height: propTypes.string.def('150px'), // ==> 150px
width: propTypes.string.def('150px'), // ==> 150px width: propTypes.string.def('150px'), // ==> 150px
@ -89,6 +89,7 @@ const { uploadUrl, httpRequest } = useUpload()
const fileList = ref<UploadUserFile[]>([]) const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0) const uploadNumber = ref<number>(0)
const uploadList = ref<UploadUserFile[]>([]) const uploadList = ref<UploadUserFile[]>([])
const nameMap = ref<Record<string, string>>({})
/** /**
* @description 文件上传之前判断 * @description 文件上传之前判断
* @param rawFile 上传的文件 * @param rawFile 上传的文件
@ -118,13 +119,41 @@ interface UploadEmits {
} }
const emit = defineEmits<UploadEmits>() const emit = defineEmits<UploadEmits>()
const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { const getUrlFromRes = (res: any): string => {
if (!res) return ''
if (typeof res === 'string') return res
if (typeof res.data === 'string') return res.data
const data = res.data || res
if (typeof data === 'string') return data
if (data.fileUrl) return data.fileUrl
return ''
}
const getNameFromRes = (res: any, url: string): string => {
const data = res && res.data ? res.data : res
if (data && typeof data === 'object' && data.fileName) return data.fileName
if (!url) return ''
const idx = url.lastIndexOf('/')
return idx !== -1 ? url.substring(idx + 1) : url
}
const uploadSuccess: UploadProps['onSuccess'] = (res: any, uploadFile): void => {
const url = getUrlFromRes(res)
if (!url) {
message.error('上传返回数据异常')
return
}
const name = getNameFromRes(res, url)
if (url && name) {
nameMap.value[url] = name
}
message.success('上传成功') message.success('上传成功')
// const index = fileList.value.findIndex((item) => item.uid === uploadFile.uid)
const index = fileList.value.findIndex((item) => item.response?.data === res.data) if (index > -1) {
fileList.value.splice(index, 1) fileList.value.splice(index, 1)
uploadList.value.push({ name: res.data, url: res.data }) }
if (uploadList.value.length == uploadNumber.value) { uploadList.value.push({ name, url })
if (uploadList.value.length === uploadNumber.value) {
fileList.value.push(...uploadList.value) fileList.value.push(...uploadList.value)
uploadList.value = [] uploadList.value = []
uploadNumber.value = 0 uploadNumber.value = 0
@ -132,6 +161,13 @@ const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => {
} }
} }
const getDisplayNameByUrl = (url: string): string => {
const cached = nameMap.value[url]
if (cached) return cached
const idx = url.lastIndexOf('/')
return idx !== -1 ? url.substring(idx + 1) : url
}
// //
watch( watch(
() => props.modelValue, () => props.modelValue,
@ -142,9 +178,8 @@ watch(
} }
fileList.value = [] // fileList.value = [] //
fileList.value.push( const list = Array.isArray(val) ? (val as string[]) : []
...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url })) fileList.value.push(...list.map((url) => ({ name: getDisplayNameByUrl(url), url })))
)
}, },
{ immediate: true, deep: true } { immediate: true, deep: true }
) )
@ -155,9 +190,15 @@ const emitUpdateModelValue = () => {
} }
// //
const handleRemove = (uploadFile: UploadFile) => { const handleRemove = (uploadFile: UploadFile) => {
fileList.value = fileList.value.filter( fileList.value = fileList.value.filter((item) => {
(item) => item.url !== uploadFile.url || item.name !== uploadFile.name if (item.url === uploadFile.url && item.name === uploadFile.name) {
) if (item.url && nameMap.value[item.url]) {
delete nameMap.value[item.url]
}
return false
}
return true
})
emit( emit(
'update:modelValue', 'update:modelValue',
fileList.value.map((file) => file.url!) fileList.value.map((file) => file.url!)

@ -19,11 +19,8 @@ export const useUpload = () => {
const httpRequest = async (options: UploadRequestOptions) => { const httpRequest = async (options: UploadRequestOptions) => {
// 模式一:前端上传 // 模式一:前端上传
if (isClientUpload) { if (isClientUpload) {
// 1.1 生成文件名称
const fileName = await generateFileName(options.file) const fileName = await generateFileName(options.file)
// 1.2 获取文件预签名地址
const presignedInfo = await FileApi.getFilePresignedUrl(fileName) const presignedInfo = await FileApi.getFilePresignedUrl(fileName)
// 1.3 上传文件(不能使用 ElUpload 的 ajaxUpload 方法的原因:其使用的是 FormData 上传Minio 不支持)
return axios return axios
.put(presignedInfo.uploadUrl, options.file, { .put(presignedInfo.uploadUrl, options.file, {
headers: { headers: {
@ -31,10 +28,16 @@ export const useUpload = () => {
} }
}) })
.then(() => { .then(() => {
// 1.4. 记录文件信息到后端(异步) const fileVo = createFile(presignedInfo, fileName, options.file)
createFile(presignedInfo, fileName, options.file) return {
// 通知成功,数据格式保持与后端上传的返回结果一致 code: 0,
return { data: presignedInfo.url } status: 0,
data: {
fileName: fileVo.path,
fileUrl: fileVo.url
},
msg: ''
}
}) })
} else { } else {
// 模式二:后端上传 // 模式二:后端上传

Loading…
Cancel
Save