Spaces:
Running
Running
FIX triệt để: Giữ tất cả blob URLs alive đến khi rời trang (pagehide cleanup). Xóa setTimeout revoke. Thêm blobRegistry global.
Browse files- qr-payment.js +21 -14
qr-payment.js
CHANGED
|
@@ -1,16 +1,15 @@
|
|
| 1 |
-
/* V.AI STUDIO — QR Payment / Quote Data v1037.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
* FIX v1037.3: Thêm CORS proxy fallback wsrv.nl cho ảnh trong Excel
|
| 3 |
-
* - fetch trực tiếp fail (CORS) → fallback qua wsrv.nl
|
| 4 |
-
* - Tested: Eurogold, Hafele images đều load được với ACL=*
|
| 5 |
* FIX v1037.2:
|
| 6 |
* 1) parsePrompt() extract brand discount (malloca ck35% → itemDiscounts)
|
| 7 |
* 2) matchItemDiscount() brand matching fallback (Malloca→35%)
|
| 8 |
* 3) _doExportExcel: Giá CK luôn là formula =G*0.65 / =G*1, ko hằng số
|
| 9 |
* FIX v1037.1: Loại bỏ dòng CK/giá trị số (35đ, 50đ, Malloca Ck%) khỏi fees/phụ phí
|
| 10 |
-
* FIX: getData() và injectToModal() gọi closure parsePrompt() trực tiếp,
|
| 11 |
-
* không qua VAI_QR.parsePrompt, nên comprehensive-fix.js không áp dụng được.
|
| 12 |
-
* Thêm guards trong parsePrompt() để skip bare numbers, brand+discount, CK lines.
|
| 13 |
-
* Restored from 9db23f9 (v24) — full Excel/PDF export with proper layout
|
| 14 |
*/
|
| 15 |
(function(){
|
| 16 |
'use strict';
|
|
@@ -193,7 +192,7 @@ function doOverride(){
|
|
| 193 |
window.exportDeliveryExcel=async function(){if(typeof ExcelJS==='undefined')return;var qd=window._origGetQuoteData(),code=getEffectiveOrderCode();await _doExportDeliveryExcel(qd,code);};
|
| 194 |
window.exportDeliveryPDF=async function(){var qd=window._origGetQuoteData(),code=getEffectiveOrderCode();await _doExportDeliveryPDF(qd,code);};
|
| 195 |
window.getQuoteData=function(){var qd=window._origGetQuoteData.apply(this,arguments);if(qd.customer)qd.customer.orderCode=getEffectiveOrderCode();return qd;};
|
| 196 |
-
console.log('✅ QR Payment v1037.
|
| 197 |
}
|
| 198 |
|
| 199 |
async function _doExportPDF(d,code){
|
|
@@ -212,7 +211,11 @@ async function _doExportPDF(d,code){
|
|
| 212 |
async function _doExportDeliveryPDF(qd,code){var cv=await toCanvas(buildDeliveryHTML(qd,code),700);var img=cv.toDataURL('image/png');var pdf=new jspdf.jsPDF({orientation:'p',unit:'pt',format:'a4'});var margin=25,usableW=595-margin*2;var ratio=cv.height/cv.width;var imgH=usableW*ratio;if(imgH>842-margin*2){imgH=842-margin*2;usableW=imgH/ratio;}pdf.addImage(img,'PNG',margin,margin,usableW,imgH);pdf.save('GH-'+code+'.pdf');}
|
| 213 |
|
| 214 |
// FIX v1037.2: _doExportExcel - Giá CK luôn là formula, ko hằng số
|
| 215 |
-
// FIX v1037.3: Thêm CORS proxy fallback wsrv.nl cho ảnh
|
|
|
|
|
|
|
|
|
|
|
|
|
| 216 |
async function _doExportExcel(d,qd,code,qr){
|
| 217 |
var MONEY_FMT='#,##0"đ"';
|
| 218 |
var NUM_FMT='#,##0';
|
|
@@ -247,7 +250,6 @@ async function _doExportExcel(d,qd,code,qr){
|
|
| 247 |
var bgColor=i%2===0?'FFF8FAFC':'FFFFFFFF';
|
| 248 |
var RB={top:{style:'thin',color:{argb:bgColor}},bottom:{style:'thin',color:{argb:bgColor}},left:{style:'thin',color:{argb:bgColor}},right:{style:'thin',color:{argb:bgColor}}};
|
| 249 |
row.getCell(1).value=it.stt||i+1;row.getCell(1).alignment={horizontal:'center',vertical:'middle'};
|
| 250 |
-
// FIX v1037.3: Load ảnh với CORS proxy fallback wsrv.nl
|
| 251 |
if(it.image&&it.image.startsWith('http')){
|
| 252 |
try{
|
| 253 |
var ir=await fetch(it.image,{mode:'cors'});
|
|
@@ -256,7 +258,6 @@ async function _doExportExcel(d,qd,code,qr){
|
|
| 256 |
var ext=it.image.match(/\.(png|jpe?g)/i);ext=ext?ext[1].startsWith('png')?'png':'jpeg':'jpeg';
|
| 257 |
ws.addImage(wb.addImage({buffer:ib,extension:ext}),{tl:{col:1,row:cr-1},ext:{width:46,height:46}});
|
| 258 |
}catch(e1){
|
| 259 |
-
// Fallback: dùng wsrv.nl (CORS proxy, tested: ✅ Eurogold, Hafele)
|
| 260 |
try{
|
| 261 |
var proxyUrl='https://wsrv.nl/?url='+encodeURIComponent(it.image)+'&w=200&output='+(it.image.match(/\.png/i)?'png':'jpg');
|
| 262 |
var ir2=await fetch(proxyUrl);
|
|
@@ -265,7 +266,7 @@ async function _doExportExcel(d,qd,code,qr){
|
|
| 265 |
var ext2=it.image.match(/\.(png|jpe?g)/i);ext2=ext2?ext2[1].startsWith('png')?'png':'jpeg':'jpeg';
|
| 266 |
ws.addImage(wb.addImage({buffer:ib2,extension:ext2}),{tl:{col:1,row:cr-1},ext:{width:46,height:46}});
|
| 267 |
}
|
| 268 |
-
}catch(e2){
|
| 269 |
}
|
| 270 |
}
|
| 271 |
row.getCell(3).value=it.name||'';row.getCell(3).font={bold:true,size:9};row.getCell(3).alignment={wrapText:true,vertical:'middle'};
|
|
@@ -308,7 +309,10 @@ async function _doExportExcel(d,qd,code,qr){
|
|
| 308 |
try{var qrR=await fetch(qr,{mode:'cors'});if(qrR.ok){var qb=await qrR.arrayBuffer();ws.addImage(wb.addImage({buffer:qb,extension:'png'}),{tl:{col:6,row:cr-5},ext:{width:115,height:115}});}}catch(e){}
|
| 309 |
ws.eachRow(function(row){row.eachCell(function(cell){if(!cell.border)cell.border=WB;});});
|
| 310 |
wb.calcProperties.fullCalcOnLoad = true;
|
| 311 |
-
var buf=await wb.xlsx.writeBuffer();var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});var url=URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
|
|
| 312 |
}
|
| 313 |
|
| 314 |
async function _doExportDeliveryExcel(qd,code){
|
|
@@ -330,7 +334,10 @@ async function _doExportDeliveryExcel(qd,code){
|
|
| 330 |
cr+=2;ws.getCell('A'+cr).value='Bên giao: ________________';ws.getCell('A'+cr).border=WB;ws.getCell('D'+cr).value='Bên nhận: ________________';ws.getCell('D'+cr).border=WB;
|
| 331 |
cr++;ws.getCell('A'+cr).value='(Ký, họ tên)';ws.getCell('A'+cr).font={italic:true,size:8,color:{argb:'FF64748B'}};ws.getCell('A'+cr).border=WB;ws.getCell('D'+cr).value='(Ký, họ tên)';ws.getCell('D'+cr).font={italic:true,size:8,color:{argb:'FF64748B'}};ws.getCell('D'+cr).border=WB;
|
| 332 |
ws.eachRow(function(row){row.eachCell(function(cell){if(!cell.border)cell.border=WB;});});
|
| 333 |
-
var buf=await wb.xlsx.writeBuffer();var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});var url=URL.createObjectURL(blob);
|
|
|
|
|
|
|
|
|
|
| 334 |
}
|
| 335 |
|
| 336 |
var att=0;var t=setInterval(function(){if(doOverride()||att>120)clearInterval(t);att++;},500);
|
|
|
|
| 1 |
+
/* V.AI STUDIO — QR Payment / Quote Data v1037.4
|
| 2 |
+
* FIX v1037.4: Giữ tất cả blob URLs alive đến khi rời trang
|
| 3 |
+
* - Xóa setTimeout(revokeObjectURL, 60000) — không revoke sớm
|
| 4 |
+
* - Thêm blobRegistry[] global (window.__vaiBlobUrls)
|
| 5 |
+
* - Cleanup chỉ khi pagehide (rời tab/đóng trang)
|
| 6 |
+
* - User có thể download Excel/PDF bao nhiêu lần cũng được
|
| 7 |
* FIX v1037.3: Thêm CORS proxy fallback wsrv.nl cho ảnh trong Excel
|
|
|
|
|
|
|
| 8 |
* FIX v1037.2:
|
| 9 |
* 1) parsePrompt() extract brand discount (malloca ck35% → itemDiscounts)
|
| 10 |
* 2) matchItemDiscount() brand matching fallback (Malloca→35%)
|
| 11 |
* 3) _doExportExcel: Giá CK luôn là formula =G*0.65 / =G*1, ko hằng số
|
| 12 |
* FIX v1037.1: Loại bỏ dòng CK/giá trị số (35đ, 50đ, Malloca Ck%) khỏi fees/phụ phí
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
*/
|
| 14 |
(function(){
|
| 15 |
'use strict';
|
|
|
|
| 192 |
window.exportDeliveryExcel=async function(){if(typeof ExcelJS==='undefined')return;var qd=window._origGetQuoteData(),code=getEffectiveOrderCode();await _doExportDeliveryExcel(qd,code);};
|
| 193 |
window.exportDeliveryPDF=async function(){var qd=window._origGetQuoteData(),code=getEffectiveOrderCode();await _doExportDeliveryPDF(qd,code);};
|
| 194 |
window.getQuoteData=function(){var qd=window._origGetQuoteData.apply(this,arguments);if(qd.customer)qd.customer.orderCode=getEffectiveOrderCode();return qd;};
|
| 195 |
+
console.log('✅ QR Payment v1037.4 — blob URLs kept alive, unlimited downloads');return true;
|
| 196 |
}
|
| 197 |
|
| 198 |
async function _doExportPDF(d,code){
|
|
|
|
| 211 |
async function _doExportDeliveryPDF(qd,code){var cv=await toCanvas(buildDeliveryHTML(qd,code),700);var img=cv.toDataURL('image/png');var pdf=new jspdf.jsPDF({orientation:'p',unit:'pt',format:'a4'});var margin=25,usableW=595-margin*2;var ratio=cv.height/cv.width;var imgH=usableW*ratio;if(imgH>842-margin*2){imgH=842-margin*2;usableW=imgH/ratio;}pdf.addImage(img,'PNG',margin,margin,usableW,imgH);pdf.save('GH-'+code+'.pdf');}
|
| 212 |
|
| 213 |
// FIX v1037.2: _doExportExcel - Giá CK luôn là formula, ko hằng số
|
| 214 |
+
// FIX v1037.3: Thêm CORS proxy fallback wsrv.nl cho ảnh
|
| 215 |
+
// FIX v1037.4: Blob registry — ko revoke, cleanup chỉ khi pagehide
|
| 216 |
+
// Tạo global registry nếu chưa có
|
| 217 |
+
if(!window.__vaiBlobUrls){window.__vaiBlobUrls=[];if(typeof window.addEventListener==='function'){window.addEventListener('pagehide',function(){window.__vaiBlobUrls.forEach(function(u){try{URL.revokeObjectURL(u);}catch(e){}});window.__vaiBlobUrls=[];});}}
|
| 218 |
+
|
| 219 |
async function _doExportExcel(d,qd,code,qr){
|
| 220 |
var MONEY_FMT='#,##0"đ"';
|
| 221 |
var NUM_FMT='#,##0';
|
|
|
|
| 250 |
var bgColor=i%2===0?'FFF8FAFC':'FFFFFFFF';
|
| 251 |
var RB={top:{style:'thin',color:{argb:bgColor}},bottom:{style:'thin',color:{argb:bgColor}},left:{style:'thin',color:{argb:bgColor}},right:{style:'thin',color:{argb:bgColor}}};
|
| 252 |
row.getCell(1).value=it.stt||i+1;row.getCell(1).alignment={horizontal:'center',vertical:'middle'};
|
|
|
|
| 253 |
if(it.image&&it.image.startsWith('http')){
|
| 254 |
try{
|
| 255 |
var ir=await fetch(it.image,{mode:'cors'});
|
|
|
|
| 258 |
var ext=it.image.match(/\.(png|jpe?g)/i);ext=ext?ext[1].startsWith('png')?'png':'jpeg':'jpeg';
|
| 259 |
ws.addImage(wb.addImage({buffer:ib,extension:ext}),{tl:{col:1,row:cr-1},ext:{width:46,height:46}});
|
| 260 |
}catch(e1){
|
|
|
|
| 261 |
try{
|
| 262 |
var proxyUrl='https://wsrv.nl/?url='+encodeURIComponent(it.image)+'&w=200&output='+(it.image.match(/\.png/i)?'png':'jpg');
|
| 263 |
var ir2=await fetch(proxyUrl);
|
|
|
|
| 266 |
var ext2=it.image.match(/\.(png|jpe?g)/i);ext2=ext2?ext2[1].startsWith('png')?'png':'jpeg':'jpeg';
|
| 267 |
ws.addImage(wb.addImage({buffer:ib2,extension:ext2}),{tl:{col:1,row:cr-1},ext:{width:46,height:46}});
|
| 268 |
}
|
| 269 |
+
}catch(e2){}
|
| 270 |
}
|
| 271 |
}
|
| 272 |
row.getCell(3).value=it.name||'';row.getCell(3).font={bold:true,size:9};row.getCell(3).alignment={wrapText:true,vertical:'middle'};
|
|
|
|
| 309 |
try{var qrR=await fetch(qr,{mode:'cors'});if(qrR.ok){var qb=await qrR.arrayBuffer();ws.addImage(wb.addImage({buffer:qb,extension:'png'}),{tl:{col:6,row:cr-5},ext:{width:115,height:115}});}}catch(e){}
|
| 310 |
ws.eachRow(function(row){row.eachCell(function(cell){if(!cell.border)cell.border=WB;});});
|
| 311 |
wb.calcProperties.fullCalcOnLoad = true;
|
| 312 |
+
var buf=await wb.xlsx.writeBuffer();var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});var url=URL.createObjectURL(blob);
|
| 313 |
+
// FIX v1037.4: Giữ blob URL trong registry — chỉ revoke khi pagehide
|
| 314 |
+
window.__vaiBlobUrls.push(url);
|
| 315 |
+
var a=document.createElement('a');a.href=url;a.download=code+'.xlsx';a.click();
|
| 316 |
}
|
| 317 |
|
| 318 |
async function _doExportDeliveryExcel(qd,code){
|
|
|
|
| 334 |
cr+=2;ws.getCell('A'+cr).value='Bên giao: ________________';ws.getCell('A'+cr).border=WB;ws.getCell('D'+cr).value='Bên nhận: ________________';ws.getCell('D'+cr).border=WB;
|
| 335 |
cr++;ws.getCell('A'+cr).value='(Ký, họ tên)';ws.getCell('A'+cr).font={italic:true,size:8,color:{argb:'FF64748B'}};ws.getCell('A'+cr).border=WB;ws.getCell('D'+cr).value='(Ký, họ tên)';ws.getCell('D'+cr).font={italic:true,size:8,color:{argb:'FF64748B'}};ws.getCell('D'+cr).border=WB;
|
| 336 |
ws.eachRow(function(row){row.eachCell(function(cell){if(!cell.border)cell.border=WB;});});
|
| 337 |
+
var buf=await wb.xlsx.writeBuffer();var blob=new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});var url=URL.createObjectURL(blob);
|
| 338 |
+
// FIX v1037.4: Giữ blob URL trong registry
|
| 339 |
+
window.__vaiBlobUrls.push(url);
|
| 340 |
+
var a=document.createElement('a');a.href=url;a.download='GH-'+code+'.xlsx';a.click();
|
| 341 |
}
|
| 342 |
|
| 343 |
var att=0;var t=setInterval(function(){if(doOverride()||att>120)clearInterval(t);att++;},500);
|