Authored by yyq

Merge branch 'release/newSearch' of git.yoho.cn:fe/yohobuy-node into release/newSearch

@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 'use strict'; 7 'use strict';
8 const mRoot = '../models'; 8 const mRoot = '../models';
9 const search = require(`${mRoot}/search`); 9 const search = require(`${mRoot}/search`);
  10 +const _ = require('lodash');
10 11
11 /** 12 /**
12 * search 首页 13 * search 首页
@@ -25,6 +26,11 @@ exports.index = (req, res, next) => { @@ -25,6 +26,11 @@ exports.index = (req, res, next) => {
25 26
26 search.getSearchData(req.query, req.yoho.channel).then(result => { 27 search.getSearchData(req.query, req.yoho.channel).then(result => {
27 Object.assign(resData, result); 28 Object.assign(resData, result);
  29 +
  30 + if (!_.get(resData, 'search.goods') || !_.get(resData, 'search.goods').length) {
  31 + _.set(resData, 'search.keyWord', req.query.query);
  32 + return res.render('search/no-result', resData);
  33 + }
28 res.render('search/index', resData); 34 res.render('search/index', resData);
29 }).catch(next); 35 }).catch(next);
30 36
@@ -53,7 +53,7 @@ exports.getListData = (params, channel) => { @@ -53,7 +53,7 @@ exports.getListData = (params, channel) => {
53 // 调用接口 53 // 调用接口
54 let apiMethod = [ 54 let apiMethod = [
55 headerModel.requestHeaderData(channel), 55 headerModel.requestHeaderData(channel),
56 - searchApi.getSortList(params), 56 + searchApi.getSortList(Object.assign({}, params, {msort: '', misort: ''})),
57 searchApi.getProductList(searchParams) 57 searchApi.getProductList(searchParams)
58 ]; 58 ];
59 59
@@ -81,9 +81,10 @@ exports.getListData = (params, channel) => { @@ -81,9 +81,10 @@ exports.getListData = (params, channel) => {
81 81
82 // 获取左侧类目数据 82 // 获取左侧类目数据
83 if (result[1].code === 200) { 83 if (result[1].code === 200) {
84 - finalResult.list = Object.assign(searchHandler.handlePathNavData(result[1].data.sort, params, 'sort'), {  
85 - leftContent: searchHandler.handleSortData(result[1].data.sort, params)  
86 - }); 84 + finalResult.list = Object.assign(
  85 + searchHandler.handlePathNavData(result[1].data.sort, params, 'sort', channel), {
  86 + leftContent: searchHandler.handleSortData(result[1].data.sort, params)
  87 + });
87 } 88 }
88 89
89 // 获取商品数据和顶部筛选条件 90 // 获取商品数据和顶部筛选条件
@@ -133,7 +134,7 @@ exports.getListNewData = (params, channel) => { @@ -133,7 +134,7 @@ exports.getListNewData = (params, channel) => {
133 // 调用接口 134 // 调用接口
134 let apiMethod = [ 135 let apiMethod = [
135 headerModel.requestHeaderData(channel), 136 headerModel.requestHeaderData(channel),
136 - searchApi.getSortList(searchParams), 137 + searchApi.getSortList(Object.assign({}, searchParams, {msort: '', misort: ''})),
137 searchApi.getProductList(Object.assign({new: 'Y'}, searchParams)), 138 searchApi.getProductList(Object.assign({new: 'Y'}, searchParams)),
138 searchApi.getWeekNew(params) 139 searchApi.getWeekNew(params)
139 ]; 140 ];
@@ -150,9 +151,10 @@ exports.getListNewData = (params, channel) => { @@ -150,9 +151,10 @@ exports.getListNewData = (params, channel) => {
150 151
151 // 获取左侧类目数据 152 // 获取左侧类目数据
152 if (result[1].code === 200) { 153 if (result[1].code === 200) {
153 - finalResult.list = Object.assign(searchHandler.handlePathNavData(result[1].data.sort, params, 'new'), {  
154 - leftContent: searchHandler.handleSortData(result[1].data.sort, params)  
155 - }); 154 + finalResult.list = Object.assign(
  155 + searchHandler.handlePathNavData(result[1].data.sort, params, 'new', channel), {
  156 + leftContent: searchHandler.handleSortData(result[1].data.sort, params)
  157 + });
156 } 158 }
157 159
158 // 获取商品数据和顶部筛选条件 160 // 获取商品数据和顶部筛选条件
@@ -226,7 +228,7 @@ exports.getBrandData = (params, extra, channel) => { @@ -226,7 +228,7 @@ exports.getBrandData = (params, extra, channel) => {
226 // 调用接口 228 // 调用接口
227 let apiMethod = [ 229 let apiMethod = [
228 headerModel.requestHeaderData(channel), 230 headerModel.requestHeaderData(channel),
229 - searchApi.getSortList(Object.assign({}, params, {brand: extra.brandId})), 231 + searchApi.getSortList(Object.assign({}, params, {brand: extra.brandId, msort: '', misort: ''})),
230 searchApi.getProductList(Object.assign({order: order, brand: extra.brandId}, searchParams)) 232 searchApi.getProductList(Object.assign({order: order, brand: extra.brandId}, searchParams))
231 233
232 ]; 234 ];
@@ -247,7 +249,7 @@ exports.getBrandData = (params, extra, channel) => { @@ -247,7 +249,7 @@ exports.getBrandData = (params, extra, channel) => {
247 if (result[1].code === 200) { 249 if (result[1].code === 200) {
248 Object.assign(finalResult.brand, { 250 Object.assign(finalResult.brand, {
249 leftContent: searchHandler.handleSortData(result[1].data.sort, params) 251 leftContent: searchHandler.handleSortData(result[1].data.sort, params)
250 - }, searchHandler.handlePathNavData(extra, params, 'brand')); 252 + }, searchHandler.handlePathNavData(extra, params, 'brand', channel));
251 } 253 }
252 254
253 // 获取商品数据和顶部筛选条件 255 // 获取商品数据和顶部筛选条件
@@ -443,7 +445,7 @@ exports.getShopData = (shopId, channel, params, shopInfo) => { @@ -443,7 +445,7 @@ exports.getShopData = (shopId, channel, params, shopInfo) => {
443 445
444 Object.assign(finalResult, 446 Object.assign(finalResult,
445 result[0], // 头部数据 447 result[0], // 头部数据
446 - searchHandler.handlePathNavData(shopInfo, params, 'shop') // 面包屑导航 448 + searchHandler.handlePathNavData(shopInfo, params, 'shop', channel) // 面包屑导航
447 ); 449 );
448 450
449 _.set(finalResult, 'headerData.header', true); 451 _.set(finalResult, 'headerData.header', true);
@@ -578,7 +580,7 @@ exports.getShopListData = (channel, params, uid) => { @@ -578,7 +580,7 @@ exports.getShopListData = (channel, params, uid) => {
578 }; 580 };
579 581
580 // 面包屑导航 582 // 面包屑导航
581 - Object.assign(finalResult, searchHandler.handlePathNavData({}, params, 'shop')); 583 + Object.assign(finalResult, searchHandler.handlePathNavData({}, params, 'shop', channel));
582 584
583 // 店铺装修 585 // 店铺装修
584 if (result[1].code === 200) { 586 if (result[1].code === 200) {
@@ -509,7 +509,7 @@ exports.getSaleSpecialData = (id, params, channel) => { @@ -509,7 +509,7 @@ exports.getSaleSpecialData = (id, params, channel) => {
509 }, 509 },
510 apiList = [ 510 apiList = [
511 headerModel.requestHeaderData(channel), 511 headerModel.requestHeaderData(channel),
512 - searchApi.getSortList() 512 + searchApi.getSortList(params)
513 ]; 513 ];
514 514
515 if (special && special.data) { 515 if (special && special.data) {
@@ -16,6 +16,7 @@ const images = require('../../../utils/images.js'); @@ -16,6 +16,7 @@ const images = require('../../../utils/images.js');
16 const cache = global.yoho.cache; 16 const cache = global.yoho.cache;
17 const logger = global.yoho.logger; 17 const logger = global.yoho.logger;
18 const md5 = require('md5'); 18 const md5 = require('md5');
  19 +const config = require('../../../config/common');
19 20
20 const getSortByConditionAsync = (condition) => { 21 const getSortByConditionAsync = (condition) => {
21 return api.get('sortgroup.json', condition); 22 return api.get('sortgroup.json', condition);
@@ -42,6 +43,13 @@ const getSearchCackeKey = params => { @@ -42,6 +43,13 @@ const getSearchCackeKey = params => {
42 return md5(ks.join('_')); 43 return md5(ks.join('_'));
43 }; 44 };
44 45
  46 +const getProductListOrig = (finalParams) => {
  47 +
  48 + return yohoApi.get('', finalParams).then(result => {
  49 + return result;
  50 + });
  51 +};
  52 +
45 /** 53 /**
46 * 获取商品列表 54 * 获取商品列表
47 * @return 55 * @return
@@ -58,39 +66,49 @@ const getProductList = (params) => { @@ -58,39 +66,49 @@ const getProductList = (params) => {
58 66
59 Object.assign(finalParams, params); 67 Object.assign(finalParams, params);
60 68
61 - let cKey = getSearchCackeKey(finalParams); 69 + if (!config.useCache) {
  70 + return getProductListOrig(finalParams);
  71 + } else {
  72 + let cKey = getSearchCackeKey(finalParams);
62 73
63 - return cache.get(cKey).catch().then(cdata => {  
64 - let hasCache = false; 74 + return cache.get(cKey).catch().then(cdata => {
  75 + let hasCache = false;
65 76
66 - if (cdata) { 77 + if (cdata) {
67 78
68 - try {  
69 - cdata = JSON.parse(cdata);  
70 - } catch (e) {  
71 - logger.debug('getProductList cache data parse fail.');  
72 - } 79 + try {
  80 + cdata = JSON.parse(cdata);
  81 + } catch (e) {
  82 + logger.debug('getProductList cache data parse fail.');
  83 + }
73 84
74 - if (cdata.filter && cdata.standard) {  
75 - hasCache = true;  
76 - finalParams.need_filter = 'no'; 85 + if (cdata.filter && cdata.standard) {
  86 + hasCache = true;
  87 + finalParams.need_filter = 'no';
  88 + }
77 } 89 }
78 - }  
79 -  
80 - return yohoApi.get('', finalParams).then(result => {  
81 90
82 - if (hasCache && result && result.data) {  
83 - Object.assign(result.data, cdata);  
84 - } else {  
85 - if (result && result.data && result.data.filter) {  
86 - cache.set(cKey, Object.assign({}, {  
87 - filter: result.data.filter,  
88 - standard: result.data.standard  
89 - }), 3600); 91 + return getProductListOrig(finalParams).then(result => {
  92 + if (hasCache && result && result.data) {
  93 + Object.assign(result.data, cdata);
  94 + } else {
  95 + if (result && result.data && result.data.filter) {
  96 + cache.set(cKey, Object.assign({}, {
  97 + filter: result.data.filter,
  98 + standard: result.data.standard
  99 + }), 3600);
  100 + }
90 } 101 }
91 - }  
92 - return result; 102 +
  103 + return result;
  104 + });
93 }); 105 });
  106 + }
  107 +};
  108 +
  109 +const getSortListOrig = (finalParams) => {
  110 + return yohoApi.get('', finalParams).then(ret => {
  111 + return ret;
94 }); 112 });
95 }; 113 };
96 114
@@ -108,31 +126,34 @@ const getSortList = (params) => { @@ -108,31 +126,34 @@ const getSortList = (params) => {
108 126
109 Object.assign(finalParams, params); 127 Object.assign(finalParams, params);
110 128
111 - let cKey = getSearchCackeKey(finalParams); 129 + if (!config.useCache) {
  130 + return getSortListOrig(finalParams);
  131 + } else {
  132 + let cKey = getSearchCackeKey(finalParams);
112 133
113 - return cache.get(cKey).catch().then(cdata => {  
114 - let cdataObj; 134 + return cache.get(cKey).catch().then(cdata => {
  135 + let cdataObj;
115 136
116 - if (cdata) {  
117 - try {  
118 - cdataObj = JSON.parse(cdata);  
119 - } catch (e) {  
120 - logger.debug('getSortList cache data parse fail.'); 137 + if (cdata) {
  138 + try {
  139 + cdataObj = JSON.parse(cdata);
  140 + } catch (e) {
  141 + logger.debug('getSortList cache data parse fail.');
  142 + }
121 } 143 }
122 - }  
123 -  
124 - if (cdataObj) {  
125 - return cdataObj;  
126 - } else {  
127 - return yohoApi.get('', finalParams).then(ret => {  
128 144
129 - if (ret && ret.code === 200) {  
130 - cache.set(cKey, ret, 3600);  
131 - }  
132 - return ret;  
133 - });  
134 - }  
135 - }); 145 + if (cdataObj) {
  146 + return cdataObj;
  147 + } else {
  148 + return getSortListOrig(finalParams).then(ret => {
  149 + if (ret && ret.code === 200) {
  150 + cache.set(cKey, ret, 3600);
  151 + }
  152 + return ret;
  153 + });
  154 + }
  155 + });
  156 + }
136 }; 157 };
137 158
138 /** 159 /**
@@ -649,14 +649,14 @@ exports.handleFilterData = (origin, params, total) => { @@ -649,14 +649,14 @@ exports.handleFilterData = (origin, params, total) => {
649 649
650 _.forEach(origin.ageLevel, (value) => { 650 _.forEach(origin.ageLevel, (value) => {
651 let ageLevel = { 651 let ageLevel = {
652 - checked: params.ageLevel === value.id || isChecked,  
653 - href: handleFilterUrl(params, {ageLevel: value.id}), 652 + checked: params.age_level === value.id || isChecked,
  653 + href: handleFilterUrl(params, {age_level: value.id}),
654 name: value.name 654 name: value.name
655 }; 655 };
656 656
657 // 处理颜色年龄段数据 657 // 处理颜色年龄段数据
658 if (ageLevel.checked || isChecked) { 658 if (ageLevel.checked || isChecked) {
659 - ageLevel.href = handleFilterUrl(params, null, {ageLevel: value.id}); 659 + ageLevel.href = handleFilterUrl(params, null, {age_level: value.id});
660 dest.checkedConditions.conditions.push(ageLevel); 660 dest.checkedConditions.conditions.push(ageLevel);
661 } 661 }
662 662
@@ -829,11 +829,18 @@ exports.handleFilterDataAll = (data, params) => { @@ -829,11 +829,18 @@ exports.handleFilterDataAll = (data, params) => {
829 * 根据页面设置面包屑导航 829 * 根据页面设置面包屑导航
830 * @type {[type]} 830 * @type {[type]}
831 */ 831 */
832 -exports.handlePathNavData = (data, params, page) => { 832 +exports.handlePathNavData = (data, params, page, channel) => {
  833 +
  834 + let rootName = '首页';
  835 +
  836 + if (channel && _.isString(channel)) {
  837 + rootName = channel.toUpperCase() + rootName;
  838 + }
  839 +
833 let pathNav = [{ 840 let pathNav = [{
834 href: '/', 841 href: '/',
835 - name: '首页', // TODO 从根据cookie获取频道  
836 - pathTitle: '首页' 842 + name: rootName, // '首页', // TODO 从根据cookie获取频道
  843 + pathTitle: rootName // '首页'
837 }]; 844 }];
838 845
839 switch (page) { 846 switch (page) {
@@ -921,6 +928,7 @@ exports.handlePathNavData = (data, params, page) => { @@ -921,6 +928,7 @@ exports.handlePathNavData = (data, params, page) => {
921 * 分页 928 * 分页
922 * @param {[type]} total 总页数 929 * @param {[type]} total 总页数
923 * @param {[type]} params 筛选条件 930 * @param {[type]} params 筛选条件
  931 + * @param {[noNextBtn]} 列表是否有下一页的按钮,如果有则实际查询数比传递参数的少一个,入60 => 59
924 * @return {[type]} [description] 932 * @return {[type]} [description]
925 */ 933 */
926 exports.handlePagerData = (total, params, noNextBtn) => { 934 exports.handlePagerData = (total, params, noNextBtn) => {
@@ -936,7 +944,21 @@ exports.handlePagerData = (total, params, noNextBtn) => { @@ -936,7 +944,21 @@ exports.handlePagerData = (total, params, noNextBtn) => {
936 944
937 let currentPage = parseInt(_.get(params, 'page', 1), 10); // 当前页 945 let currentPage = parseInt(_.get(params, 'page', 1), 10); // 当前页
938 let perPageCount = parseInt(_.get(params, 'limit', true === noNextBtn ? 60 : 59), 10); // 每页商品数 946 let perPageCount = parseInt(_.get(params, 'limit', true === noNextBtn ? 60 : 59), 10); // 每页商品数
939 - let totalPage = parseInt(total / perPageCount, 10) + 1; // 总页数 947 + let totalPage = Math.ceil(total / perPageCount); // 总页数
  948 +
  949 + if (true !== noNextBtn) {
  950 + switch (perPageCount) {
  951 + case 200:
  952 + perPageCount = 199;
  953 + break;
  954 + case 100:
  955 + perPageCount = 99;
  956 + break;
  957 + case 60:
  958 + perPageCount = 59;
  959 + break;
  960 + }
  961 + }
940 962
941 if (currentPage === 1) { 963 if (currentPage === 1) {
942 // 当前页为 1,一定没有上一页 964 // 当前页为 1,一定没有上一页
  1 +<div class="product-search-page product-page yoho-page center-content">
  2 + {{# search}}
  3 + {{> common/path-nav}}
  4 + {{> product/no-result}}
  5 + {{> product/latest-walk}}
  6 + {{/ search}}
  7 +</div>
@@ -395,7 +395,7 @@ exports.processProduct = (productData, options) => { @@ -395,7 +395,7 @@ exports.processProduct = (productData, options) => {
395 } 395 }
396 396
397 result.is_soon_sold_out = (productData.is_soon_sold_out === 'Y'); 397 result.is_soon_sold_out = (productData.is_soon_sold_out === 'Y');
398 - result.url = helpers.urlFormat(`/product/pro_${productData.product_id}_${productData.goods_list[0].goods_id}/${productData.cn_alphabet}.html`, null, 'list'); // eslint-disable-line 398 + result.url = helpers.urlFormat(`/product/pro_${productData.product_id}_${productData.goods_list[0].goods_id}/${productData.cn_alphabet}.html`, null, 'item'); // eslint-disable-line
399 399
400 400
401 if (options.showTags) { 401 if (options.showTags) {