import axios from 'axios' import camelcaseObjectDeep from 'camelcase-object-deep' export default async function handler(req, res) { const { q = '*', page = 1, brand = '', category = '', priceFrom = 0, priceTo = 0, orderBy = '', operation = 'AND', fq = '', limit = 30 } = req.query let paramOrderBy = '' switch (orderBy) { case 'price-asc': paramOrderBy += 'price_discount_f ASC' break case 'price-desc': paramOrderBy += 'price_discount_f DESC' break case 'popular': paramOrderBy += 'search_rank_i DESC' break case 'popular-weekly': paramOrderBy += 'search_rank_weekly_i DESC' break case 'stock': paramOrderBy += 'stock_total_f DESC' break default: paramOrderBy += 'product_rating_f DESC, price_discount_f DESC' break } let offset = (page - 1) * limit let parameter = [ 'facet.field=manufacture_name', 'facet.field=category_name', 'facet=true', 'indent=true', `facet.query=${escapeSolrQuery(q)}`, `q.op=${operation}`, `q=${escapeSolrQuery(q)}`, 'qf=name_s', `start=${offset}`, `rows=${limit}`, `sort=${paramOrderBy}`, `fq=-publish_b:false` ] if (priceFrom > 0 || priceTo > 0) { parameter.push( `fq=price_discount_f:[${priceFrom == '' ? '*' : priceFrom} TO ${ priceTo == '' ? '*' : priceTo }]` ) } if (brand) parameter.push(`fq=manufacture_name:${brand}`) if (category) parameter.push(`fq=category_name:${category}`) // Single fq in url params 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}`)) 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 = productResponseMap( 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) } 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(' ') } const productResponseMap = (products, pricelist) => { return products.map((product) => { let price = price_tier1_v2_f || 0 let priceDiscount = product.price_discount_f || 0 let discountPercentage = product.discount_f || 0 if (pricelist) { // const pricelistDiscount = product?.[`price_${pricelist}_f`] || false // const pricelistDiscountPerc = product?.[`discount_${pricelist}_f`] || false // if (pricelistDiscount && pricelistDiscount > 0) priceDiscount = pricelistDiscount // if (pricelistDiscountPerc && pricelistDiscountPerc > 0) // discountPercentage = pricelistDiscountPerc price = product?.[`price_${pricelist}_v2_f`] || 0 } if (product?.flashsale_id_i > 0) { price = product?.flashsale_base_price_f || 0 priceDiscount = product?.flashsale_price_f || 0 discountPercentage = product?.flashsale_discount_f || 0 } let productMapped = { id: product.product_id_i || '', image: product.image_s || '', code: product.default_code_s || '', name: product.name_s || '', lowestPrice: { price, priceDiscount, discountPercentage }, variantTotal: product.variant_total_i || 0, stockTotal: product.stock_total_f || 0, weight: product.weight_f || 0, manufacture: {}, categories: [], flashSale: { id: product?.flashsale_id_i, name: product?.product?.flashsale_name_s, tag : product?.flashsale_tag_s || 'FLASH SALE' } } if (product.manufacture_id_i && product.manufacture_name_s) { productMapped.manufacture = { id: product.manufacture_id_i || '', name: product.manufacture_name_s || '' } } productMapped.categories = [ { id: product.category_id_i || '', name: product.category_name_s || '' } ] return productMapped }) }