Spaces:
Running
Running
Fix ALL: local CK (no API), remove AI quote btn, cart btn on cards, Eurogold images, Excel numFmt
Browse files- index.html +25 -52
index.html
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="vi">
|
| 3 |
-
<head><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
<title>V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi</title>
|
|
@@ -498,7 +498,7 @@ textarea.form-input{height:120px;resize:vertical}
|
|
| 498 |
<input type="text" id="aiSearch" placeholder="🔍 AI tìm kiếm: bếp từ đôi dưới 15 triệu, máy hút mùi tốt nhất..." style="width:100%;padding:11px 14px 11px 36px;border:2px solid #003f62;border-radius:10px;font-size:.85rem;font-family:inherit;outline:none" onkeypress="if(event.key==='Enter')doAISearch()">
|
| 499 |
</div>
|
| 500 |
<button onclick="doAISearch()" style="padding:11px 20px;background:#003f62;color:#fff;border:none;border-radius:10px;font-weight:700;font-size:.85rem;cursor:pointer;white-space:nowrap"><i class="fas fa-search"></i> Tìm AI</button>
|
| 501 |
-
|
| 502 |
</div>
|
| 503 |
<div id="aiResults" style="max-width:900px;margin:12px auto 0;display:none;background:#f8fafc;border-radius:10px;padding:14px;font-size:.82rem"></div>
|
| 504 |
</div>
|
|
@@ -2032,62 +2032,31 @@ document.querySelectorAll('.qt-disc').forEach(el=>{el.disabled=true;el.style.bac
|
|
| 2032 |
}
|
| 2033 |
}
|
| 2034 |
|
| 2035 |
-
async function
|
| 2036 |
-
let
|
| 2037 |
-
|
| 2038 |
let btn=document.getElementById('aiDiscBtn');
|
| 2039 |
let statusEl=document.getElementById('aiDiscStatus');
|
| 2040 |
-
btn.disabled=true;btn.innerHTML='<i class="fas fa-spinner fa-spin"></i> Đang xử lý...';
|
| 2041 |
-
statusEl.textContent='';
|
| 2042 |
-
|
| 2043 |
-
// Build product list for AI
|
| 2044 |
-
let productList=cart.map((c,i)=>{
|
| 2045 |
-
let product=D[c.idx]||{};
|
| 2046 |
-
return `SP${i+1}: ${c.name} | Mã: ${product.model||''} | Đơn giá: ${c.priceNum}`;
|
| 2047 |
-
}).join('\n');
|
| 2048 |
-
|
| 2049 |
-
let systemMsg=`Bạn là hệ thống tính chiết khấu. Người dùng sẽ yêu cầu giảm giá cho danh sách sản phẩm.
|
| 2050 |
|
| 2051 |
-
|
| 2052 |
-
|
|
|
|
| 2053 |
|
| 2054 |
-
|
| 2055 |
-
|
| 2056 |
-
|
| 2057 |
-
|
| 2058 |
-
|
| 2059 |
-
Ví dụ: nếu có 3 SP giá 10000000, 5000000, 8000000 và user yêu cầu "giảm 10%":
|
| 2060 |
-
[9000000, 4500000, 7200000]`;
|
| 2061 |
-
|
| 2062 |
-
try{
|
| 2063 |
-
let vars=window.huggingface?.variables||{};
|
| 2064 |
-
let token=vars.HF_TOKEN||vars.VAISTUDIO||'';
|
| 2065 |
-
if(token&&!token.startsWith('hf_'))token='';
|
| 2066 |
-
if(!token){statusEl.textContent='⚠️ Chưa có API token';btn.disabled=false;btn.innerHTML='<i class="fas fa-robot"></i> Áp dụng';return}
|
| 2067 |
|
| 2068 |
-
|
| 2069 |
-
|
| 2070 |
-
|
| 2071 |
-
|
| 2072 |
-
|
| 2073 |
-
|
| 2074 |
-
|
| 2075 |
-
// Parse JSON array from reply
|
| 2076 |
-
let match=reply.match(/\[[\d,\s]+\]/);
|
| 2077 |
-
if(match){
|
| 2078 |
-
let prices=JSON.parse(match[0]);
|
| 2079 |
-
if(prices.length===cart.length){
|
| 2080 |
-
prices.forEach((p,i)=>{
|
| 2081 |
-
let el=document.querySelector(`.qt-disc[data-idx="${i}"]`);
|
| 2082 |
-
if(el){el.value=Math.round(p).toLocaleString('vi-VN');el.disabled=false;el.style.background='#fff';el.style.cursor='text'}
|
| 2083 |
});
|
| 2084 |
updateQuoteTotal();
|
| 2085 |
-
statusEl.
|
| 2086 |
-
statusEl.style.color='#28a745';
|
| 2087 |
-
}else{statusEl.textContent='⚠️ Số SP không khớp ('+prices.length+' vs '+cart.length+')';statusEl.style.color='#dc3545'}
|
| 2088 |
-
}else{statusEl.textContent='⚠️ AI: '+reply.substring(0,80);statusEl.style.color='#dc3545'}
|
| 2089 |
-
}catch(e){statusEl.textContent='❌ Lỗi: '+e.message;statusEl.style.color='#dc3545'}
|
| 2090 |
-
btn.disabled=false;btn.innerHTML='<i class="fas fa-robot"></i> Áp dụng';
|
| 2091 |
}
|
| 2092 |
|
| 2093 |
function renderQuoteTable(){
|
|
@@ -2105,7 +2074,7 @@ let discStyle='width:80px;padding:5px 6px;border:1.5px solid var(--gl);border-ra
|
|
| 2105 |
discStyle+=locked?'background:var(--l);cursor:not-allowed':'background:#fff';
|
| 2106 |
return `<tr>
|
| 2107 |
<td style="text-align:center">${i+1}</td>
|
| 2108 |
-
<td><img class="qt-img" src="${c.image}" alt="${c.name}" crossorigin="anonymous" onerror="this.style.display='none'" style="width:72px;height:72px;object-fit:contain"></td>
|
| 2109 |
<td class="qt-name">${c.name}</td>
|
| 2110 |
<td style="text-align:center">${model}</td>
|
| 2111 |
<td style="font-size:.72rem;color:var(--g);max-width:160px">${specs}</td>
|
|
@@ -2283,6 +2252,9 @@ let dataEndR=r-1;
|
|
| 2283 |
// ═══ SUMMARY SECTION ═══
|
| 2284 |
let sumStyle={border:{top:{style:'thin',color:{argb:'FFD0D5DD'}},bottom:{style:'thin',color:{argb:'FFD0D5DD'}}}};
|
| 2285 |
|
|
|
|
|
|
|
|
|
|
| 2286 |
// TỔNG CỘNG
|
| 2287 |
let tr=r;
|
| 2288 |
ws.mergeCells(tr,1,tr,8);
|
|
@@ -2782,6 +2754,7 @@ function doAISearch(){
|
|
| 2782 |
h+='<div style="font-size:.88rem;font-weight:800;color:#003f62;margin-top:4px">'+(p.price||'Liên hệ')+'</div>';
|
| 2783 |
const specs=p.specs||{};const sk=Object.entries(specs).slice(0,3);
|
| 2784 |
if(sk.length){h+='<div style="margin-top:4px;padding-top:4px;border-top:1px solid #eee;font-size:.58rem;color:#555">';sk.forEach(([k,v])=>{h+='<div>'+k+': <b>'+v+'</b></div>'});h+='</div>'}
|
|
|
|
| 2785 |
h+='</div>';
|
| 2786 |
});
|
| 2787 |
h+='</div>';
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="vi">
|
| 3 |
+
<head><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script><script>window.huggingface={variables:{"SPACE_CREATOR_USER_ID":"661b9191e7b0ab12bceb66f3","VAISTUDIO":""}};</script>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
<title>V.AI STUDIO | Niềm tin khách hàng là tài sản của chúng tôi</title>
|
|
|
|
| 498 |
<input type="text" id="aiSearch" placeholder="🔍 AI tìm kiếm: bếp từ đôi dưới 15 triệu, máy hút mùi tốt nhất..." style="width:100%;padding:11px 14px 11px 36px;border:2px solid #003f62;border-radius:10px;font-size:.85rem;font-family:inherit;outline:none" onkeypress="if(event.key==='Enter')doAISearch()">
|
| 499 |
</div>
|
| 500 |
<button onclick="doAISearch()" style="padding:11px 20px;background:#003f62;color:#fff;border:none;border-radius:10px;font-weight:700;font-size:.85rem;cursor:pointer;white-space:nowrap"><i class="fas fa-search"></i> Tìm AI</button>
|
| 501 |
+
|
| 502 |
</div>
|
| 503 |
<div id="aiResults" style="max-width:900px;margin:12px auto 0;display:none;background:#f8fafc;border-radius:10px;padding:14px;font-size:.82rem"></div>
|
| 504 |
</div>
|
|
|
|
| 2032 |
}
|
| 2033 |
}
|
| 2034 |
|
| 2035 |
+
async function applyDiscount(){
|
| 2036 |
+
let inp=document.querySelector('.quote-section textarea, .quote-section input[type="text"]');
|
| 2037 |
+
let txt=inp?inp.value.trim():'';
|
| 2038 |
let btn=document.getElementById('aiDiscBtn');
|
| 2039 |
let statusEl=document.getElementById('aiDiscStatus');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2040 |
|
| 2041 |
+
// Parse CK percentage from text: "30%", "ck 30", "giảm 30%", etc.
|
| 2042 |
+
let match=txt.match(/(\d+)\s*%?/);
|
| 2043 |
+
let ckPercent=match?parseFloat(match[1]):0;
|
| 2044 |
|
| 2045 |
+
if(!ckPercent||ckPercent<=0||ckPercent>90){
|
| 2046 |
+
if(statusEl)statusEl.textContent='Nhập % chiết khấu (VD: 30%)';
|
| 2047 |
+
return;
|
| 2048 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2049 |
|
| 2050 |
+
// Apply CK to all items locally - NO API needed
|
| 2051 |
+
cart.forEach((c,i)=>{
|
| 2052 |
+
if(c.priceNum>0){
|
| 2053 |
+
let discPrice=Math.round(c.priceNum*(1-ckPercent/100));
|
| 2054 |
+
let discInput=document.querySelector('.qt-disc[data-idx="'+i+'"]');
|
| 2055 |
+
if(discInput)discInput.value=discPrice.toLocaleString('vi-VN');
|
| 2056 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2057 |
});
|
| 2058 |
updateQuoteTotal();
|
| 2059 |
+
if(statusEl)statusEl.textContent='\u2705 Đã áp dụng CK '+ckPercent+'% cho '+cart.length+' SP';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2060 |
}
|
| 2061 |
|
| 2062 |
function renderQuoteTable(){
|
|
|
|
| 2074 |
discStyle+=locked?'background:var(--l);cursor:not-allowed':'background:#fff';
|
| 2075 |
return `<tr>
|
| 2076 |
<td style="text-align:center">${i+1}</td>
|
| 2077 |
+
<td><img class="qt-img" src="${c.image}" referrerpolicy="no-referrer" alt="${c.name}" crossorigin="anonymous" onerror="this.style.display='none'" style="width:72px;height:72px;object-fit:contain"></td>
|
| 2078 |
<td class="qt-name">${c.name}</td>
|
| 2079 |
<td style="text-align:center">${model}</td>
|
| 2080 |
<td style="font-size:.72rem;color:var(--g);max-width:160px">${specs}</td>
|
|
|
|
| 2252 |
// ═══ SUMMARY SECTION ═══
|
| 2253 |
let sumStyle={border:{top:{style:'thin',color:{argb:'FFD0D5DD'}},bottom:{style:'thin',color:{argb:'FFD0D5DD'}}}};
|
| 2254 |
|
| 2255 |
+
// Number format for prices
|
| 2256 |
+
ws.getColumn(7).numFmt='#,##0';ws.getColumn(8).numFmt='#,##0';ws.getColumn(9).numFmt='#,##0';
|
| 2257 |
+
|
| 2258 |
// TỔNG CỘNG
|
| 2259 |
let tr=r;
|
| 2260 |
ws.mergeCells(tr,1,tr,8);
|
|
|
|
| 2754 |
h+='<div style="font-size:.88rem;font-weight:800;color:#003f62;margin-top:4px">'+(p.price||'Liên hệ')+'</div>';
|
| 2755 |
const specs=p.specs||{};const sk=Object.entries(specs).slice(0,3);
|
| 2756 |
if(sk.length){h+='<div style="margin-top:4px;padding-top:4px;border-top:1px solid #eee;font-size:.58rem;color:#555">';sk.forEach(([k,v])=>{h+='<div>'+k+': <b>'+v+'</b></div>'});h+='</div>'}
|
| 2757 |
+
h+='<button onclick="event.stopPropagation();addToCart('+D.indexOf(p)+')" style="margin-top:5px;width:100%;padding:5px;background:var(--p);color:#fff;border:none;border-radius:5px;font-size:.68rem;cursor:pointer;font-weight:600">+ Thêm giỏ hàng</button>';
|
| 2758 |
h+='</div>';
|
| 2759 |
});
|
| 2760 |
h+='</div>';
|