Spaces:
Running
Running
Smart product cards: only show products AI actually mentions in response, match by model code + name keywords
Browse files- index.html +26 -3
index.html
CHANGED
|
@@ -1253,19 +1253,42 @@ text=text.replace(/\/san-pham\/[a-z0-9-]+\/index\.html/g,'');
|
|
| 1253 |
text=text.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>');
|
| 1254 |
// Line breaks
|
| 1255 |
text=text.replace(/\n/g,'<br>');
|
| 1256 |
-
//
|
| 1257 |
if(matchedProducts&&matchedProducts.length>0){
|
| 1258 |
-
let
|
|
|
|
|
|
|
| 1259 |
'<a href="/san-pham/'+p.slug+'/index.html" style="text-decoration:none;color:inherit;display:flex;gap:10px;background:var(--l);border-radius:10px;padding:10px;margin-top:6px;border:1px solid var(--gl);transition:all .2s" onmouseover="this.style.borderColor=\'var(--p)\'" onmouseout="this.style.borderColor=\'var(--gl)\'">'
|
| 1260 |
+'<img src="'+p.image+'" style="width:50px;height:50px;object-fit:contain;border-radius:6px;background:#fff;flex-shrink:0" onerror="this.style.display=\'none\'">'
|
| 1261 |
+'<div style="flex:1;min-width:0"><div style="font-size:.76rem;font-weight:600;color:var(--d);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">'+p.name+'</div>'
|
| 1262 |
+'<div style="font-size:.8rem;font-weight:800;color:var(--p);margin-top:2px">'+(p.price||'Liên hệ')+'</div></div></a>'
|
| 1263 |
).join('');
|
| 1264 |
-
text+=cards;
|
|
|
|
| 1265 |
}
|
| 1266 |
return text;
|
| 1267 |
}
|
| 1268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1269 |
async function sendChat(){
|
| 1270 |
if(chatBusy)return;
|
| 1271 |
let input=document.getElementById('chatInput');
|
|
|
|
| 1253 |
text=text.replace(/\*\*([^*]+)\*\*/g,'<strong>$1</strong>');
|
| 1254 |
// Line breaks
|
| 1255 |
text=text.replace(/\n/g,'<br>');
|
| 1256 |
+
// Smart product cards: only show products MENTIONED in the AI response
|
| 1257 |
if(matchedProducts&&matchedProducts.length>0){
|
| 1258 |
+
let mentionedProducts=filterMentionedProducts(text,matchedProducts);
|
| 1259 |
+
if(mentionedProducts.length>0){
|
| 1260 |
+
let cards=mentionedProducts.slice(0,4).map(p=>
|
| 1261 |
'<a href="/san-pham/'+p.slug+'/index.html" style="text-decoration:none;color:inherit;display:flex;gap:10px;background:var(--l);border-radius:10px;padding:10px;margin-top:6px;border:1px solid var(--gl);transition:all .2s" onmouseover="this.style.borderColor=\'var(--p)\'" onmouseout="this.style.borderColor=\'var(--gl)\'">'
|
| 1262 |
+'<img src="'+p.image+'" style="width:50px;height:50px;object-fit:contain;border-radius:6px;background:#fff;flex-shrink:0" onerror="this.style.display=\'none\'">'
|
| 1263 |
+'<div style="flex:1;min-width:0"><div style="font-size:.76rem;font-weight:600;color:var(--d);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden">'+p.name+'</div>'
|
| 1264 |
+'<div style="font-size:.8rem;font-weight:800;color:var(--p);margin-top:2px">'+(p.price||'Liên hệ')+'</div></div></a>'
|
| 1265 |
).join('');
|
| 1266 |
+
text+='<div style="margin-top:10px;padding-top:10px;border-top:1px solid var(--gl)"><div style="font-size:.68rem;font-weight:700;color:var(--g);margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px">👉 Xem chi tiết sản phẩm</div>'+cards+'</div>';
|
| 1267 |
+
}
|
| 1268 |
}
|
| 1269 |
return text;
|
| 1270 |
}
|
| 1271 |
|
| 1272 |
+
// Filter products that are actually mentioned in the AI response
|
| 1273 |
+
function filterMentionedProducts(responseText,products){
|
| 1274 |
+
if(!products||!products.length)return[];
|
| 1275 |
+
let text=responseText.toLowerCase().replace(/<[^>]*>/g,' ');
|
| 1276 |
+
let mentioned=[];
|
| 1277 |
+
for(let p of products){
|
| 1278 |
+
// Check model code (most reliable match)
|
| 1279 |
+
let model=(p.model||'').toLowerCase().replace(/[^a-z0-9]/g,'');
|
| 1280 |
+
if(model.length>=3&&text.replace(/[^a-z0-9]/g,'').includes(model)){mentioned.push(p);continue}
|
| 1281 |
+
// Check significant words in product name (at least 2 matches from meaningful words)
|
| 1282 |
+
let nameWords=p.name.toLowerCase().replace(/[|]/g,' ').split(/\s+/).filter(w=>w.length>3&&!['malloca','eurogold','grob'].includes(w));
|
| 1283 |
+
let matchCount=nameWords.filter(w=>text.includes(w)).length;
|
| 1284 |
+
if(matchCount>=2){mentioned.push(p);continue}
|
| 1285 |
+
// Check if price is mentioned with nearby product context
|
| 1286 |
+
let priceStr=(p.price||'').replace(/\./g,'').replace('đ','');
|
| 1287 |
+
if(priceStr&&text.replace(/\./g,'').includes(priceStr)){mentioned.push(p)}
|
| 1288 |
+
}
|
| 1289 |
+
return mentioned;
|
| 1290 |
+
}
|
| 1291 |
+
|
| 1292 |
async function sendChat(){
|
| 1293 |
if(chatBusy)return;
|
| 1294 |
let input=document.getElementById('chatInput');
|