From db4ce203b97baa03083ff55c4fb28ccfb97f480e Mon Sep 17 00:00:00 2001 From: "hangyu.tao" Date: Mon, 2 Feb 2026 11:39:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(upload):=20=E5=AE=9E=E7=8E=B0Canvas?= =?UTF-8?q?=E8=BD=AC=E6=8D=A2=E6=B3=95,=E5=BD=BB=E5=BA=95=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E8=BF=9C=E7=AB=AF=E6=9C=8D=E5=8A=A1=E5=99=A8=E5=9B=BE?= =?UTF-8?q?=E7=89=87=E4=B8=8A=E4=BC=A0=E9=99=90=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/index.html | 2 +- frontend/js/main.js | 85 ++++++++++++++++++++++----------------------- 2 files changed, 43 insertions(+), 44 deletions(-) diff --git a/frontend/index.html b/frontend/index.html index dda039f..e3129e0 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -1180,7 +1180,7 @@ - + diff --git a/frontend/js/main.js b/frontend/js/main.js index 463ac2e..104b5ff 100644 --- a/frontend/js/main.js +++ b/frontend/js/main.js @@ -61,7 +61,7 @@ function canDelete() { } document.addEventListener("DOMContentLoaded", function () { - console.log("CRM System Main JS v5.0 Loaded - " + new Date().toLocaleString()); + console.log("CRM System Main JS v5.1 Loaded - " + new Date().toLocaleString()); // 登录守卫 const token = localStorage.getItem("crmToken"); if (!token && !window.location.pathname.endsWith("login.html")) { @@ -3235,25 +3235,42 @@ document.addEventListener("DOMContentLoaded", function () { const newBase64Images = []; - // Helper to convert file to base64 with retry - const fileToBase64 = async (f, attempt = 1) => { - try { - return await new Promise((resolve, reject) => { - const reader = new FileReader(); - reader.onload = () => resolve(reader.result); - reader.onerror = () => reject(reader.error || new Error("FileReader error")); - reader.onabort = () => reject(new Error("File read aborted")); - reader.readAsDataURL(f); - }); - } catch (err) { - // If NotReadableError, retry up to 3 times - if (attempt < 3 && (err.name === "NotReadableError" || err.code === 1)) { - console.warn(`Retrying ${f.name} read due to error (attempt ${attempt})...`); - await new Promise(r => setTimeout(r, 200 * attempt)); - return fileToBase64(f, attempt + 1); - } - throw err; - } + // Canvas-based conversion - most compatible method for restricted environments + const fileToBase64Canvas = (file) => { + return new Promise((resolve, reject) => { + // Create object URL from file + const url = URL.createObjectURL(file); + const img = new Image(); + + img.onload = () => { + try { + // Create canvas and draw image + const canvas = document.createElement('canvas'); + canvas.width = img.width; + canvas.height = img.height; + + const ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + + // Convert to base64 + const base64 = canvas.toDataURL(file.type || 'image/png'); + + // Clean up + URL.revokeObjectURL(url); + resolve(base64); + } catch (error) { + URL.revokeObjectURL(url); + reject(error); + } + }; + + img.onerror = () => { + URL.revokeObjectURL(url); + reject(new Error('Failed to load image')); + }; + + img.src = url; + }); }; for (const file of files) { @@ -3263,31 +3280,13 @@ document.addEventListener("DOMContentLoaded", function () { } try { - console.log(`[v5.0] Converting ${file.name} (${file.size} bytes)...`); - const base64 = await fileToBase64(file); + console.log(`[v5.1-Canvas] Converting ${file.name} (${file.size} bytes)...`); + const base64 = await fileToBase64Canvas(file); newBase64Images.push(base64); - console.log(`Successfully converted ${file.name}`); + console.log(`✅ Successfully converted ${file.name} using Canvas method`); } catch (error) { - console.error(`Primary method failed for ${file.name}:`, error); - - // Fallback: arrayBuffer (usually works when FileReader fails) - try { - console.log(`Trying arrayBuffer fallback for ${file.name}...`); - const buffer = await file.arrayBuffer(); - const bytes = new Uint8Array(buffer); - let binary = ""; - const chunkSize = 8192; - for (let i = 0; i < bytes.length; i += chunkSize) { - const chunk = bytes.slice(i, i + chunkSize); - binary += String.fromCharCode.apply(null, chunk); - } - const b64 = `data:${file.type};base64,${btoa(binary)}`; - newBase64Images.push(b64); - console.log(`Fallback successful for ${file.name}`); - } catch (fallbackError) { - console.error(`Both methods failed for ${file.name}:`, fallbackError); - alert(`无法读取文件 "${file.name}"。\n这种情况通常是浏览器或系统文件锁定导致的。\n\n建议尝试:\n1. 刷新页面后再试\n2. 使用浏览器的“无痕模式”\n3. 确认文件没有被其他软件打开`); - } + console.error(`❌ Canvas method failed for ${file.name}:`, error); + alert(`无法处理文件 "${file.name}"。\n\n可能的原因:\n1. 图片格式不受支持\n2. 图片文件损坏\n3. 浏览器内存不足\n\n建议:\n• 尝试使用较小的图片\n• 转换为标准格式(JPG/PNG)\n• 刷新页面后重试`); } }