bep40 commited on
Commit
0c1d8c2
·
verified ·
1 Parent(s): 2ece7e9

Fix AI search: use window.D instead of bare D references

Browse files
Files changed (1) hide show
  1. ai-search-fix.js +48 -16
ai-search-fix.js CHANGED
@@ -8,6 +8,8 @@
8
  * properly loaded and contains full NL search logic.
9
  *
10
  * Additional fix: Handle multi-product search (comma/semicolon separated codes).
 
 
11
  */
12
 
13
  window.doAISearch = function() {
@@ -25,23 +27,34 @@ window.doAISearch = function() {
25
  resultsDiv.style.display = 'block';
26
  resultsDiv.innerHTML = '⏳ Đang tìm...';
27
 
 
 
 
28
  // Multi-product search: if query contains comma/semicolon, search by product codes
29
  var queries = query.split(/[,;]+/).map(function(c) { return c.trim(); }).filter(function(c) { return c.length >= 2; });
30
 
31
- if (queries.length > 1) {
 
 
32
  // Multi-code search mode
33
  var allResults = [];
34
- var normFn = function(s) { return String(s || '').toLowerCase().replace(/[.\- _\/]/g, '').replace(/đ/g, 'd'); };
35
 
36
  queries.forEach(function(q) {
37
- var qNorm = normFn(q);
38
  for (var i = 0; i < D.length && allResults.length < 30; i++) {
39
  var p = D[i];
40
  if (!p) continue;
41
- var fields = [(p.sku || ''), (p.mod || ''), (p.model || ''), (p.slug || '')].map(normFn);
42
- if (fields.some(function(f) {
43
- return f === qNorm || (f && qNorm.length >= 3 && (f.indexOf(qNorm) !== -1 || qNorm.indexOf(f) !== -1));
44
- })) {
 
 
 
 
 
 
45
  allResults.push(p);
46
  }
47
  }
@@ -53,7 +66,7 @@ window.doAISearch = function() {
53
  }
54
  }
55
 
56
- if (typeof window.aiSearch === 'function' && typeof window.D !== 'undefined' && D.length > 0) {
57
  var aiToken = (window.huggingface && window.huggingface.variables && window.huggingface.variables.VAISTUDIO) || '';
58
  window.aiSearch(query, D, aiToken).then(function(aiResult) {
59
  if (!aiResult || (!aiResult.results.length && !aiResult.aiAnswer)) {
@@ -184,8 +197,9 @@ function _renderAIResultsToDiv(aiResult, container, query) {
184
  }
185
 
186
  function _fallbackAISearch(query, container) {
187
- if (typeof D === 'undefined' || !D.length) {
188
- container.innerHTML = '⏳ Đang tải dữ liệu...';
 
189
  return;
190
  }
191
  var qNorm = query.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd');
@@ -195,22 +209,40 @@ function _fallbackAISearch(query, container) {
195
  if (!p) continue;
196
  var nameNorm = (p.name || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd');
197
  var skuNorm = (p.sku || p.mod || '').toLowerCase();
198
- if (nameNorm.indexOf(qNorm) !== -1 || (skuNorm && skuNorm.indexOf(qNorm) !== -1)) {
 
 
 
 
 
 
199
  results.push(p);
200
  }
201
  }
202
  if (!results.length) {
203
- container.innerHTML = '❌ Không tìm thấy "' + query + '". Thử: "bếp từ", "máy hút mùi"';
204
  return;
205
  }
206
  container.innerHTML = '<div style="font-size:.78rem;color:#64748b;margin-bottom:10px"><strong>' + results.length + '</strong> kết quả</div>' +
207
  '<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px">' +
208
- results.map(function(p, idx) {
 
 
209
  var imgSrc = p.image || p.i || '';
210
  var priceStr = p.price || (p.pn ? p.pn : 'Liên hệ');
211
  return '<div class="pc fade" onclick="showDetail(' + idx + ')" style="cursor:pointer">' +
212
- '<div class="pi" style="height:150px"><img src="' + imgSrc + '" alt="' + p.name + '" loading="lazy"></div>' +
213
- '<div class="pb" style="padding:10px"><div class="pn" style="font-size:.76rem">' + p.name + '</div>' +
 
214
  '<div class="pf" style="margin-top:6px"><span class="pp" style="font-size:.92rem">' + priceStr + '</span></div></div></div>';
215
  }).join('') + '</div>';
216
- }
 
 
 
 
 
 
 
 
 
 
8
  * properly loaded and contains full NL search logic.
9
  *
10
  * Additional fix: Handle multi-product search (comma/semicolon separated codes).
11
+ * Critical fix: All references to D must use window.D since let D in index.html
12
+ * does NOT create a global property on window object.
13
  */
14
 
15
  window.doAISearch = function() {
 
27
  resultsDiv.style.display = 'block';
28
  resultsDiv.innerHTML = '⏳ Đang tìm...';
29
 
30
+ // Wait for data to be ready
31
+ function getD() { return (typeof window.D !== 'undefined' && window.D.length > 0) ? window.D : null; }
32
+
33
  // Multi-product search: if query contains comma/semicolon, search by product codes
34
  var queries = query.split(/[,;]+/).map(function(c) { return c.trim(); }).filter(function(c) { return c.length >= 2; });
35
 
36
+ var D = getD();
37
+
38
+ if (queries.length > 1 && D) {
39
  // Multi-code search mode
40
  var allResults = [];
41
+ var normSimple = function(s) { return String(s || '').toLowerCase().replace(/[.\/\-]/g, ''); };
42
 
43
  queries.forEach(function(q) {
44
+ var qNorm = normSimple(q);
45
  for (var i = 0; i < D.length && allResults.length < 30; i++) {
46
  var p = D[i];
47
  if (!p) continue;
48
+ var nameField = (p.name || '').toLowerCase();
49
+ var modField = (p.mod || '').toLowerCase();
50
+ var skuField = normSimple(p.sku || '');
51
+ var modelField = (p.model || '').toLowerCase();
52
+ var slugField = (p.slug || '').toLowerCase();
53
+
54
+ if (skuField === qNorm ||
55
+ modField.replace(/[.\/\- ]/g, '').includes(qNorm) ||
56
+ nameField.replace(/[.\/\- ]/g, '').includes(qNorm) ||
57
+ slugField.replace(/[.\/\- ]/g, '').includes(qNorm)) {
58
  allResults.push(p);
59
  }
60
  }
 
66
  }
67
  }
68
 
69
+ if (typeof window.aiSearch === 'function' && D) {
70
  var aiToken = (window.huggingface && window.huggingface.variables && window.huggingface.variables.VAISTUDIO) || '';
71
  window.aiSearch(query, D, aiToken).then(function(aiResult) {
72
  if (!aiResult || (!aiResult.results.length && !aiResult.aiAnswer)) {
 
197
  }
198
 
199
  function _fallbackAISearch(query, container) {
200
+ var D = (typeof window.D !== 'undefined') ? window.D : null;
201
+ if (!D || !D.length) {
202
+ container.innerHTML = '⏳ Đang tải dữ liệu sản phẩm... Vui lòng chờ.';
203
  return;
204
  }
205
  var qNorm = query.toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd');
 
209
  if (!p) continue;
210
  var nameNorm = (p.name || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd');
211
  var skuNorm = (p.sku || p.mod || '').toLowerCase();
212
+ var catNorm = (p.cat || '').toLowerCase().normalize('NFD').replace(/[̀-ͯ]/g, '').replace(/đ/g, 'd');
213
+ var brandNorm = (p.brand || '').toLowerCase();
214
+ if (nameNorm.indexOf(qNorm) !== -1 ||
215
+ (skuNorm && skuNorm.indexOf(qNorm) !== -1) ||
216
+ (catNorm && catNorm.indexOf(qNorm) !== -1) ||
217
+ (brandNorm && brandNorm.indexOf(qNorm) !== -1) ||
218
+ (p._idx && typeof p._idx === 'string' && p._idx.toLowerCase().indexOf(qNorm) !== -1)) {
219
  results.push(p);
220
  }
221
  }
222
  if (!results.length) {
223
+ container.innerHTML = '❌ Không tìm thấy "' + query + '". Thử: "bếp từ", "máy hút mùi", "Malloca", "Eurogold"';
224
  return;
225
  }
226
  container.innerHTML = '<div style="font-size:.78rem;color:#64748b;margin-bottom:10px"><strong>' + results.length + '</strong> kết quả</div>' +
227
  '<div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px">' +
228
+ results.map(function(p) {
229
+ var idx = window.D ? window.D.indexOf(p) : -1;
230
+ var brandColor = p.brand === 'Eurogold' ? '#c8102e' : (p.brand === 'Grob' ? '#2e7d32' : '#003f62');
231
  var imgSrc = p.image || p.i || '';
232
  var priceStr = p.price || (p.pn ? p.pn : 'Liên hệ');
233
  return '<div class="pc fade" onclick="showDetail(' + idx + ')" style="cursor:pointer">' +
234
+ '<div class="pi" style="height:150px"><img src="' + imgSrc + '" alt="' + p.name + '" loading="lazy" onerror="this.style.display=\'none\'"></div>' +
235
+ '<div class="pb" style="padding:10px"><div style="font-size:.62rem;font-weight:600;color:' + brandColor + ';margin-bottom:3px">' + (p.brand || '') + '</div>' +
236
+ '<div class="pn" style="font-size:.76rem">' + p.name + '</div>' +
237
  '<div class="pf" style="margin-top:6px"><span class="pp" style="font-size:.92rem">' + priceStr + '</span></div></div></div>';
238
  }).join('') + '</div>';
239
+
240
+ if (window.requestAnimationFrame) {
241
+ requestAnimationFrame(function() {
242
+ var fadeEls = container.querySelectorAll('.fade');
243
+ for (var j = 0; j < fadeEls.length; j++) {
244
+ fadeEls[j].classList.add('vis');
245
+ }
246
+ });
247
+ }
248
+ }