Pre Merge pull request !663 from shixiaohe/master

pull/663/MERGE
shixiaohe 2025-05-05 15:03:41 +00:00 committed by Gitee
commit c55b01cebb
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 179 additions and 14 deletions

View File

@ -79,7 +79,11 @@ const props = defineProps({
width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px)
borderradius: propTypes.string.def('8px'), // 组件边框圆角 ==> 非必传(默认为 8px)
showDelete: propTypes.bool.def(true), // 是否显示删除按钮
showBtnText: propTypes.bool.def(true) // 是否显示按钮文字
showBtnText: propTypes.bool.def(true), // 是否显示按钮文字
// 新增压缩相关属性
enableCompress: propTypes.bool.def(false), // 是否启用压缩
compressSize: propTypes.number.def(300), // 压缩后的大小限制,单位KB
compressQuality: propTypes.number.def(0.8) // 压缩质量,0-1之间
})
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
@ -105,14 +109,88 @@ const editImg = () => {
const dom = document.querySelector(`#${uuid.value} .el-upload__input`)
dom && dom.dispatchEvent(new MouseEvent('click'))
}
// 压缩图片方法
const compressImage = (file: File): Promise<Blob> => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (e) => {
const img = new Image()
img.src = e.target?.result as string
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) {
reject(new Error('Failed to get canvas context'))
return
}
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
const imgSize = rawFile.size / 1024 / 1024 < props.fileSize
const imgType = props.fileType
if (!imgType.includes(rawFile.type as FileTypes))
// 计算压缩后的尺寸
let width = img.width
let height = img.height
const maxSize = Math.max(width, height)
if (maxSize > 1920) {
const ratio = 1920 / maxSize
width *= ratio
height *= ratio
}
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
// 转换为Blob
canvas.toBlob(
(blob) => {
if (blob) {
resolve(blob)
} else {
reject(new Error('Failed to compress image'))
}
},
file.type,
props.compressQuality
)
}
img.onerror = () => reject(new Error('Failed to load image'))
}
reader.onerror = () => reject(new Error('Failed to read file'))
})
}
// 修改上传前的处理方法
const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => {
// 检查文件类型
if (!props.fileType.includes(rawFile.type as FileTypes)) {
message.notifyWarning('上传图片不符合所需的格式!')
if (!imgSize) message.notifyWarning(`上传图片大小不能超过 ${props.fileSize}M!`)
return imgType.includes(rawFile.type as FileTypes) && imgSize
return false
}
// 检查原始文件大小
const originalSize = rawFile.size / 1024 / 1024
if (originalSize > props.fileSize) {
message.notifyWarning(`上传图片大小不能超过 ${props.fileSize}M!`)
return false
}
// 如果启用压缩且文件大小超过压缩限制
if (props.enableCompress && rawFile.size > props.compressSize * 1024) {
try {
const compressedBlob = await compressImage(rawFile)
// 如果压缩后仍然超过限制
if (compressedBlob.size > props.compressSize * 1024) {
message.notifyWarning(`压缩后图片${compressedBlob.size/1024}KB仍然超过 ${props.compressSize}KB,请选择更小的图片!`)
return false
}
// 创建新的文件对象
const newFile = new File([compressedBlob], rawFile.name, { type: rawFile.type })
return newFile
} catch (error) {
message.notifyError('图片压缩失败,请重试!')
return false
}
}
return true
}
// 图片上传成功提示

View File

@ -81,7 +81,11 @@ const props = defineProps({
fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif']), // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"])
height: propTypes.string.def('150px'), // 组件高度 ==> 非必传(默认为 150px)
width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px)
borderradius: propTypes.string.def('8px') // 组件边框圆角 ==> 非必传(默认为 8px)
borderradius: propTypes.string.def('8px'), // 组件边框圆角 ==> 非必传(默认为 8px)
// 新增压缩相关属性
enableCompress: propTypes.bool.def(false), // 是否启用压缩
compressSize: propTypes.number.def(300), // 压缩后的大小限制,单位KB
compressQuality: propTypes.number.def(0.8) // 压缩质量,0-1之间
})
const { uploadUrl, httpRequest } = useUpload()
@ -89,27 +93,110 @@ const { uploadUrl, httpRequest } = useUpload()
const fileList = ref<UploadUserFile[]>([])
const uploadNumber = ref<number>(0)
const uploadList = ref<UploadUserFile[]>([])
// 压缩图片方法
const compressImage = (file: File): Promise<Blob> => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = (e) => {
const img = new Image()
img.src = e.target?.result as string
img.onload = () => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
if (!ctx) {
reject(new Error('Failed to get canvas context'))
return
}
// 计算压缩后的尺寸
let width = img.width
let height = img.height
const maxSize = Math.max(width, height)
if (maxSize > 1920) {
const ratio = 1920 / maxSize
width *= ratio
height *= ratio
}
canvas.width = width
canvas.height = height
ctx.drawImage(img, 0, 0, width, height)
// 转换为Blob
canvas.toBlob(
(blob) => {
if (blob) {
resolve(blob)
} else {
reject(new Error('Failed to compress image'))
}
},
file.type,
props.compressQuality
)
}
img.onerror = () => reject(new Error('Failed to load image'))
}
reader.onerror = () => reject(new Error('Failed to read file'))
})
}
/**
* @description 文件上传之前判断
* @param rawFile 上传的文件
* */
const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => {
const imgSize = rawFile.size / 1024 / 1024 < props.fileSize
const imgType = props.fileType
if (!imgType.includes(rawFile.type as FileTypes))
// 修改文件上传前的处理方法
const beforeUpload: UploadProps['beforeUpload'] = async (rawFile) => {
// 检查文件类型
if (!props.fileType.includes(rawFile.type as FileTypes)) {
ElNotification({
title: '温馨提示',
message: '上传图片不符合所需的格式!',
type: 'warning'
})
if (!imgSize)
return false
}
// 检查原始文件大小
const originalSize = rawFile.size / 1024 / 1024
if (originalSize > props.fileSize) {
ElNotification({
title: '温馨提示',
message: `上传图片大小不能超过 ${props.fileSize}M!`,
type: 'warning'
})
return false
}
// 如果启用压缩且文件大小超过压缩限制
if (props.enableCompress && rawFile.size > props.compressSize * 1024) {
try {
const compressedBlob = await compressImage(rawFile)
// 如果压缩后仍然超过限制
if (compressedBlob.size > props.compressSize * 1024) {
ElNotification({
title: '温馨提示',
message: `压缩后图片仍然超过 ${props.compressSize}KB,请选择更小的图片!`,
type: 'warning'
})
return false
}
// 创建新的文件对象
const newFile = new File([compressedBlob], rawFile.name, { type: rawFile.type })
uploadNumber.value++
return imgType.includes(rawFile.type as FileTypes) && imgSize
return newFile
} catch (error) {
ElNotification({
title: '温馨提示',
message: '图片压缩失败,请重试!',
type: 'error'
})
return false
}
}
uploadNumber.value++
return true
}
// 图片上传成功