summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFIN-IT_AndriFP <andrifebriyadiputra@gmail.com>2025-12-19 15:20:31 +0700
committerFIN-IT_AndriFP <andrifebriyadiputra@gmail.com>2025-12-19 15:20:31 +0700
commit1876d142f492714c37efdc1eabb72709917a0c1d (patch)
treeff5e7032e78517a58cdcce27c13e8d0f914ce499
parent0c745c513765b23ee200eb61ebfe13086a1ea700 (diff)
(andri) searching comparable
-rw-r--r--src-migrate/modules/product-detail/components/ProductComparisonModal.tsx2
-rw-r--r--src-migrate/types/productVariant.ts1
-rw-r--r--src/pages/api/shop/search.js106
-rw-r--r--src/utils/solrMapping.js1
4 files changed, 64 insertions, 46 deletions
diff --git a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
index 3ee61c9d..e0685d35 100644
--- a/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
+++ b/src-migrate/modules/product-detail/components/ProductComparisonModal.tsx
@@ -168,7 +168,7 @@ const ProductComparisonModal = ({ isOpen, onClose, mainProduct, selectedVariant
const params = new URLSearchParams({
source: 'compare',
- q: '*',
+ q: searchQuery,
limit: '5',
// Filter kategori aktif agar Apple-to-Apple
fq: attrSetId ? `attribute_set_id_i:${attrSetId}` : ''
diff --git a/src-migrate/types/productVariant.ts b/src-migrate/types/productVariant.ts
index 08fdd270..31cedf8c 100644
--- a/src-migrate/types/productVariant.ts
+++ b/src-migrate/types/productVariant.ts
@@ -6,6 +6,7 @@ export interface IProductVariantDetail {
weight: number;
attribute_set_id: number;
attribute_set_name: string;
+ search_keywords: string;
is_in_bu: boolean;
is_flashsale: {
remaining_time: number;
diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js
index 90841e09..5ea6a70a 100644
--- a/src/pages/api/shop/search.js
+++ b/src/pages/api/shop/search.js
@@ -28,54 +28,67 @@ export default async function handler(req, res) {
let { stock = '' } = req.query;
// ============================================================
- // [BARU] 1. LOGIC KHUSUS COMPARE (Wajib ditaruh paling atas)
+ // [PERBAIKAN] 1. LOGIC KHUSUS COMPARE (PAKAI URLSearchParams)
// ============================================================
if (source === 'compare') {
try {
let qCompare = q === '*' ? '*:*' : q;
-
+
// Sanitasi Query
if (qCompare !== '*:*') {
- const escaped = escapeSolrQuery(qCompare);
- qCompare = `*${escaped}*`;
+ // Kita escape, tapi biarkan stringnya bersih (jangan ditambah wildcard * manual)
+ // karena kita serahkan ke 'edismax' parser
+ qCompare = escapeSolrQuery(qCompare);
}
- // Susun Parameter Solr
- const parameter = [
- `q=${encodeURIComponent(qCompare)}`,
- `rows=${limit}`,
- 'wt=json',
- 'indent=true',
- 'defType=edismax',
-
- // Grouping agar varian tidak banjir (per template)
- 'group=true',
- 'group.field=template_id_i',
- 'group.limit=1',
- 'group.main=true',
-
- // Field Wajib (Perhatikan: kita butuh product_id_i/default_code_s)
- 'fl=id,display_name_s,default_code_s,image_s,price_tier1_v2_f,attribute_set_id_i,attribute_set_name_s,template_id_i,product_id_i',
-
- // Filter Dasar
- 'fq=-publish_b:false',
- 'fq=price_tier1_v2_f:[1 TO *]'
- ];
+ // [SOLUSI] Gunakan URLSearchParams untuk menyusun URL dengan aman
+ const params = new URLSearchParams();
+
+ params.append('q', qCompare);
+ params.append('rows', limit);
+ params.append('wt', 'json');
+ params.append('indent', 'true');
+
+ // Gunakan eDisMax parser (Otak Cerdas)
+ params.append('defType', 'edismax');
+
+ // Set Prioritas Pencarian (Boost ^)
+ // 1. default_code_s^20 : SKU persis (Prioritas Tertinggi)
+ // 2. search_keywords_t^10 : Field baru (Case insensitive)
+ // 3. display_name_s^1 : Cadangan
+ params.append('qf', 'default_code_s^20 search_keywords_t^10 display_name_s^1');
+
+ // Minimum Match 100% (Semua kata harus ada), ubah jika ingin lebih longgar
+ params.append('mm', '100%');
+
+ // Grouping
+ params.append('group', 'true');
+ params.append('group.field', 'template_id_i');
+ params.append('group.limit', '1');
+ params.append('group.main', 'true');
+
+ // Field List (fl)
+ params.append('fl', 'id,display_name_s,default_code_s,image_s,price_tier1_v2_f,attribute_set_id_i,attribute_set_name_s,template_id_i,product_id_i');
+
+ // Filter Query (fq) Dasar
+ params.append('fq', '-publish_b:false');
+ params.append('fq', 'price_tier1_v2_f:[1 TO *]');
// Logic Locking (Filter Attribute Set ID dari Frontend)
- // Frontend akan mengirim fq="attribute_set_id_i:9"
if (fq) {
- if (Array.isArray(fq)) {
- fq.forEach(f => parameter.push(`fq=${encodeURIComponent(f)}`));
- } else {
- parameter.push(`fq=${encodeURIComponent(fq)}`);
- }
+ if (Array.isArray(fq)) {
+ fq.forEach(f => params.append('fq', f));
+ } else {
+ params.append('fq', fq);
+ }
}
- // Target Core: VARIANTS (Karena compare butuh data spesifik)
- const solrUrl = process.env.SOLR_HOST + '/solr/variants/select?' + parameter.join('&');
-
- const result = await axios(solrUrl);
+ // Target Core: VARIANTS
+ // HAPUS parameter manual dari string URL, gunakan params object
+ const solrUrl = process.env.SOLR_HOST + '/solr/variants/select';
+
+ // Axios akan otomatis handle encoding % dan & dengan benar
+ const result = await axios.get(solrUrl, { params: params });
// Mapping Result
const mappedProducts = productMappingSolr(
@@ -84,13 +97,13 @@ export default async function handler(req, res) {
);
const finalResponse = {
- ...result.data,
- response: {
- ...result.data.response,
- products: mappedProducts
- }
+ ...result.data,
+ response: {
+ ...result.data.response,
+ products: mappedProducts
+ }
};
-
+
delete finalResponse.response.docs;
const camelCasedData = camelcaseObjectDeep(finalResponse);
@@ -98,13 +111,16 @@ export default async function handler(req, res) {
} catch (e) {
console.error('[COMPARE SEARCH ERROR]', e.message);
- // Return JSON valid meski kosong, agar frontend tidak error syntax
+ if (e.response && e.response.data) {
+ // Log detail error dari Solr
+ console.error('[SOLR DETAILS]:', JSON.stringify(e.response.data, null, 2));
+ }
return res.status(200).json({ response: { products: [], numFound: 0 } });
}
}
// ============================================================
- // LOGIC KHUSUS UPSELL (Simple & Direct)
+ // LOGIC KHUSUS UPSELL (KODE LAMA ANDA)
// ============================================================
if (source === 'upsell') {
try {
@@ -172,7 +188,7 @@ export default async function handler(req, res) {
}
// ============================================================
- // SITEMAP (Biarkan tetap sama)
+ // SITEMAP (KODE LAMA ANDA)
// ============================================================
if (source === 'sitemap') {
try {
@@ -197,7 +213,7 @@ export default async function handler(req, res) {
}
// ============================================================
- // SEARCH NORMAL (LOGIKA LAMA)
+ // SEARCH NORMAL (KODE LAMA ANDA)
// ============================================================
let paramOrderBy = '';
diff --git a/src/utils/solrMapping.js b/src/utils/solrMapping.js
index 419e0c61..8c0abcf1 100644
--- a/src/utils/solrMapping.js
+++ b/src/utils/solrMapping.js
@@ -129,6 +129,7 @@ export const variantsMappingSolr = (parent, products, pricelist) => {
weight: product.weight_f || 0,
attribute_set_id: product.attribute_set_id_i || 0,
attribute_set_name: product.attribute_set_name_s || '',
+ search_keywords: product.search_keywords_t || '',
manufacture: {},
parent: {},
qtySold: product?.qty_sold_f || 0,