diff --git a/src/views/ValueForum/components/CreatePostModal.js b/src/views/ValueForum/components/CreatePostModal.js index 34c78447..41ee02af 100644 --- a/src/views/ValueForum/components/CreatePostModal.js +++ b/src/views/ValueForum/components/CreatePostModal.js @@ -73,69 +73,90 @@ const CreatePostModal = ({ isOpen, onClose, onPostCreated }) => { // 压缩图片 const compressImage = (file) => { return new Promise((resolve, reject) => { + // 检查文件类型 + if (!file.type.startsWith('image/')) { + reject(new Error('请选择图片文件')); + return; + } + // 检查文件大小(5MB 限制) if (file.size > 5 * 1024 * 1024) { - toast({ - title: '图片过大', - description: '单张图片不能超过 5MB', - status: 'warning', - duration: 3000, - }); - reject(new Error('图片过大')); + reject(new Error('图片大小不能超过 5MB')); return; } const reader = new FileReader(); + reader.onload = (e) => { const img = new Image(); + img.onload = () => { - // 创建 canvas 进行压缩 - const canvas = document.createElement('canvas'); - let width = img.width; - let height = img.height; + try { + // 创建 canvas 进行压缩 + const canvas = document.createElement('canvas'); + let width = img.width; + let height = img.height; - // 如果图片尺寸过大,等比缩放到最大 1920px - const maxDimension = 1920; - if (width > maxDimension || height > maxDimension) { - if (width > height) { - height = (height * maxDimension) / width; - width = maxDimension; - } else { - width = (width * maxDimension) / height; - height = maxDimension; + // 如果图片尺寸过大,等比缩放到最大 1920px + const maxDimension = 1920; + if (width > maxDimension || height > maxDimension) { + if (width > height) { + height = (height * maxDimension) / width; + width = maxDimension; + } else { + width = (width * maxDimension) / height; + height = maxDimension; + } } + + canvas.width = width; + canvas.height = height; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0, width, height); + + // 转换为 JPEG 格式,质量 0.8(压缩) + canvas.toBlob( + (blob) => { + if (!blob) { + reject(new Error('图片压缩失败')); + return; + } + + const compressedReader = new FileReader(); + + compressedReader.onloadend = () => { + console.log( + `图片压缩: ${(file.size / 1024).toFixed(2)}KB -> ${(blob.size / 1024).toFixed(2)}KB` + ); + resolve(compressedReader.result); + }; + + compressedReader.onerror = () => { + reject(new Error('压缩后图片读取失败')); + }; + + compressedReader.readAsDataURL(blob); + }, + 'image/jpeg', + 0.8 + ); + } catch (error) { + reject(new Error(`图片处理失败: ${error.message}`)); } - - canvas.width = width; - canvas.height = height; - - const ctx = canvas.getContext('2d'); - ctx.drawImage(img, 0, 0, width, height); - - // 转换为 JPEG 格式,质量 0.8(压缩) - canvas.toBlob( - (blob) => { - const compressedReader = new FileReader(); - compressedReader.onloadend = () => { - console.log( - `图片压缩: ${(file.size / 1024).toFixed(2)}KB -> ${(blob.size / 1024).toFixed(2)}KB` - ); - resolve(compressedReader.result); - }; - compressedReader.readAsDataURL(blob); - }, - 'image/jpeg', - 0.8 - ); }; + img.onerror = () => { reject(new Error('图片加载失败')); }; + img.src = e.target.result; }; + reader.onerror = () => { reject(new Error('文件读取失败')); }; + reader.readAsDataURL(file); }); }; @@ -144,6 +165,9 @@ const CreatePostModal = ({ isOpen, onClose, onPostCreated }) => { const handleImageUpload = async (e) => { const files = Array.from(e.target.files); + // 清空 input 以支持重复上传同一文件 + e.target.value = ''; + if (files.length === 0) return; // 检查总数量限制 @@ -157,27 +181,42 @@ const CreatePostModal = ({ isOpen, onClose, onPostCreated }) => { return; } - try { - // 压缩所有图片 - const compressedImages = await Promise.all( - files.map((file) => compressImage(file)) - ); + // 逐个处理图片,而不是使用 Promise.all + const compressedImages = []; + let hasError = false; - // 添加到表单数据 + for (let i = 0; i < files.length; i++) { + try { + const compressed = await compressImage(files[i]); + compressedImages.push(compressed); + } catch (error) { + console.error('图片压缩失败:', error); + hasError = true; + toast({ + title: '图片处理失败', + description: error.message || `第 ${i + 1} 张图片处理失败`, + status: 'error', + duration: 3000, + }); + break; // 遇到错误就停止 + } + } + + // 如果有成功压缩的图片,添加到表单 + if (compressedImages.length > 0) { setFormData((prev) => ({ ...prev, images: [...prev.images, ...compressedImages], })); - toast({ - title: '上传成功', - description: `成功添加 ${files.length} 张图片`, - status: 'success', - duration: 2000, - }); - } catch (error) { - console.error('图片上传失败:', error); - // 已经在 compressImage 中显示了具体错误 + if (!hasError) { + toast({ + title: '上传成功', + description: `成功添加 ${compressedImages.length} 张图片`, + status: 'success', + duration: 2000, + }); + } } };