/** * search controller * @author: wsl<shuiling.wang@yoho.cn> * @date: 2016/7/21 */ 'use strict'; const utils = '../../../utils'; const mRoot = '../models'; const headerModel = require('../../../doraemon/models/header'); const searchModel = require(`${mRoot}/search`); const _ = require('lodash'); const helpers = global.yoho.helpers; const searchProcess = require(`${utils}/search-process`); const productProcess = require(`${utils}/product-process`); const listParamsProcess = require(`${utils}/list-params-process`); const co = require('bluebird').coroutine; /** * 搜索落地页 */ exports.list = (req, res, next) => { let params = Object.assign({ isSearch: true, // 搜索列表将最新改成默认的标识 cartUrl: helpers.urlFormat('/cart/index/index') }, req.query, {query: (req.query.query || '').toString()}); let title = ''; let isQueryFirstClass = false; // 标识用户搜的是不是一级品类 let isQuerySecondClass = false; // 标识用户搜的是不是二级品类 // let domain = null; let uid = req.user.uid || 0; if (params.shop_id) { params.shopId = params.shop_id; } params.isApp = req.yoho.isApp; params.physical_channel = req.yoho.channel && searchProcess.getChannelType(req.yoho.channel); // 唤起 APP 的路径 res.locals.appPath = `yohobuy://yohobuy.com/goapp?openby:yohobuy={"action":"go.list","params":${JSON.stringify(params)}}`; return req.ctx(searchModel).searchKeyActivity(params.query || '').then(activityResult => { let activity = _.get(activityResult, 'urlobj.appUrl', ''); if (activity) { return res.redirect(activity); } else { // 获取第一页数据做服务端渲染 let initialData = _.assign({ type: 'default', order: '0', page: 1, limit: 24 }, params); if (uid) { initialData.uid = uid; } /* 判断是不是品牌, 是品牌跳到品牌列表页(显示搜索框),判断是不是品类, 是品类加导航标题(不显示搜索框) */ return Promise.all([ req.ctx(searchModel).getBrandDomain(params.query.toLowerCase()), req.ctx(searchModel).getClassNames(), req.ctx(searchModel).getSearchData(initialData) ]).then(result => { // 推荐词条件判断 redmine: 18567 if (result[2].suggestion && result[2].suggestion.isNeedSuggestion && result[2].suggestion.termsSuggestion.length) { params.newquery = result[2].suggestion.termsSuggestion[0].name; } if (result[2] && result[2].brandWay) { params.brandWay = result[2].brandWay; } if (params.query) { // domain = result[0]; // 跳转到品牌商品列表页 // if (domain !== null && !params.shop_id) { // let urlPro = { // from: 'search', // query: params.query // }; // if (req.query.app_type) { // urlPro = _.assign(urlPro, { // app_type: req.query.app_type // }); // } // let url = helpers.urlFormat('', urlPro, domain); // return res.redirect(url); // } // 品类名称为空时跳出 if (!result[1]) { return; } _.forEach(result[1].first, (obj) => { // 精确查一级品类 if (obj === params.query) { isQueryFirstClass = true; return false; } }); _.forEach(result[1].second, (obj) => { // 精确查二级品类 if (obj === params.query) { isQuerySecondClass = true; return false; } }); } else { params.query = ''; } // 搜索是一级品类 if (isQueryFirstClass) { title = '全部' + params.query; } else if (isQuerySecondClass) { // 搜索是二级品类 title = params.query; } else { // 搜索其它内容 if (params.query || params.form) { params.search = { default: params.query === '' ? false : params.query, url: helpers.urlFormat('', null, 'search') }; } title = '搜索'; } title = params.title ? params.title : title; res.render('search/list', { _noLazy: true, module: 'product', page: 'search-list', pageHeader: headerModel.setNav({ navTitle: title }), title: title, goodList: params, firstPageGoods: result[2] || [], suggestion: result[2].suggestion || [], pageFooter: true, shopId: params.shop_id || '' }); }).catch(next); } }).catch(next); }; /** * 搜索主页 */ exports.index = (req, res, next) => { let title = '搜索', uid = req.user.uid || 0; ((render) => { if (_.get(req, 'app.locals.wap.search.removeHotSearch', false)) { render([]); } else { req.ctx(searchModel).getSearchIndex({ gender: req.yoho.channel || 'boys', uid: uid }).then((result) => { render(result); }).catch(next); } })((result) => { res.render('search/index', Object.assign({ module: 'product', page: 'search-index', pageHeader: headerModel.setNav({ navTitle: title }), pageFooter: true, width750: true, search: { defaultTerms: (result && result.defaultTerms && result.defaultTerms.length) ? result.defaultTerms[0].content : '', url: helpers.urlFormat('', null, 'search'), hotTerms: result.hotTerms, wantTerms: result.guessTerms } }, searchProcess.getListSeoData())); }); }; /** * 联动搜索 */ exports.fuzzyDatas = (req, res, next) => { let params = req.query.keyword; req.ctx(searchModel).getFuzzyDatas(params).then((result) => { res.json(result); }).catch(next); }; /** * ajax 商品数据请求 */ exports.search = (req, res, next) => { let allowOrigin = _.get(req, 'headers.origin', null) ? req.headers.origin : req.protocol + '://' + req.headers.host; res.setHeader('Access-Control-Allow-Origin', allowOrigin); res.setHeader('Access-Control-Allow-Credentials', 'true'); let params = Object.assign({}, req.query); let uid = req.user.uid || 0; if (uid) { params.uid = uid; } params.isApp = req.yoho.isApp; params.limit = 24; req.ctx(searchModel).getSearchData(params).then((result) => { if (result.list && result.list.length > 0) { res.render('search/page', { layout: false, new: result.list, suggestion: result.suggestion || [], total: result.total, _noLazy: params.noLazy || false }); } else { res.json(result); } }).catch(next); }; /** * 筛选 */ exports.filter = (req, res, next) => { let allowOrigin = _.get(req, 'headers.origin', null) ? req.headers.origin : req.protocol + '://' + req.headers.host; res.setHeader('Access-Control-Allow-Origin', allowOrigin); res.setHeader('Access-Control-Allow-Credentials', 'true'); let params = {}; let currentUrlParams = {}; // 页面链接伪静态固定参数 if (req.query.isShopList === 'Y') { let shopId; let pathSplitArr = _.compact(_.split(req.query.currentUrl, '/')); let pathParams = _.last(pathSplitArr); if (pathSplitArr.length === 2) { shopId = _.last(_.split(pathParams, '-')); } else { currentUrlParams = listParamsProcess.getParams(pathParams); let shopInfoPath = _.replace(req.query.currentUrl, `/${pathParams}`, ''); shopId = _.last(_.split(shopInfoPath, '-')); } _.assign(req.query, currentUrlParams, {shop_id: shopId}); } else { currentUrlParams = listParamsProcess.getParams(_.last(_.split(req.query.currentUrl, '/'))); } delete req.query.currentUrl; delete req.query.page; _.assign(params, currentUrlParams, req.query); let uid = req.user.uid || 0; if (uid) { params.uid = uid; } req.ctx(searchModel).getFilterData(params).then((result) => { res.render('search/filter', { layout: false, params: params, filter: result }); }).catch(next); }; /** * 搜索品牌下的商品 */ exports.searchBrandGoods = (req, res, next) => { let allowOrigin = _.get(req, 'headers.origin', null) ? req.headers.origin : req.protocol + '://' + req.headers.host; res.setHeader('Access-Control-Allow-Origin', allowOrigin); res.setHeader('Access-Control-Allow-Credentials', 'true'); co(function* () { let goodListApi = yield req.ctx(searchModel).getBrandGoods(req.query); let goodsData = _.get(goodListApi, 'data', []); let goodsList = productProcess.processProductList(_.get(goodListApi, 'data.product_list', [])); if (goodsList) { res.render('search/goods-list-ajax', { layout: false, goodsList: goodsList, _noLazy: req.query.noLazy || false }); } else { res.json(goodsData); } })().catch(next); }; /** * 搜索店铺下的商品 */ exports.searchShopGoods = (req, res, next) => { let allowOrigin = _.get(req, 'headers.origin', null) ? req.headers.origin : req.protocol + '://' + req.headers.host; res.setHeader('Access-Control-Allow-Origin', allowOrigin); res.setHeader('Access-Control-Allow-Credentials', 'true'); co(function* () { let goodListApi = yield req.ctx(searchModel).getShopGoods(req.query); let goodsData = _.get(goodListApi, 'data', []); let goodsList = productProcess.processProductList(_.get(goodListApi, 'data.product_list', [])); if (goodsList) { res.render('search/goods-list-ajax', { layout: false, goodsList: goodsList, _noLazy: req.query.noLazy || false }); } else { res.json(goodsData); } })().catch(next); };