| <!DOCTYPE html> |
| <html lang="vi"> |
| <head><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":"HF_TOKEN_REDACTED","REBUILD_TRIGGER":"NOW"}};</script> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width,initial-scale=1"> |
| <title>V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi</title> |
| <meta name="description" content="V.AI STUDIO — 8000+ sản phẩm thiết bị nhà bếp & điện máy. Malloca, Eurogold, Grob, Canzy, Demax & Điện Máy Xanh chính hãng."> |
| <meta property="og:type" content="website"> |
| <meta property="og:site_name" content="V.AI STUDIO"> |
| <meta property="og:title" id="ogTitle" content="V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi"> |
| <meta property="og:description" id="ogDesc" content="8000+ sản phẩm thiết bị nhà bếp & điện máy chính hãng. Malloca, Eurogold, Grob, Canzy, Demax & Điện Máy Xanh."> |
| <meta property="og:image" id="ogImage" content="https://huggingface.co/spaces/bep40/V.AISTUDIO/resolve/main/logo/logo_main.png"> |
| <link rel="canonical" id="canonicalUrl" href="https://bep40-v-aistudio.static.hf.space/"> |
| <meta property="og:url" id="ogUrl" content="https://bep40-v-aistudio.static.hf.space/"> |
| <meta name="twitter:card" content="summary_large_image"> |
| <meta name="twitter:title" id="twTitle" content="V.AI STUDIO"> |
| <meta name="twitter:description" id="twDesc" content="8000+ sản phẩm thiết bị nhà bếp & điện máy chính hãng"> |
| <meta name="twitter:image" id="twImage" content="https://huggingface.co/spaces/bep40/V.AISTUDIO/resolve/main/logo/logo_main.png"> |
| <link rel="icon" href="https://huggingface.co/spaces/bep40/V.AISTUDIO/resolve/main/logo/favicon.png"> |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet"> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css"> |
| <style> |
| *{margin:0;padding:0;box-sizing:border-box} |
| :root{--p:#003f62;--pl:#005a8c;--a:#db9815;--al:#f0b840;--d:#0f172a;--l:#f8fafc;--g:#64748b;--gl:#e2e8f0;--w:#fff;--r:14px;--t:all .25s ease} |
| body{font-family:'Inter',system-ui,sans-serif;color:var(--d);background:var(--l);overflow-x:hidden} |
| ::-webkit-scrollbar{width:6px}::-webkit-scrollbar-thumb{background:var(--p);border-radius:3px} |
| img{max-width:100%;display:block}a{text-decoration:none;color:inherit} |
| .container{max-width:1360px;margin:0 auto;padding:0 20px} |
| </style> |
| </head> |
| <body> |
| |
| <script src="https://cdn.jsdelivr.net/npm/exceljs@4.4.0/dist/exceljs.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script> |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> |
|
|
| |
| <script> |
| (function(){ |
| "use strict"; |
| |
| |
| window.__VAI_BLOB_REG = { blobs: [], isUnloading: false }; |
| var REG = window.__VAI_BLOB_REG; |
| |
| |
| window.addEventListener('pagehide', function() { |
| REG.isUnloading = true; |
| REG.blobs.forEach(function(e) { try { URL.revokeObjectURL(e.url); } catch(r) {} }); |
| }); |
| |
| |
| (function(){var o=URL.revokeObjectURL;URL.revokeObjectURL=function(u){if(REG.isUnloading)return o.call(this,u);if(u&&typeof u==='string'&&u.startsWith('blob:')){var e=REG.blobs.find(function(x){return x.url===u});if(!e)REG.blobs.push({url:u});return;}return o.call(this,u);};})(); |
| |
| |
| function dl(blob, name) { |
| var url = URL.createObjectURL(blob); |
| REG.blobs.push({url:url}); |
| var a = document.createElement('a'); |
| a.href = url; a.download = name; a.style.cssText = 'position:absolute;left:-9999px'; |
| document.body.appendChild(a); |
| a.click(); |
| setTimeout(function() { try { document.body.removeChild(a); } catch(r) {} }, 100); |
| } |
| |
| function fmt(n) { return n && !isNaN(n) ? Number(n).toLocaleString('vi-VN') + 'đ' : '0đ'; } |
| function strip(s) { return (s||'').normalize('NFD').replace(/[\u0300-\u036f]/g,'').replace(/[Đđ]/g,'D'); } |
| function genCode(name) { |
| var d = new Date(), dd = String(d.getDate()).padStart(2,'0'); |
| var mm = String(d.getMonth()+1).padStart(2,'0'), yy = String(d.getFullYear()).slice(-2); |
| var ini = ''; |
| if(name && name.trim()) { |
| name.trim().split(/\s+/).forEach(function(w){ |
| if(w) { var c = strip(w.charAt(0)).toUpperCase(); if(/[A-Z]/.test(c)) ini += c; } |
| }); |
| } |
| return 'VAS' + (ini||'X') + dd + mm + yy; |
| } |
| function setBtn(b, exporting) { |
| if(exporting) { |
| b.disabled = true; |
| b.dataset.vaiExporting = '1'; |
| b.dataset.vaiOrig = b.innerHTML; |
| b.innerHTML = '<span style="opacity:0.7">⏳</span>'; |
| } else { |
| b.disabled = false; |
| b.dataset.vaiExporting = '0'; |
| b.dataset.vaiOrig && (b.innerHTML = b.dataset.vaiOrig); |
| } |
| } |
| function getQD() { |
| var d = { customer:{name:'',phone:'',email:'',addr:'',date:new Date().toLocaleDateString('vi-VN')}, items:[], grandTotal:0 }; |
| var cart = window.cart || [], prods = window.D || []; |
| cart.forEach(function(item,i){ |
| var p = prods[item.idx] || (prods.find ? prods.find(function(x){return x.id===item.id;}) : null); |
| var pr = item.priceNum || item.price || (p ? p.price : 0) || 0; |
| d.items.push({ stt:i+1, name:p ? (p.name||p.n||'') : (item.name||''), model:p ? (p.sku||p.mod||'') : (item.sku||item.model||''), qty:item.qty||1, price:pr, discPrice:pr, total:(item.qty||1)*pr }); |
| }); |
| ['#quoteName','#quoteCustomerName','#checkoutName'].forEach(function(sel){ |
| var el = document.querySelector(sel); |
| if(el && el.value && el.value.trim()) { d.customer.name = el.value.trim(); return; } |
| }); |
| var ph = document.querySelector('#quotePhone,#checkoutPhone'); if(ph && ph.value) d.customer.phone = ph.value.trim(); |
| var ad = document.querySelector('#quoteAddr,#checkoutAddr'); if(ad && ad.value) d.customer.addr = ad.value.trim(); |
| d.grandTotal = d.items.reduce(function(s,i){return s+(i.total||0);},0); |
| return d; |
| } |
| |
| window.VAI_EXCEL_DL = async function(t) { |
| var qd = getQD(), code = genCode(qd.customer.name || ''); |
| if(!qd.items.length || typeof ExcelJS==='undefined') { |
| alert(!qd.items.length ? '⚠️ Không có SP' : '⚠️ Chưa có ExcelJS'); |
| return; |
| } |
| try { |
| var wb = new ExcelJS.Workbook(), ws = wb.addWorksheet('Báo giá'); |
| ws.views = [{showGridLines:false}]; |
| ws.columns = [{width:5},{width:11},{width:28},{width:13},{width:20},{width:6},{width:13},{width:13},{width:15},{width:14}]; |
| ws.mergeCells('A3:J3'); ws.getCell('A3').value = 'BẢNG BÁO GIÁ'; |
| ws.getCell('A3').font = {bold:true,size:18,color:{argb:'FFDB9815'}}; |
| ws.getCell('A3').alignment = {horizontal:'center'}; |
| ws.getCell('A5').value = 'Khách hàng:'; ws.mergeCells('B5:E5'); ws.getCell('B5').value = qd.customer.name; |
| ws.getCell('H5').value = 'Mã đơn:'; ws.mergeCells('I5:J5'); ws.getCell('I5').value = code; |
| ws.getCell('A6').value = 'SĐT:'; ws.mergeCells('B6:E6'); ws.getCell('B6').value = qd.customer.phone; |
| ws.getCell('A8').value = 'Địa chỉ:'; ws.mergeCells('B8:J8'); ws.getCell('B8').value = qd.customer.addr; |
| var hr = ws.getRow(10); |
| ['STT','Hình','Tên sản phẩm','Mã SP','Thông tin','SL','Đơn giá','Giá CK','Thành tiền','Ghi chú'].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 cr = 11, firstRow = cr; |
| qd.items.forEach(function(it){ |
| var row = ws.getRow(cr); row.height = 50; |
| row.getCell(1).value = it.stt; |
| row.getCell(3).value = it.name; row.getCell(3).font = {bold:true}; |
| row.getCell(4).value = it.model; |
| row.getCell(6).value = Number(it.qty); row.getCell(6).numFmt = '#,##0'; |
| row.getCell(7).value = Number(it.price); row.getCell(7).numFmt = '#,##0"đ"'; |
| row.getCell(8).value = Number(it.discPrice); row.getCell(8).numFmt = '#,##0"đ"'; |
| row.getCell(9).value = Number(it.total); row.getCell(9).numFmt = '#,##0"đ"'; |
| cr++; |
| }); |
| ws.getRow(cr).height = 28; ws.mergeCells(cr,1,cr,5); ws.getCell('A'+cr).value = 'TỔNG CỘNG'; |
| ws.getCell('A'+cr).font = {bold:true}; |
| ws.getCell('A'+cr).fill = {type:'pattern',pattern:'solid',fgColor:{argb:'FF003F62'}}; |
| ws.getCell('E'+cr).value = {formula:'SUM(I'+firstRow+':I'+(cr-1)+')',result:qd.grandTotal}; |
| ws.getCell('E'+cr).numFmt = '#,##0"đ"'; |
| wb.calcProperties.fullCalcOnLoad = true; |
| var buf = await wb.xlsx.writeBuffer(); |
| dl(new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}), code + '.xlsx'); |
| if(typeof showToast==='function') showToast('✅ Excel OK'); |
| } catch(err) { alert('❌ Lỗi: ' + err.message); } |
| }; |
| |
| window.VAI_GH_DL = async function() { |
| var order = window.VAI_CURRENT_ORDER; |
| var qd = order && order.items ? { customer:{name:order.customer||'',phone:order.phone||'',addr:order.addr||''}, items:order.items.map(function(it,i){ |
| return { stt:i+1, name:it.name||'', model:it.model||'', qty:it.qty||1, note:it.note||'' }; |
| }) } : getQD(); |
| var code = genCode(qd.customer.name || ''); |
| if(typeof ExcelJS==='undefined' || !qd.items.length) return; |
| try { |
| var wb = new ExcelJS.Workbook(), ws = wb.addWorksheet('Giao hàng'); |
| ws.columns = [{width:5},{width:34},{width:14},{width:8},{width:20}]; |
| ws.mergeCells('A1:E1'); ws.getCell('A1').value = 'PHIẾU GIAO HÀNG'; |
| ws.getCell('A1').font = {bold:true,size:16}; |
| ws.getCell('A2').value = 'KH: ' + qd.customer.name; |
| ws.getCell('D2').value = 'Mã: ' + code; |
| var hr = ws.getRow(6); |
| ['STT','Tên sản phẩm','Mã SP','SL','Ghi chú'].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 cr = 7, tq = 0; |
| qd.items.forEach(function(it){ |
| var row = ws.getRow(cr); |
| row.getCell(1).value = it.stt; |
| row.getCell(2).value = it.name; |
| row.getCell(3).value = it.model; |
| row.getCell(4).value = it.qty; |
| row.getCell(5).value = it.note; |
| tq += Number(it.qty); cr++; |
| }); |
| ws.mergeCells(cr,1,cr,3); ws.getCell('A'+cr).value = 'TỔNG CỘNG SỐ LƯỢNG'; ws.getCell('D'+cr).value = tq; |
| var buf = await wb.xlsx.writeBuffer(); |
| dl(new Blob([buf],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'}), 'GH-' + code + '.xlsx'); |
| } catch(err) {} |
| }; |
| |
| |
| (function(){ |
| function hdl(e) { |
| var btn = e.target.closest('button, a'); |
| if(!btn) return; |
| var txt = (btn.textContent || '').toLowerCase(); |
| var act = document.activeElement; |
| |
| |
| if(txt.includes('excel') && !txt.includes('giao') && !txt.includes('gh-')) { |
| e.preventDefault(); |
| if(act && act.dataset.vaiExporting === '1') return; |
| setBtn(btn, true); |
| window.VAI_EXCEL_DL().then(function(){ setBtn(btn, false); }); |
| return false; |
| } |
| |
| |
| if((txt.includes('giao hàng') || txt.includes('gh')) && txt.includes('excel')) { |
| e.preventDefault(); |
| if(act && act.dataset.vaiExporting === '1') return; |
| setBtn(btn, true); |
| window.VAI_GH_DL().then(function(){ setBtn(btn, false); }); |
| return false; |
| } |
| } |
| |
| |
| document.addEventListener('click', hdl, true); |
| console.log('[VAI EXCEL] CLICK HANDLER ACTIVE'); |
| })(); |
| |
| })(); |
| </script> |
|
|
| |
| <div class="topbar"><div class="container"> |
| <div class="topbar-item"><i class="fas fa-truck-fast"></i> Miễn phí vận chuyển</div> |
| <div class="topbar-item"><i class="fas fa-shield-halved"></i> Bảo hành chính hãng</div> |
| <div class="topbar-item"><i class="fas fa-headset"></i> Hỗ trợ 24/7</div> |
| </div></div> |
|
|
| |
| <div id="app"></div> |
|
|
| <script>console.log('[V.AI STUDIO] Loaded');</script> |
| </body> |
| </html> |