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• 刷新页面后重试`); } }