/** * V.AI STUDIO — Excel Export Complete Fix v3.0 * ========================================== * FIX TRIỆT ĐỐI: File Excel tải được nhiều lần */ (function() { 'use strict'; // Registry blob URLs toàn cục window.__VAI_BLOB_REGISTRY = window.__VAI_BLOB_REGISTRY || []; var isUnloading = false; // Cleanup khi unload function cleanupAllBlobs() { isUnloading = true; window.__VAI_BLOB_REGISTRY.forEach(function(e) { if (!e.revoked && e.url) { try { URL.revokeObjectURL(e.url); e.revoked = true; } catch(err) {} } }); } window.addEventListener('pagehide', cleanupAllBlobs); window.addEventListener('beforeunload', cleanupAllBlobs); window.addEventListener('unload', cleanupAllBlobs); // PATCH URL.revokeObjectURL - quan trọng nhất! var origRevoke = URL.revokeObjectURL; URL.revokeObjectURL = function(url) { // Chỉ revoke khi unload hoặc không phải blob if (isUnloading || !url || typeof url !== 'string' || !url.startsWith('blob:')) { return origRevoke.apply(this, arguments); } // Đăng ký - KHÔNG revoke! var found = window.__VAI_BLOB_REGISTRY.find(function(e) { return e.url === url; }); if (!found) { window.__VAI_BLOB_REGISTRY.push({ url: url, revoked: false, created: Date.now() }); } }; // Chờ DOM + ExcelJS async function init() { let waited = 0; while (typeof ExcelJS === 'undefined' && waited < 15000) { await new Promise(r => setTimeout(r, 500)); waited += 500; } // Ghi đè exportDeliveryExcel if (window.exportDeliveryExcel) { var origCode = window.exportDeliveryExcel.toString(); if (!origCode.includes('.xlsx') || origCode.includes('text/csv') || origCode.includes('revokeObjectURL')) { window.exportDeliveryExcel = async function() { if (!window.cart || window.cart.length === 0) { if (typeof showToast === 'function') showToast('⚠️ Giỏ hàng trống!'); return; } try { if (typeof ExcelJS === 'undefined') { if (typeof showToast === 'function') showToast('⚠️ Chưa có thư viện Excel. Vui lòng đợi 2-3s.'); return; } var wb = new ExcelJS.Workbook(); var ws = wb.addWorksheet('Phiếu Giao Hàng'); ws.mergeCells('A1:E1'); ws.getCell('A1').value = 'PHIẾU GIAO HÀNG V.AI STUDIO'; ws.getCell('A1').font = { bold: true, size: 14, color: { argb: 'FF003F62' } }; ws.getCell('A1').alignment = { horizontal: 'center' }; var today = new Date().toLocaleDateString('vi-VN'); ws.getCell('A2').value = 'Ngày:'; ws.getCell('B2').value = today; var hr = ws.getRow(4); ['STT', 'Mã SP', 'Tên sản phẩm', 'SL', 'Thành tiền'].forEach(function(h, i) { var c = hr.getCell(i + 1); c.value = h; c.font = { bold: true, color: { argb: 'FFFFFFFF' } }; c.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: 'FF003F62' } }; }); var total = 0; window.cart.forEach(function(item, idx) { var p = (window.D && window.D[item.idx]) ? window.D[item.idx] : null; var name = p ? (p.name || p.n || '') : (item.name || ''); var model = p ? (p.sku || p.mod || '') : (item.sku || item.model || ''); var qty = item.qty || 1; var price = item.priceNum || item.price || 0; var lineTotal = qty * price; total += lineTotal; var row = ws.getRow(idx + 5); row.values = [idx + 1, model, name.replace(/,/g, ' -'), qty, lineTotal]; if (lineTotal > 0) row.getCell(5).numFmt = '#,##0"đ"'; }); var tr = ws.getRow(window.cart.length + 6); ws.mergeCells(window.cart.length + 6, 1, window.cart.length + 6, 4); ws.getCell('A' + (window.cart.length + 6)).value = 'TỔNG CỘNG:'; ws.getCell('E' + (window.cart.length + 6)).value = total; ws.getCell('E' + (window.cart.length + 6)).font = { bold: true }; ws.getCell('E' + (window.cart.length + 6)).numFmt = '#,##0"đ"'; var buf = await wb.xlsx.writeBuffer(); var blob = new Blob([buf], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); var url = URL.createObjectURL(blob); // ✅ ĐĂNG KÝ blob - KHÔNG revoke! window.__VAI_BLOB_REGISTRY.push({ url: url, revoked: false }); var a = document.createElement('a'); a.href = url; a.download = 'GH_VAI_STUDIO_' + Date.now() + '.xlsx'; document.body.appendChild(a); a.click(); setTimeout(function() { try { document.body.removeChild(a); } catch(e) {} }, 100); if (typeof showToast === 'function') { showToast('✅ Đã tải Excel thành công! Tải lại được.'); } } catch (e) { console.error('exportDeliveryExcel error:', e); if (typeof showToast === 'function') showToast('❌ Lỗi: ' + e.message); } }; } } } // Chạy ngay if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } console.log('[VAI Excel Complete Fix v3.0] Loaded - Multi-download enabled'); })();