diff options
| author | trisusilo48 <tri.susilo@altama.co.id> | 2024-07-10 15:58:51 +0700 |
|---|---|---|
| committer | trisusilo48 <tri.susilo@altama.co.id> | 2024-07-10 15:58:51 +0700 |
| commit | 2e3c726bc8217f3960cfecec44b81303b03de72b (patch) | |
| tree | 1b85ced7f61f3e4c3f1f27b577b37aa161615065 /src/pages/api | |
| parent | 2b3bd9c0a454dbad69ce29cee877bfb1fca5dfa6 (diff) | |
| parent | a99bf6480eea556e53b85e6db45f3b8c2361e693 (diff) | |
Merge branch 'release' into development
# Conflicts:
# src/pages/shop/product/variant/[slug].jsx
Diffstat (limited to 'src/pages/api')
| -rw-r--r-- | src/pages/api/product-variant/[id].js | 2 | ||||
| -rw-r--r-- | src/pages/api/product-variant/[id]/promotion/[category].js | 2 | ||||
| -rw-r--r-- | src/pages/api/product-variant/[id]/promotion/highlight.js | 2 | ||||
| -rw-r--r-- | src/pages/api/promotion-program/[id].js | 2 | ||||
| -rw-r--r-- | src/pages/api/shop/brands.js | 49 | ||||
| -rw-r--r-- | src/pages/api/shop/generate-recomendation.js | 64 | ||||
| -rw-r--r-- | src/pages/api/shop/search.js | 118 | ||||
| -rw-r--r-- | src/pages/api/shop/variant-detail.js | 5 |
8 files changed, 172 insertions, 72 deletions
diff --git a/src/pages/api/product-variant/[id].js b/src/pages/api/product-variant/[id].js new file mode 100644 index 00000000..4186a724 --- /dev/null +++ b/src/pages/api/product-variant/[id].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]'; +export default handler; diff --git a/src/pages/api/product-variant/[id]/promotion/[category].js b/src/pages/api/product-variant/[id]/promotion/[category].js new file mode 100644 index 00000000..aef03c22 --- /dev/null +++ b/src/pages/api/product-variant/[id]/promotion/[category].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]/promotion/[category]'; +export default handler; diff --git a/src/pages/api/product-variant/[id]/promotion/highlight.js b/src/pages/api/product-variant/[id]/promotion/highlight.js new file mode 100644 index 00000000..93b1e781 --- /dev/null +++ b/src/pages/api/product-variant/[id]/promotion/highlight.js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/product-variant/[id]/promotion/highlight'; +export default handler;
\ No newline at end of file diff --git a/src/pages/api/promotion-program/[id].js b/src/pages/api/promotion-program/[id].js new file mode 100644 index 00000000..f2bb550e --- /dev/null +++ b/src/pages/api/promotion-program/[id].js @@ -0,0 +1,2 @@ +import handler from '~/pages/api/promotion-program/[id]'; +export default handler; diff --git a/src/pages/api/shop/brands.js b/src/pages/api/shop/brands.js index dbbfcfe3..cc64a7e7 100644 --- a/src/pages/api/shop/brands.js +++ b/src/pages/api/shop/brands.js @@ -1,36 +1,37 @@ -import axios from 'axios' +import axios from 'axios'; + +const SOLR_HOST = process.env.SOLR_HOST; export default async function handler(req, res) { try { - let params = '*:*' - let sort = 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc ' - let rows = 2000 + let params = '*:*'; + let sort = + 'sort=if(exists(sequence_i),0,1) asc,sequence_i asc, if(exists(image_s),0,1) asc '; + let rows = 2000; if (req.query.params) { - rows = 100 + rows = 100; switch (req?.query?.params) { case 'level_s': - params = 'level_s:prioritas' - break + params = 'level_s:prioritas'; + break; case 'search': - params = `name_s:${req?.query?.q.toLowerCase()}` - sort = '' - rows = 1 + params = `name_s:"${req?.query?.q.toLowerCase()}"`; + sort = ''; + rows = 1; break; default: - params = `name_s:${req.query.params}` + params = `name_s:${req.query.params}`.toLowerCase(); } } - let brands = await axios( - process.env.SOLR_HOST + - `/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}` - ) - let dataBrands = responseMap(brands.data.response.docs) + const url = `${SOLR_HOST}/solr/brands/select?q=${params}&q.op=OR&indent=true&rows=${rows}&${sort}`; + let brands = await axios(url); + let dataBrands = responseMap(brands.data.response.docs); - res.status(200).json(dataBrands) + res.status(200).json(dataBrands); } catch (error) { - console.error('Error fetching data from Solr:', error) - res.status(500).json({ error: 'Internal Server Error' }) + console.error('Error fetching data from Solr:', error); + res.status(500).json({ error: 'Internal Server Error' }); } } @@ -40,9 +41,9 @@ const responseMap = (brands) => { id: brand.id, name: brand.display_name_s, logo: brand.image_s || '', - sequance: brand.sequence_i || '' - } + sequance: brand.sequence_i || '', + }; - return brandMapping - }) -} + return brandMapping; + }); +}; diff --git a/src/pages/api/shop/generate-recomendation.js b/src/pages/api/shop/generate-recomendation.js new file mode 100644 index 00000000..dce8ae72 --- /dev/null +++ b/src/pages/api/shop/generate-recomendation.js @@ -0,0 +1,64 @@ +import { productMappingSolr } from '@/utils/solrMapping' +import axios from 'axios'; +import camelcaseObjectDeep from 'camelcase-object-deep'; + +export default async function handler(req, res) { + const { q = null, op = 'AND' } = req.query + + if (!q) { + return res.status(422).json({ error: 'parameter missing' }) + } + + /*let parameter = [ + `q=${escapeSolrQuery(q)}`, + `q.op=${op}`, + `indent=true`, + `fq=-publish_b:false`, + `qf=name_s^2 description_s`, + `facetch=true`, + `fq=price_tier1_v2_f:[1 TO *]`, + `rows=10`, + `sort=product_rating_f DESC, price_discount_f DESC`, + ]; + let result = await axios( + process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') + );*/ + let parameter = [ + `q=${q}`, + `q.op=${op}`, + `debugQuery=on`, + `defType=edismax`, + `df=display_name_s`, + `fq=-publish_b:false`, + `rows=5`, + ]; + if(op == 'AND'){ + parameter.push(`sort=product_rating_f DESC, price_discount_f DESC`); + parameter.push(`rows=1`); + } + + let result = await axios( + process.env.SOLR_HOST + '/solr/recommendation/select?' + parameter.join('&') + ); + try { + result.data = camelcaseObjectDeep(result.data) + res.status(200).json(result.data) + } catch (error) { + res.status(400).json({ error: error.message }); + } +} + +const escapeSolrQuery = (query) => { + if (query == '*') return query; + + const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g; + const words = query.split(/\s+/); + const escapedWords = words.map((word) => { + if (specialChars.test(word)) { + return `"${word.replace(specialChars, '\\$1')}"`; + } + return word; + }); + + return escapedWords.join(' '); +}; diff --git a/src/pages/api/shop/search.js b/src/pages/api/shop/search.js index 576d028a..b6b8c795 100644 --- a/src/pages/api/shop/search.js +++ b/src/pages/api/shop/search.js @@ -1,6 +1,6 @@ -import { productMappingSolr } from '@/utils/solrMapping' -import axios from 'axios' -import camelcaseObjectDeep from 'camelcase-object-deep' +import { productMappingSolr } from '@/utils/solrMapping'; +import axios from 'axios'; +import camelcaseObjectDeep from 'camelcase-object-deep'; export default async function handler(req, res) { const { @@ -14,35 +14,36 @@ export default async function handler(req, res) { operation = 'AND', fq = '', limit = 30, - stock = '' - } = req.query + } = req.query; - let paramOrderBy = '' + let { stock = '' } = req.query; + + let paramOrderBy = ''; switch (orderBy) { case 'price-asc': - paramOrderBy += 'price_tier1_v2_f ASC' - break + paramOrderBy += 'price_tier1_v2_f ASC'; + break; case 'price-desc': - paramOrderBy += 'price_tier1_v2_f DESC' - break + paramOrderBy += 'price_tier1_v2_f DESC'; + break; case 'popular': - paramOrderBy += 'product_rating_f DESC, search_rank_i DESC,' - break + paramOrderBy += 'product_rating_f DESC, search_rank_i DESC,'; + break; case 'popular-weekly': - paramOrderBy += 'search_rank_weekly_i DESC' - break + paramOrderBy += 'search_rank_weekly_i DESC'; + break; case 'stock': - paramOrderBy += 'stock_total_f DESC' - break + paramOrderBy += 'product_rating_f DESC, stock_total_f DESC'; + break; case 'flashsale-price-asc': - paramOrderBy += 'flashsale_price_f ASC' - break + paramOrderBy += 'flashsale_price_f ASC'; + break; default: - paramOrderBy += 'product_rating_f DESC, price_discount_f DESC' - break + paramOrderBy += 'product_rating_f DESC, price_discount_f DESC'; + break; } - let offset = (page - 1) * limit + let offset = (page - 1) * limit; let parameter = [ 'facet.field=manufacture_name_s', 'facet.field=category_name', @@ -55,59 +56,82 @@ export default async function handler(req, res) { `start=${parseInt(offset)}`, `rows=${limit}`, `sort=${paramOrderBy}`, - `fq=-publish_b:false` - ] + `fq=-publish_b:false`, + ]; if (priceFrom > 0 || priceTo > 0) { parameter.push( `fq=price_tier1_v2_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ priceTo == '' ? '*' : priceTo }]` - ) + ); + } + + let { auth } = req.cookies; + if (auth) { + auth = JSON.parse(auth); + if (auth.feature.onlyReadyStock) stock = true; } - if (brand) parameter.push(`fq=${brand.split(',').map(manufacturer => `manufacture_name:"${manufacturer}"`).join(" OR ")}`) - if (category) parameter.push(`fq=${category.split(',').map(cat => `category_name:"${cat}"`).join(' OR ')}`) + if (brand) + parameter.push( + `fq=${brand + .split(',') + .map((manufacturer) => `manufacture_name:"${encodeURIComponent(manufacturer)}"`) + .join(' OR ')}` + ); + if (category) + parameter.push( + `fq=${category + .split(',') + .map((cat) => `category_name:"${encodeURIComponent(cat)}"`) + .join(' OR ')}` + ); // if (category) parameter.push(`fq=category_name:${capitalizeFirstLetter(category.replace(/,/g, ' OR '))}`) - if (stock) parameter.push(`fq=stock_total_f:{1 TO *}`) + if (stock) parameter.push(`fq=stock_total_f:{1 TO *}`); // Single fq in url params - if (typeof fq === 'string') parameter.push(`fq=${fq}`) + if (typeof fq === 'string') parameter.push(`fq=${fq}`); // Multi fq in url params - if (Array.isArray(fq)) parameter = parameter.concat(fq.map((val) => `fq=${val}`)) + if (Array.isArray(fq)) + parameter = parameter.concat(fq.map((val) => `fq=${val}`)); - let result = await axios(process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&')) + let result = await axios( + process.env.SOLR_HOST + '/solr/product/select?' + parameter.join('&') + ); try { - let { auth } = req.cookies - if (auth) auth = JSON.parse(auth) result.data.response.products = productMappingSolr( result.data.response.docs, auth?.pricelist || false - ) - result.data.responseHeader.params.start = parseInt(result.data.responseHeader.params.start) - result.data.responseHeader.params.rows = parseInt(result.data.responseHeader.params.rows) - delete result.data.response.docs - result.data = camelcaseObjectDeep(result.data) - res.status(200).json(result.data) + ); + result.data.responseHeader.params.start = parseInt( + result.data.responseHeader.params.start + ); + result.data.responseHeader.params.rows = parseInt( + result.data.responseHeader.params.rows + ); + delete result.data.response.docs; + result.data = camelcaseObjectDeep(result.data); + res.status(200).json(result.data); } catch (error) { - res.status(400).json({ error: error.message }) + res.status(400).json({ error: error.message }); } } const escapeSolrQuery = (query) => { - if (query == '*') return query + if (query == '*') return query; - const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g - const words = query.split(/\s+/) + const specialChars = /([\+\-\!\(\)\{\}\[\]\^"~\*\?:\\\/])/g; + const words = query.split(/\s+/); const escapedWords = words.map((word) => { if (specialChars.test(word)) { - return `"${word.replace(specialChars, '\\$1')}"` + return `"${word.replace(specialChars, '\\$1')}"`; } - return word - }) + return word; + }); - return escapedWords.join(' ') -} + return escapedWords.join(' '); +}; /*const productResponseMap = (products, pricelist) => { return products.map((product) => { diff --git a/src/pages/api/shop/variant-detail.js b/src/pages/api/shop/variant-detail.js index fadbe000..08ce75b8 100644 --- a/src/pages/api/shop/variant-detail.js +++ b/src/pages/api/shop/variant-detail.js @@ -8,7 +8,10 @@ export default async function handler(req, res) { `/solr/variants/select?q=id:${req.query.id}&q.op=OR&indent=true` ) let auth = req.query.auth === 'false' ? JSON.parse(req.query.auth) : req.query.auth - let result = variantsMappingSolr('',productVariants.data.response.docs, auth || false) + let productTemplate = await axios( + process.env.SOLR_HOST + `/solr/product/select?q=id:${req.query.id}&q.op=OR&indent=true` + ) + let result = variantsMappingSolr(productTemplate.data.response.docs, productVariants.data.response.docs, auth || false) res.status(200).json(result) } catch (error) { |
