bep40 commited on
Commit
f5b67c8
·
verified ·
1 Parent(s): 2b8722f

Khôi phục vai-img-ultimate.js về commit a75919ca

Browse files
Files changed (1) hide show
  1. vai-img-ultimate.js +216 -0
vai-img-ultimate.js ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * V.AI STUDIO — IMAGE EXCEL FIX: ULTIMATE
3
+ * Chạy SAU CÙNG (sau vai-export-fixed.js, sau 100percent, sau robust)
4
+ * Cách fix: Preload TẤT CẢ ảnh, SAU ĐÓ gọi genXl gốc
5
+ * Không patch _doExportExcel — patch genXl TRỰC TIẾP
6
+ */
7
+
8
+ (function() {
9
+ 'use strict';
10
+ console.log('[VAI IMG ULTIMATE] === LOADING ===');
11
+
12
+ // Cache ảnh đã fetch
13
+ var imgCache = {};
14
+
15
+ function fetchImageSafe(url) {
16
+ if (!url || !url.startsWith('http')) return Promise.resolve(null);
17
+ if (imgCache[url]) return Promise.resolve(imgCache[url]);
18
+
19
+ return fetch(url, { mode: 'cors', credentials: 'omit' })
20
+ .then(function(r) {
21
+ if (!r.ok) throw new Error('HTTP ' + r.status);
22
+ return r.arrayBuffer();
23
+ })
24
+ .then(function(buf) {
25
+ var ext = url.match(/\.png/i) ? 'png' : 'jpeg';
26
+ var result = { buffer: buf, ext: ext };
27
+ imgCache[url] = result;
28
+ return result;
29
+ })
30
+ .catch(function() {
31
+ // Fallback: dùng AllOrigins proxy
32
+ return fetch('https://api.allorigins.win/raw?url=' + encodeURIComponent(url))
33
+ .then(function(pr) {
34
+ if (!pr.ok) return null;
35
+ return pr.arrayBuffer().then(function(buf) {
36
+ var ext = url.match(/\.png/i) ? 'png' : 'jpeg';
37
+ var result = { buffer: buf, ext: ext };
38
+ imgCache[url] = result;
39
+ return result;
40
+ });
41
+ })
42
+ .catch(function() { return null; });
43
+ });
44
+ }
45
+
46
+ function waitForGenXl(cb, maxWait) {
47
+ maxWait = maxWait || 30000;
48
+ var waited = 0;
49
+ var t = setInterval(function() {
50
+ waited += 500;
51
+ // genXl là closure trong vai-export-fixed.js, không truy cập trực tiếp được
52
+ // Nhưng window.exportExcel chính là async function chứa await genXl(data,qd,code)
53
+ if (typeof window.exportExcel === 'function' && typeof ExcelJS !== 'undefined') {
54
+ clearInterval(t);
55
+ console.log('[VAI IMG ULTIMATE] exportExcel ready after ' + waited + 'ms');
56
+ cb();
57
+ }
58
+ if (waited >= maxWait) {
59
+ clearInterval(t);
60
+ console.warn('[VAI IMG ULTIMATE] timeout');
61
+ cb();
62
+ }
63
+ }, 500);
64
+ }
65
+
66
+ function fixExportExcel() {
67
+ if (window.__vaiImgUltimateDone) return;
68
+ window.__vaiImgUltimateDone = true;
69
+
70
+ var origExportExcel = window.exportExcel;
71
+
72
+ window.exportExcel = async function() {
73
+ console.log('[VAI IMG ULTIMATE] exportExcel called — preloading images...');
74
+
75
+ // Lấy dữ liệu
76
+ var data = null;
77
+ try {
78
+ if (window.VAI_QR && typeof window.VAI_QR.getData === 'function') {
79
+ data = window.VAI_QR.getData();
80
+ } else if (typeof window.getData === 'function') {
81
+ data = window.getData();
82
+ }
83
+ } catch(e) {}
84
+
85
+ if (!data || !data.qd || !data.qd.items) {
86
+ console.log('[VAI IMG ULTIMATE] No data from VAI_QR, trying getQuoteData');
87
+ try {
88
+ if (typeof window.getQuoteData === 'function') {
89
+ var qd = window.getQuoteData();
90
+ data = { qd: qd, fees: [], notes: [], deposit: 0, discountPercent: 0, itemDiscounts: {}, grandTotal: qd.grandTotal || 0, remaining: qd.grandTotal || 0, productTotal: qd.grandTotal || 0 };
91
+ // Tìm items từ qd
92
+ if (qd.items && qd.items.length) {
93
+ // OK
94
+ } else if (window.__quoteItems) {
95
+ qd.items = window.__quoteItems;
96
+ } else if (window.__cartItems) {
97
+ qd.items = window.__cartItems;
98
+ }
99
+ }
100
+ } catch(e) {}
101
+ }
102
+
103
+ if (!data || !data.qd || !data.qd.items || !data.qd.items.length) {
104
+ console.warn('[VAI IMG ULTIMATE] No items found');
105
+ // Vẫn gọi hàm gốc để hiển thị lỗi
106
+ if (origExportExcel) return origExportExcel.apply(this, arguments);
107
+ return;
108
+ }
109
+
110
+ // Lấy tất cả URL ảnh từ items
111
+ var items = data.qd.items || [];
112
+ var allProducts = window.D || [];
113
+ var imgUrls = items.map(function(it) {
114
+ var url = it.image || '';
115
+ if (!url && allProducts.length) {
116
+ var key = (it.model || it.sku || '').toLowerCase();
117
+ for (var i = 0; i < allProducts.length; i++) {
118
+ var p = allProducts[i];
119
+ var pKey = (p.mod || p.model || '').toLowerCase();
120
+ if (pKey && key.indexOf(pKey) >= 0) {
121
+ url = p.i || (p.imgs && p.imgs[0]) || '';
122
+ break;
123
+ }
124
+ if (key && pKey.indexOf(key) >= 0) {
125
+ url = p.i || (p.imgs && p.imgs[0]) || '';
126
+ break;
127
+ }
128
+ }
129
+ }
130
+ return url;
131
+ });
132
+
133
+ // Preload song song
134
+ var loadedImgs = await Promise.all(imgUrls.map(function(url) {
135
+ return url ? fetchImageSafe(url) : Promise.resolve(null);
136
+ }));
137
+ var loaded = loadedImgs.filter(Boolean).length;
138
+ console.log('[VAI IMG ULTIMATE] ✅ Loaded ' + loaded + '/' + imgUrls.length + ' images');
139
+
140
+ // Gán _imgBuffer vào item
141
+ items.forEach(function(it, i) {
142
+ if (loadedImgs[i]) {
143
+ it._imgBuffer = loadedImgs[i].buffer;
144
+ it._imgExt = loadedImgs[i].ext;
145
+ }
146
+ });
147
+
148
+ // Patch fetch để trả về cached
149
+ var origFetch = window.fetch;
150
+ window.fetch = function(url, opts) {
151
+ if (imgCache[url]) {
152
+ var cached = imgCache[url];
153
+ return Promise.resolve({
154
+ ok: true,
155
+ arrayBuffer: function() { return Promise.resolve(cached.buffer); },
156
+ json: function() { return Promise.resolve(null); },
157
+ text: function() { return Promise.resolve(''); },
158
+ blob: function() { return Promise.resolve(new Blob([cached.buffer])); },
159
+ status: 200,
160
+ statusText: 'OK'
161
+ });
162
+ }
163
+ return origFetch.call(window, url, opts);
164
+ };
165
+
166
+ try {
167
+ // Gọi hàm export gốc — các file khác đã patch _doExportExcel, exportExcel
168
+ if (typeof origExportExcel === 'function') {
169
+ return await origExportExcel.apply(this, arguments);
170
+ } else {
171
+ // Fallback: tìm _doExportExcel gốc
172
+ for (var k in window) {
173
+ if (k.indexOf('_doExport') === 0 && typeof window[k] === 'function') {
174
+ console.log('[VAI IMG ULTIMATE] Found: ' + k);
175
+ return await window[k](data, data.qd, 'BAOGIA', '');
176
+ }
177
+ }
178
+ }
179
+ } catch(e) {
180
+ console.error('[VAI IMG ULTIMATE] Export error:', e);
181
+ throw e;
182
+ } finally {
183
+ window.fetch = origFetch;
184
+ }
185
+ };
186
+
187
+ // Cũng patch _doExportExcel nếu có
188
+ if (typeof window._doExportExcel === 'function') {
189
+ var origDo = window._doExportExcel;
190
+ window._doExportExcel = async function(d, qd, code, qrUrl, bw) {
191
+ // Nếu đã có _imgBuffer thì ảnh đã được preload
192
+ if (qd && qd.items && qd.items[0] && qd.items[0]._imgBuffer) {
193
+ return origDo.call(this, d, qd, code, qrUrl, bw);
194
+ }
195
+ // Chưa preload — gọi exportExcel (đã patch ở trên)
196
+ if (window.exportExcel && window.exportExcel !== arguments.callee) {
197
+ return window.exportExcel(d, qd, code, qrUrl, bw);
198
+ }
199
+ return origDo.call(this, d, qd, code, qrUrl, bw);
200
+ };
201
+ }
202
+
203
+ // Patch lại VAI_QR.exportExcel
204
+ if (window.VAI_QR) {
205
+ window.VAI_QR.exportExcel = window.exportExcel;
206
+ }
207
+
208
+ console.log('[VAI IMG ULTIMATE] ✅ Fix active — 100% images will appear in Excel');
209
+ }
210
+
211
+ // Chờ cho tất cả các fix khác load xong
212
+ waitForGenXl(function() {
213
+ // Chờ thêm 2s để các interval 200ms của file khác chạy xong
214
+ setTimeout(fixExportExcel, 3000);
215
+ });
216
+ })();