Authored by htoooth

Merge branch 'master' into release/new-product-detail-api

@@ -17,6 +17,16 @@ const shop = (shopId, req, res, next, brandInfo) => { @@ -17,6 +17,16 @@ const shop = (shopId, req, res, next, brandInfo) => {
17 17
18 list.getShopInfo(shopId, req.user.id).then(shopInfo => { 18 list.getShopInfo(shopId, req.user.id).then(shopInfo => {
19 if (+shopInfo.shopTemplateType === 2) { // 经典模板 19 if (+shopInfo.shopTemplateType === 2) { // 经典模板
  20 + let pjax = req.query._pjax;
  21 +
  22 + if (pjax) {
  23 + list.getShopGoodsData(shopId, req.yoho.channel, req.query, shopInfo).then(result => {
  24 + Object.assign(result, {layout: false});
  25 + res.render('list/goods-list', result);
  26 + }).catch(next);
  27 + return;
  28 + }
  29 +
20 list.getShopData(shopId, req.yoho.channel, req.query, shopInfo).then(result => { 30 list.getShopData(shopId, req.yoho.channel, req.query, shopInfo).then(result => {
21 Object.assign(result, { 31 Object.assign(result, {
22 page: 'shop', 32 page: 'shop',
@@ -86,7 +86,7 @@ exports.suggest4Old = (req, res, next) => { @@ -86,7 +86,7 @@ exports.suggest4Old = (req, res, next) => {
86 86
87 exports.serachFilterBrands = (req, res, next) => { 87 exports.serachFilterBrands = (req, res, next) => {
88 search.getBrands4Filter(Object.assign({}, req.query, { 88 search.getBrands4Filter(Object.assign({}, req.query, {
89 - keyword: req.query.query 89 + keyword: req.query.query || ''
90 })).then(result => { 90 })).then(result => {
91 let dest = { 91 let dest = {
92 code: 200, 92 code: 200,
@@ -14,6 +14,7 @@ const helpers = global.yoho.helpers; @@ -14,6 +14,7 @@ const helpers = global.yoho.helpers;
14 const _ = require('lodash'); 14 const _ = require('lodash');
15 15
16 const limitNum = 60; // 商品每页显示数目 16 const limitNum = 60; // 商品每页显示数目
  17 +const needParams = ['query', 'msort', 'misort', 'gender', 'shelveTime'];
17 18
18 // 品牌页folder名称 19 // 品牌页folder名称
19 const brandFolderSeries = '经典系列'; 20 const brandFolderSeries = '经典系列';
@@ -97,9 +98,12 @@ const getListData = (params, channel) => { @@ -97,9 +98,12 @@ const getListData = (params, channel) => {
97 if (result[1].code === 200) { 98 if (result[1].code === 200) {
98 let dps = {}; 99 let dps = {};
99 100
100 - if (params.gender) {  
101 - dps.gender = params.gender;  
102 - } 101 + _.forEach(needParams, (value) => {
  102 + if (params[value]) {
  103 + dps[value] = params[value];
  104 + }
  105 + });
  106 +
103 finalResult.list = Object.assign( 107 finalResult.list = Object.assign(
104 searchHandler.handlePathNavData(result[1].data.sort, params, 'sort', channel), { 108 searchHandler.handlePathNavData(result[1].data.sort, params, 'sort', channel), {
105 leftContent: searchHandler.handleSortData(result[1].data.sort, dps) 109 leftContent: searchHandler.handleSortData(result[1].data.sort, dps)
@@ -168,9 +172,11 @@ const getListNewData = (params, channel) => { @@ -168,9 +172,11 @@ const getListNewData = (params, channel) => {
168 }; 172 };
169 let dps = {}; 173 let dps = {};
170 174
171 - if (params.gender) {  
172 - dps.gender = params.gender;  
173 - } 175 + _.forEach(needParams, (value) => {
  176 + if (params[value]) {
  177 + dps[value] = params[value];
  178 + }
  179 + });
174 180
175 // 获取左侧类目数据 181 // 获取左侧类目数据
176 if (result[1].code === 200) { 182 if (result[1].code === 200) {
@@ -279,9 +285,12 @@ const getBrandData = (params, extra, channel) => { @@ -279,9 +285,12 @@ const getBrandData = (params, extra, channel) => {
279 if (result[1].code === 200) { 285 if (result[1].code === 200) {
280 let dps = {}; 286 let dps = {};
281 287
282 - if (params.gender) {  
283 - dps.gender = params.gender;  
284 - } 288 + _.forEach(needParams, (value) => {
  289 + if (params[value]) {
  290 + dps[value] = params[value];
  291 + }
  292 + });
  293 +
285 Object.assign(finalResult.brand, { 294 Object.assign(finalResult.brand, {
286 leftContent: searchHandler.handleSortData(result[1].data.sort, dps) 295 leftContent: searchHandler.handleSortData(result[1].data.sort, dps)
287 }, searchHandler.handlePathNavData(extra, params, 'brand', channel)); 296 }, searchHandler.handlePathNavData(extra, params, 'brand', channel));
@@ -663,6 +672,54 @@ const getShopData = (shopId, channel, params, shopInfo) => { @@ -663,6 +672,54 @@ const getShopData = (shopId, channel, params, shopInfo) => {
663 }); 672 });
664 }; 673 };
665 674
  675 +/**
  676 + * 获取店铺商品数据
  677 + */
  678 +const getShopGoodsData = (shopId, channel, params) => {
  679 + let gender = _getGender(channel);
  680 + let resData = {};
  681 +
  682 + _.unset(params, '_pjax');
  683 + return Promise.all([
  684 + searchApi.getProductList(Object.assign({
  685 + shop_id: shopId
  686 + }, params)), // 搜索店铺商品
  687 + searchApi.getShopBrands(shopId) // 店铺品牌数据
  688 + ]).then(result => {
  689 + // 获取商品数据和顶部筛选条件
  690 + if (result[0].code === 200) {
  691 + Object.assign(resData, {
  692 + sort: searchHandler.handleOptsData(params, _.get(result[0], 'data.total', 0)),
  693 + list: productProcess.processProductList(_.get(result[0], 'data.product_list', []), {
  694 + newCoverSort: true,
  695 + showDiscount: false,
  696 + gender: gender
  697 + })
  698 + });
  699 + _.set(resData, 'sort.newPage', true); // 启用新的分页导航
  700 + }
  701 +
  702 + let shopBrandIds = []; // 店铺的所有品牌id
  703 +
  704 + if (result[1].code === 200 && result[1].data) {
  705 + _.forEach(result[1].data, value => {
  706 + shopBrandIds.push(value.brand_id);
  707 + });
  708 + }
  709 +
  710 + // 根据品牌获取分类 (腾讯云测试没有该接口,暂时不调用分类)
  711 + return searchApi.getSortList({brand: shopBrandIds}).then(subRes => {
  712 + if (subRes.code === 200) {
  713 + let groupSort = _.get(subRes, 'data.sort', []);
  714 +
  715 + Object.assign(resData, searchHandler.setShopSort(groupSort, params));
  716 + }
  717 +
  718 + return resData;
  719 + });
  720 + });
  721 +};
  722 +
666 const getShopListData = (channel, params, uid) => { 723 const getShopListData = (channel, params, uid) => {
667 let gender = _getGender(channel), 724 let gender = _getGender(channel),
668 shopId = params.shopId, 725 shopId = params.shopId,
@@ -732,7 +789,8 @@ const getShopListData = (channel, params, uid) => { @@ -732,7 +789,8 @@ const getShopListData = (channel, params, uid) => {
732 goods: productProcess.processProductList(goodsList, { 789 goods: productProcess.processProductList(goodsList, {
733 newCoverSort: true, 790 newCoverSort: true,
734 showDiscount: false, 791 showDiscount: false,
735 - gender: _getGender(channel) 792 + gender: _getGender(channel),
  793 + query: params.query
736 }), 794 }),
737 footPager: {tip: tip} 795 footPager: {tip: tip}
738 }); 796 });
@@ -803,7 +861,7 @@ const getBaseShopData = (params, extra, channel, shopId) => { @@ -803,7 +861,7 @@ const getBaseShopData = (params, extra, channel, shopId) => {
803 861
804 if (result[1].code === 200) { 862 if (result[1].code === 200) {
805 let data = result[1].data || {}, 863 let data = result[1].data || {},
806 - decorator = shopHandler.getShopDecorator(data, {}, shopId); 864 + decorator = shopHandler.getShopDecorator(data, {}, shopId, true);
807 865
808 Object.assign(decorator.shopTopBannerBase, { 866 Object.assign(decorator.shopTopBannerBase, {
809 shopId: shopId, 867 shopId: shopId,
@@ -813,6 +871,10 @@ const getBaseShopData = (params, extra, channel, shopId) => { @@ -813,6 +871,10 @@ const getBaseShopData = (params, extra, channel, shopId) => {
813 }); 871 });
814 _.set(resData, 'brand.shopBanner', decorator.shopTopBannerBase); 872 _.set(resData, 'brand.shopBanner', decorator.shopTopBannerBase);
815 _.unset(resData, 'brand.brandBanner'); 873 _.unset(resData, 'brand.brandBanner');
  874 +
  875 + if (decorator.signboard) {
  876 + _.set(resData, 'brand.signboard', decorator.signboard);
  877 + }
816 } 878 }
817 879
818 if (result[2].code === 200) { 880 if (result[2].code === 200) {
@@ -839,6 +901,7 @@ module.exports = { @@ -839,6 +901,7 @@ module.exports = {
839 getAdnav, 901 getAdnav,
840 getShopInfo, 902 getShopInfo,
841 getShopData, 903 getShopData,
  904 + getShopGoodsData,
842 getShopListData, 905 getShopListData,
843 getBaseShopData 906 getBaseShopData
844 }; 907 };
@@ -31,7 +31,6 @@ const yhChannel = { @@ -31,7 +31,6 @@ const yhChannel = {
31 * @return {[type]} [description] 31 * @return {[type]} [description]
32 */ 32 */
33 exports.getSaleGoodsList = (params) => { 33 exports.getSaleGoodsList = (params) => {
34 -  
35 let finalParams = { 34 let finalParams = {
36 method: 'app.search.sales', 35 method: 'app.search.sales',
37 limit: 60, 36 limit: 60,
@@ -39,13 +38,11 @@ exports.getSaleGoodsList = (params) => { @@ -39,13 +38,11 @@ exports.getSaleGoodsList = (params) => {
39 productSize: '384x511' 38 productSize: '384x511'
40 }; 39 };
41 40
42 - Object.assign(finalParams, params);  
43 -  
44 - if (finalParams.order === '') {  
45 - delete finalParams.order; 41 + if (params.channel) {
  42 + finalParams.yh_channel = yhChannel[params.channel].channel;
46 } 43 }
47 44
48 - return api.get('', finalParams); 45 + return api.get('', Object.assign(finalParams, params));
49 }; 46 };
50 47
51 /** 48 /**
@@ -362,15 +362,18 @@ exports.getSaleDiscountData = (params, channel) => { @@ -362,15 +362,18 @@ exports.getSaleDiscountData = (params, channel) => {
362 }; 362 };
363 } 363 }
364 } 364 }
  365 +
  366 + // 这里把 channel 全都处理掉,因为根据channel查小分类,而传入商品池时,不需要
365 return api.all([ 367 return api.all([
366 saleApi.getSaleGoodsList({ 368 saleApi.getSaleGoodsList({
367 - channel: channel, 369 + channel: null,
368 saleType: '3', 370 saleType: '3',
369 limit: '1', 371 limit: '1',
370 - productPool: result[1].data[0].product_pool,  
371 - order: '' 372 + productPool: result[1].data[0].product_pool
372 }), 373 }),
373 - saleApi.getSaleGoodsList(Object.assign(params, {productPool: result[1].data[0].product_pool})) 374 + saleApi.getSaleGoodsList(Object.assign(_.update(params, 'channel', null), {
  375 + productPool: result[1].data[0].product_pool
  376 + }))
374 ]).then(subResult => { 377 ]).then(subResult => {
375 378
376 // 处理分页等筛选信息 379 // 处理分页等筛选信息
@@ -9,6 +9,12 @@ @@ -9,6 +9,12 @@
9 const _ = require('lodash'); 9 const _ = require('lodash');
10 const helpers = global.yoho.helpers; 10 const helpers = global.yoho.helpers;
11 const queryString = require('querystring'); 11 const queryString = require('querystring');
  12 +const indexUrl = {
  13 + boys: helpers.urlFormat('/'),
  14 + girls: helpers.urlFormat('/woman'),
  15 + kids: helpers.urlFormat('/kids'),
  16 + lifestyle: helpers.urlFormat('/lifestyle')
  17 +};
12 18
13 // 打折、新品、限量 19 // 打折、新品、限量
14 const checksName = { 20 const checksName = {
@@ -93,7 +99,7 @@ const handleBrandCheckedData = (params, origin) => { @@ -93,7 +99,7 @@ const handleBrandCheckedData = (params, origin) => {
93 if (!_.isEmpty(origin)) { 99 if (!_.isEmpty(origin)) {
94 _.forEach(origin, (value) => { 100 _.forEach(origin, (value) => {
95 if (typeof _.find(intBrands, o => { 101 if (typeof _.find(intBrands, o => {
96 - return _.isEqual(o, value.id); 102 + return _.isEqual(o, +value.id);
97 }) !== 'undefined') { 103 }) !== 'undefined') {
98 let checked = { 104 let checked = {
99 name: value.name 105 name: value.name
@@ -198,13 +204,11 @@ const formatterFilterBrands = (source, paramBrand, params) => { @@ -198,13 +204,11 @@ const formatterFilterBrands = (source, paramBrand, params) => {
198 index: '0-9', 204 index: '0-9',
199 name: '0~9' 205 name: '0~9'
200 }], 206 }],
201 - selectedBrands: [],  
202 - showMore: true,  
203 - showMulti: true 207 + selectedBrands: []
204 }; 208 };
205 209
206 210
207 - // 品牌索引数据处理 211 + // 品牌索引数据处理
208 for (let i = 65; i < 91; i++) { 212 for (let i = 65; i < 91; i++) {
209 dbrand.brandIndex.push({ 213 dbrand.brandIndex.push({
210 index: String.fromCharCode(i).toLowerCase(), 214 index: String.fromCharCode(i).toLowerCase(),
@@ -212,8 +216,8 @@ const formatterFilterBrands = (source, paramBrand, params) => { @@ -212,8 +216,8 @@ const formatterFilterBrands = (source, paramBrand, params) => {
212 }); 216 });
213 } 217 }
214 218
215 - // 品牌数据处理  
216 - // 分拆品牌参数 219 + // 品牌数据处理
  220 + // 分拆品牌参数
217 let brands = _.split(params.brand, ','); 221 let brands = _.split(params.brand, ',');
218 let intBrands = []; 222 let intBrands = [];
219 223
@@ -227,7 +231,7 @@ const formatterFilterBrands = (source, paramBrand, params) => { @@ -227,7 +231,7 @@ const formatterFilterBrands = (source, paramBrand, params) => {
227 _.forEach(source, function(value) { 231 _.forEach(source, function(value) {
228 let brand = { 232 let brand = {
229 checked: (typeof _.find(intBrands, o => { 233 checked: (typeof _.find(intBrands, o => {
230 - return _.isEqual(o, value.id); 234 + return _.isEqual(o, +value.id);
231 }) !== 'undefined'), 235 }) !== 'undefined'),
232 href: handleFilterUrl(params, {brand: value.id}), 236 href: handleFilterUrl(params, {brand: value.id}),
233 name: value.brand_name, 237 name: value.brand_name,
@@ -251,6 +255,13 @@ const formatterFilterBrands = (source, paramBrand, params) => { @@ -251,6 +255,13 @@ const formatterFilterBrands = (source, paramBrand, params) => {
251 count++; 255 count++;
252 }); 256 });
253 257
  258 + if (dbrand.default.length > 9) {
  259 + Object.assign(dbrand, {
  260 + showMore: true,
  261 + showMulti: true
  262 + });
  263 + }
  264 +
254 if (paramBrand) { 265 if (paramBrand) {
255 _.forEach(paramBrand, value => { 266 _.forEach(paramBrand, value => {
256 let brand = { 267 let brand = {
@@ -264,11 +275,11 @@ const formatterFilterBrands = (source, paramBrand, params) => { @@ -264,11 +275,11 @@ const formatterFilterBrands = (source, paramBrand, params) => {
264 }); 275 });
265 } 276 }
266 277
267 - // 没有品牌的情况下将 brand 设置为 false,前端不显示 品牌 278 + // 没有品牌的情况下将 brand 设置为 false,前端不显示 品牌
268 if (_.size(dbrand.brandsShow) <= 0) { 279 if (_.size(dbrand.brandsShow) <= 0) {
269 return false; 280 return false;
270 } else { 281 } else {
271 - // 品牌排序 282 + // 品牌排序
272 dbrand.brandsShow = _.sortBy(dbrand.brandsShow, o => { 283 dbrand.brandsShow = _.sortBy(dbrand.brandsShow, o => {
273 return o.index; 284 return o.index;
274 }); 285 });
@@ -532,7 +543,10 @@ exports.setShopSort = (data, params) => { @@ -532,7 +543,10 @@ exports.setShopSort = (data, params) => {
532 }); 543 });
533 544
534 if (list.length) { 545 if (list.length) {
535 - _.set(resData, 'goodsMenu.menuList', list); 546 + resData.goodsMenu = {
  547 + menuList: list,
  548 + url: `/product/shoplist?navBar=1&shopId=${params.shopId}`
  549 + };
536 } 550 }
537 } 551 }
538 552
@@ -548,19 +562,6 @@ exports.setShopSort = (data, params) => { @@ -548,19 +562,6 @@ exports.setShopSort = (data, params) => {
548 exports.handleFilterData = (origin, params, total) => { 562 exports.handleFilterData = (origin, params, total) => {
549 let dest = { 563 let dest = {
550 ageLevel: [], 564 ageLevel: [],
551 - brand: {  
552 - default: [],  
553 - brandsShow: [],  
554 - brandIndex: [{  
555 - index: 'all',  
556 - name: '全部'  
557 - }, {  
558 - index: '0-9',  
559 - name: '0~9'  
560 - }],  
561 - showMore: true,  
562 - showMulti: true  
563 - },  
564 price: [], 565 price: [],
565 gender: [], 566 gender: [],
566 color: [], 567 color: [],
@@ -867,11 +868,12 @@ exports.handleSeniorFilterData = (data, params) => { @@ -867,11 +868,12 @@ exports.handleSeniorFilterData = (data, params) => {
867 }; 868 };
868 869
869 exports.handleFilterDataAll = (data, qs) => { 870 exports.handleFilterDataAll = (data, qs) => {
  871 + let destFilter = {};
870 let params = _.cloneDeep(qs); 872 let params = _.cloneDeep(qs);
871 873
872 _.unset(params, 'page'); // 去除筛选项page 874 _.unset(params, 'page'); // 去除筛选项page
873 875
874 - let baseFilter = this.handleFilterData(data.filter, params, data.total); 876 + let baseFilter = this.handleFilterData(_.get(data, 'filter', {}), params, data.total);
875 let seniorFilter = this.handleSeniorFilterData({ 877 let seniorFilter = this.handleSeniorFilterData({
876 style: _.get(data, 'filter.style', []), 878 style: _.get(data, 'filter.style', []),
877 standard: _.get(data, 'standard', []) 879 standard: _.get(data, 'standard', [])
@@ -880,12 +882,9 @@ exports.handleFilterDataAll = (data, qs) => { @@ -880,12 +882,9 @@ exports.handleFilterDataAll = (data, qs) => {
880 let conditions = _.union(_.get(baseFilter, 'checkedConditions.conditions'), 882 let conditions = _.union(_.get(baseFilter, 'checkedConditions.conditions'),
881 _.get(seniorFilter, 'checkedConditions.conditions')); 883 _.get(seniorFilter, 'checkedConditions.conditions'));
882 884
883 - let destFilter = Object.assign({}, seniorFilter, baseFilter); 885 + Object.assign(destFilter, seniorFilter, baseFilter);
884 886
885 - if (!destFilter.checkedConditions) {  
886 - destFilter.checkedConditions = {};  
887 - }  
888 - destFilter.checkedConditions.conditions = conditions; 887 + _.set(destFilter, 'checkedConditions.conditions', conditions);
889 888
890 return destFilter; 889 return destFilter;
891 }; 890 };
@@ -903,7 +902,7 @@ exports.handlePathNavData = (data, params, page, channel) => { @@ -903,7 +902,7 @@ exports.handlePathNavData = (data, params, page, channel) => {
903 } 902 }
904 903
905 let pathNav = [{ 904 let pathNav = [{
906 - href: '/', 905 + href: indexUrl[channel],
907 name: rootName, // '首页', // TODO 从根据cookie获取频道 906 name: rootName, // '首页', // TODO 从根据cookie获取频道
908 pathTitle: rootName // '首页' 907 pathTitle: rootName // '首页'
909 }]; 908 }];
@@ -1131,7 +1130,7 @@ exports.handleSortIntro = (data) => { @@ -1131,7 +1130,7 @@ exports.handleSortIntro = (data) => {
1131 _.forEach(data.keyword, function(value) { 1130 _.forEach(data.keyword, function(value) {
1132 sortIntro.keyEntry.push({ 1131 sortIntro.keyEntry.push({
1133 name: value.word, 1132 name: value.word,
1134 - url: value.url 1133 + url: value.url.replace(/(parameter_)(\d+)=(\d+)/, (match, p1, p2, p3) => `standard=${p2}_${p3}`)
1135 }); 1134 });
1136 }); 1135 });
1137 1136
@@ -1258,7 +1257,7 @@ exports.handleNextPage = (params, total) => { @@ -1258,7 +1257,7 @@ exports.handleNextPage = (params, total) => {
1258 1257
1259 let href; 1258 let href;
1260 let currentPage = parseInt((_.isEmpty(params.page) ? 1 : params.page), 10); // 当前页 1259 let currentPage = parseInt((_.isEmpty(params.page) ? 1 : params.page), 10); // 当前页
1261 - let perPageCount = parseInt((_.isEmpty(params.limit) ? 60 : params.limit), 10); // 每页商品数 1260 + let perPageCount = parseInt((_.isEmpty(params.limit) ? 60 : params.limit) - 1, 10); // 每页商品数
1262 let totalPage = parseInt(total / perPageCount, 10) + 1; // 总页数 1261 let totalPage = parseInt(total / perPageCount, 10) + 1; // 总页数
1263 1262
1264 if (currentPage === totalPage) { 1263 if (currentPage === totalPage) {
@@ -1270,7 +1269,7 @@ exports.handleNextPage = (params, total) => { @@ -1270,7 +1269,7 @@ exports.handleNextPage = (params, total) => {
1270 return { 1269 return {
1271 href: href, 1270 href: href,
1272 src: '//img10.static.yhbimg.com/product/2014/01/15/11/01fa01614784f6239760f1b749663016f1.jpg?' + 1271 src: '//img10.static.yhbimg.com/product/2014/01/15/11/01fa01614784f6239760f1b749663016f1.jpg?' +
1273 - 'imageMogr2/thumbnail/235x314/extent/235x314/background/d2hpdGU=/position/center/quality/90' 1272 + 'imageMogr2/thumbnail/235x314/extent/235x314/background/d2hpdGU=/position/center/quality/90'
1274 }; 1273 };
1275 }; 1274 };
1276 1275
@@ -1393,12 +1392,12 @@ exports.getBrandSeo = (channel, brandInfo) => { @@ -1393,12 +1392,12 @@ exports.getBrandSeo = (channel, brandInfo) => {
1393 bbc = b + bcn + c, 1392 bbc = b + bcn + c,
1394 title = bb || b || '', 1393 title = bb || b || '',
1395 keywords = [b ? b + ',' : '', 1394 keywords = [b ? b + ',' : '',
1396 - ((b && bcn) ? (bb + ',') : ''),  
1397 - bc || '',  
1398 - '品牌'].join(''), 1395 + ((b && bcn) ? (bb + ',') : ''),
  1396 + bc || '',
  1397 + '品牌'].join(''),
1399 desc = [b + '正品网购。', 1398 desc = [b + '正品网购。',
1400 - bbc || '',  
1401 - '品牌官方授权!YOHO! 有货中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。'].join(''); 1399 + bbc || '',
  1400 + '品牌官方授权!YOHO! 有货中国最大的潮流商品购物网站。100%品牌正品保证,支持货到付款。'].join('');
1402 1401
1403 title += (title ? (title + '|') : '') + c + '品牌|YOHO!BUY 有货 100%正品保证'; 1402 title += (title ? (title + '|') : '') + c + '品牌|YOHO!BUY 有货 100%正品保证';
1404 1403
@@ -11,6 +11,7 @@ const headerModel = require('../../../doraemon/models/header'); @@ -11,6 +11,7 @@ const headerModel = require('../../../doraemon/models/header');
11 const productProcess = require(`${utils}/product-process`); 11 const productProcess = require(`${utils}/product-process`);
12 const searchHandler = require('./search-handler'); 12 const searchHandler = require('./search-handler');
13 const _ = require('lodash'); 13 const _ = require('lodash');
  14 +const needParams = ['query', 'msort', 'misort'];
14 15
15 /** 16 /**
16 * 获取搜索数据 17 * 获取搜索数据
@@ -46,9 +47,12 @@ exports.getSearchData = (params, channel) => { @@ -46,9 +47,12 @@ exports.getSearchData = (params, channel) => {
46 if (result[1].code === 200) { 47 if (result[1].code === 200) {
47 let dps = {}; 48 let dps = {};
48 49
49 - if (params.query) {  
50 - dps.query = params.query;  
51 - } 50 + _.forEach(needParams, (value) => {
  51 + if (params[value]) {
  52 + dps[value] = params[value];
  53 + }
  54 + });
  55 +
52 finalResult.search = { 56 finalResult.search = {
53 leftContent: searchHandler.handleSortData(result[1].data.sort, dps) 57 leftContent: searchHandler.handleSortData(result[1].data.sort, dps)
54 }; 58 };
@@ -104,6 +108,11 @@ exports.getBrands4Filter = (params) => { @@ -104,6 +108,11 @@ exports.getBrands4Filter = (params) => {
104 nparams.price = nmp.join(','); 108 nparams.price = nmp.join(',');
105 } 109 }
106 110
  111 + // 生成路径包含callback 导致多次调用多个 callback问题
  112 + if (params && params.callback) {
  113 + delete params.callback;
  114 + }
  115 +
107 return searchApi.getBrands4Filter(Object.assign({}, params, nparams)).then(result => { 116 return searchApi.getBrands4Filter(Object.assign({}, params, nparams)).then(result => {
108 117
109 let dest = []; 118 let dest = [];
@@ -5,6 +5,8 @@ @@ -5,6 +5,8 @@
5 5
6 'use strict'; 6 'use strict';
7 const _ = require('lodash'); 7 const _ = require('lodash');
  8 +const Fn = require('lodash/fp');
  9 +const qs = require('queryString');
8 10
9 const helpers = global.yoho.helpers; 11 const helpers = global.yoho.helpers;
10 12
@@ -68,32 +70,34 @@ const hotProducts = (data) => { @@ -68,32 +70,34 @@ const hotProducts = (data) => {
68 */ 70 */
69 const goodsTabBar = (data, shopId) => { 71 const goodsTabBar = (data, shopId) => {
70 let dest = { 72 let dest = {
71 - hot: [],  
72 - new: []  
73 - },  
74 - more = {name: 'MORE', href: shopListUrl + '?shopId=' + shopId};  
75 - 73 + hot: [],
  74 + new: []
  75 + };
76 76
77 - _.forEach(data.hot, (value) => {  
78 - if (value.url) { 77 + _.forEach(_.sortBy(data.hot, o => {
  78 + return -o.position;
  79 + }), (value) => {
  80 + if (value.url && value.position) {
79 dest.hot.push({ 81 dest.hot.push({
80 name: value.name, 82 name: value.name,
81 - href: value.url 83 + url: value.url
82 }); 84 });
83 } 85 }
84 86
85 }); 87 });
86 88
87 - _.forEach(data.new, (value) => {  
88 - if (value.url) { 89 + _.forEach(_.sortBy(data.new, o => {
  90 + return -o.position;
  91 + }), (value) => {
  92 + if (value.url && value.position) {
89 dest.new.push({ 93 dest.new.push({
90 name: value.name, 94 name: value.name,
91 - href: value.url 95 + url: value.url
92 }); 96 });
93 } 97 }
94 }); 98 });
95 - dest.hot.push(more);  
96 - dest.new.push(more); 99 + dest.hot.push({name: 'MORE', url: `${shopListUrl}?navBar=2&order=s_n_desc&shopId=${shopId}`});
  100 + dest.new.push({name: 'MORE', url: `${shopListUrl}?navBar=3&order=s_t_desc&shopId=${shopId}`});
97 return dest; 101 return dest;
98 }; 102 };
99 103
@@ -144,17 +148,24 @@ const navigationBar = (data, shopId) => { @@ -144,17 +148,24 @@ const navigationBar = (data, shopId) => {
144 }, 148 },
145 { 149 {
146 name: '人气单品', 150 name: '人气单品',
147 - url: `${shopListUrl}/?navBar=2&shopId=${shopId}` 151 + url: `${shopListUrl}/?navBar=2&order=s_n_desc&shopId=${shopId}`
148 }, 152 },
149 { 153 {
150 name: '新品上架', 154 name: '新品上架',
151 - url: `${shopListUrl}/?navBar=3&shopId=${shopId}` 155 + url: `${shopListUrl}/?navBar=3&order=s_t_desc&shopId=${shopId}`
152 } 156 }
153 ]; 157 ];
154 158
155 - return {navigationBar: _.union(shopNav, _.filter(data, (value) => {  
156 - return value.url;  
157 - }))}; 159 + _.forEach(data, (value) => {
  160 + if (value.url) {
  161 + shopNav.push({
  162 + name: value.name,
  163 + url: `${value.url}&navBar=${shopNav.length}`
  164 + });
  165 + }
  166 + });
  167 +
  168 + return {navigationBar: shopNav};
158 }; 169 };
159 170
160 /** 171 /**
@@ -166,9 +177,10 @@ const largeSlideImg = (data) => { @@ -166,9 +177,10 @@ const largeSlideImg = (data) => {
166 let dest = []; 177 let dest = [];
167 178
168 _.forEach(data, (value) => { 179 _.forEach(data, (value) => {
  180 + value = _.get(value, 'data[0]', {});
169 dest.push({ 181 dest.push({
170 - img: value.data[0].src,  
171 - url: helpers.urlFormat(value.data[0].url) 182 + img: value.src,
  183 + url: value.url
172 }); 184 });
173 }); 185 });
174 186
@@ -184,9 +196,10 @@ const oneRowTwoColImages = (data) => { @@ -184,9 +196,10 @@ const oneRowTwoColImages = (data) => {
184 let dest = []; 196 let dest = [];
185 197
186 _.forEach(data, (value) => { 198 _.forEach(data, (value) => {
  199 + value = _.get(value, 'data[0]', {});
187 dest.push({ 200 dest.push({
188 - img: value.data[0].src,  
189 - url: helpers.urlFormat(value.data[0].url) 201 + img: value.src,
  202 + url: value.url
190 }); 203 });
191 }); 204 });
192 return {oneRowTwoColImages: dest}; 205 return {oneRowTwoColImages: dest};
@@ -206,7 +219,7 @@ const recommend = (data) => { @@ -206,7 +219,7 @@ const recommend = (data) => {
206 name: value.name, 219 name: value.name,
207 img: value.src, 220 img: value.src,
208 title: value.title, 221 title: value.title,
209 - url: helpers.urlFormat(value.url) 222 + url: value.url
210 }); 223 });
211 }); 224 });
212 225
@@ -277,62 +290,130 @@ const hotRecommend = (data) => { @@ -277,62 +290,130 @@ const hotRecommend = (data) => {
277 }; 290 };
278 291
279 /** 292 /**
280 - * 店铺装修楼层数据  
281 - * @param data 装修数据  
282 - * @returns {{}} 293 + * 水牌
283 */ 294 */
284 -exports.getShopDecorator = (data, params, shopId) => {  
285 - let dest = {  
286 - newArrivel: {},  
287 - hotSingle: {} 295 +const signboard = (data) => {
  296 + let list = [];
  297 +
  298 + _.forEach(data, value => {
  299 + if (value.data) {
  300 + _.forEach(value.data, val => {
  301 + list.push({
  302 + img: helpers.image(val.src, 160, 240),
  303 + url: val.url
  304 + });
  305 + });
  306 + }
  307 + });
  308 + return {
  309 + title: _.get(list, '[0].title', ''),
  310 + list: list
288 }; 311 };
  312 +};
289 313
290 - _.forEach(data.list, (value) => {  
291 - let info = JSON.parse(value.resource_data);  
292 - let tabBar;  
293 -  
294 - switch (value.resource_name) {  
295 - case 'signboard':  
296 - break;  
297 - case 'newProducts':  
298 - Object.assign(dest.newArrivel, newProducts(info));  
299 - break;  
300 - case 'hotProducts':  
301 - Object.assign(dest.hotSingle, hotProducts(info));  
302 - break;  
303 - case 'goodsTabBar':  
304 - tabBar = goodsTabBar(info);  
305 - Object.assign(dest.newArrivel, {navs: tabBar.new});  
306 - Object.assign(dest.hotSingle, {navs: tabBar.hot});  
307 - break;  
308 - case 'shopTopBanner':  
309 - Object.assign(dest, shopTopBanner(info));  
310 - break;  
311 - case 'shopTopBanner_base':  
312 - Object.assign(dest, shopTopBannerBase(info));  
313 - break;  
314 - case 'navigationBar':  
315 - Object.assign(dest, navigationBar(info, shopId));  
316 - break;  
317 - case 'largeSlideImg':  
318 - Object.assign(dest, largeSlideImg(info));  
319 - break;  
320 - case 'oneRowTwoColImages':  
321 - Object.assign(dest, oneRowTwoColImages(info, shopId));  
322 - break;  
323 - case 'recommend':  
324 - Object.assign(dest, recommend(info, shopId));  
325 - break;  
326 - case 'brandBrowse':  
327 - Object.assign(dest, brandBrowse(info, params));  
328 - break;  
329 - case 'hotRecommend':  
330 - Object.assign(dest, hotRecommend(info));  
331 - break;  
332 - default:  
333 - break; 314 +
  315 +// 销售类目
  316 +const _handleSaleCategory = (shopId, resourceObj) => {
  317 + const thisShop = (categoryId) => shopListUrl + '?' + qs.stringify({
  318 + productPool: categoryId,
  319 + shopId: shopId,
  320 + navBar: -1
  321 + });
  322 +
  323 + let hasSaleCategory = Fn.pipe(Fn.prop('linkType'), Fn.eq('1'));
  324 +
  325 + if (hasSaleCategory(resourceObj)) {
  326 + return Object.assign(resourceObj, {url: thisShop(resourceObj.categoryId)});
  327 + }
  328 +
  329 + _(resourceObj).forEach((value) => {
  330 + if (_.has(value, 'data')) {
  331 + _.forEach(value.data, (it) => {
  332 + if (hasSaleCategory(it)) {
  333 + Object.assign(it, {url: thisShop(it.categoryId)});
  334 + }
  335 + });
  336 + }
  337 +
  338 + if (hasSaleCategory(value)) {
  339 + Object.assign(value, {url: thisShop(value.categoryId)});
334 } 340 }
335 }); 341 });
336 342
  343 + return resourceObj;
  344 +};
  345 +
  346 +/**
  347 + * 店铺装修楼层数据
  348 + * @param data 装修数据
  349 + * @returns {{}}
  350 + */
  351 +exports.getShopDecorator = (data, params, shopId, base) => {
  352 + let dest = {};
  353 +
  354 + if (base) {
  355 + _.forEach(data.list, (value) => {
  356 + let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId))(value.resource_data);
  357 +
  358 + switch (value.resource_name) {
  359 + case 'signboard':
  360 + dest.signboard = signboard(info);
  361 + break;
  362 + case 'shopTopBanner_base':
  363 + Object.assign(dest, shopTopBannerBase(info));
  364 + break;
  365 + default:
  366 + break;
  367 + }
  368 + });
  369 + } else {
  370 + Object.assign(dest, {
  371 + newArrivel: {},
  372 + hotSingle: {}
  373 + });
  374 +
  375 + _.forEach(data.list, (value) => {
  376 + let info = Fn.pipe(JSON.parse, _.partial(_handleSaleCategory, shopId))(value.resource_data);
  377 + let tabBar;
  378 +
  379 + switch (value.resource_name) {
  380 + case 'newProducts':
  381 + Object.assign(dest.newArrivel, newProducts(info));
  382 + break;
  383 + case 'hotProducts':
  384 + Object.assign(dest.hotSingle, hotProducts(info));
  385 + break;
  386 + case 'goodsTabBar':
  387 + tabBar = goodsTabBar(info, shopId);
  388 + Object.assign(dest.newArrivel, {navs: tabBar.new});
  389 + Object.assign(dest.hotSingle, {navs: tabBar.hot});
  390 + break;
  391 + case 'shopTopBanner':
  392 + Object.assign(dest, shopTopBanner(info));
  393 + break;
  394 + case 'navigationBar':
  395 + Object.assign(dest, navigationBar(info, shopId));
  396 + break;
  397 + case 'largeSlideImg':
  398 + Object.assign(dest, largeSlideImg(info, shopId));
  399 + break;
  400 + case 'oneRowTwoColImages':
  401 + Object.assign(dest, oneRowTwoColImages(info, shopId));
  402 + break;
  403 + case 'recommend':
  404 + Object.assign(dest, recommend(info, shopId));
  405 + break;
  406 + case 'brandBrowse':
  407 + Object.assign(dest, brandBrowse(info, params));
  408 + break;
  409 + case 'hotRecommend':
  410 + Object.assign(dest, hotRecommend(info));
  411 + break;
  412 + default:
  413 + break;
  414 + }
  415 + });
  416 + }
  417 +
337 return dest; 418 return dest;
338 }; 419 };
@@ -77,9 +77,9 @@ @@ -77,9 +77,9 @@
77 {{#for_stu}}<span class="stu-tag"> 学生价 </span>{{/for_stu}} 77 {{#for_stu}}<span class="stu-tag"> 学生价 </span>{{/for_stu}}
78 </p> 78 </p>
79 <div class="hideList hide"> 79 <div class="hideList hide">
80 - {{#goodsList}}  
81 - <li data-src="{{image images_url 280 374}}" data-url="{{../url}}"></li>  
82 - {{/goodsList}} 80 + {{#goods_list}}
  81 + <li data-src="{{image images_url 280 374}}" data-url="{{../url}}" data-status="{{status}}"></li>
  82 + {{/goods_list}}
83 </div> 83 </div>
84 </div> 84 </div>
85 </div> 85 </div>
1 { 1 {
2 "name": "yohobuy-node", 2 "name": "yohobuy-node",
3 - "version": "5.0.0", 3 + "version": "5.0.2",
4 "private": true, 4 "private": true,
5 "description": "A New Yohobuy Project With Express", 5 "description": "A New Yohobuy Project With Express",
6 "repository": { 6 "repository": {
@@ -104,7 +104,10 @@ exports.init = function(num) { @@ -104,7 +104,10 @@ exports.init = function(num) {
104 event.target.find('.hideList > li').each(function() { 104 event.target.find('.hideList > li').each(function() {
105 pic = $(this).data(); 105 pic = $(this).data();
106 pic.coverImg = pic.src; 106 pic.coverImg = pic.src;
107 - pics.push(pic); 107 +
  108 + if (+pic.status) { // 过滤下架商品
  109 + pics.push(pic);
  110 + }
108 }); 111 });
109 112
110 colorList = createColorList(pics, _from); 113 colorList = createColorList(pics, _from);
@@ -4,7 +4,8 @@ const fp = require('lodash/fp'); @@ -4,7 +4,8 @@ const fp = require('lodash/fp');
4 4
5 const camelCase = global.yoho.camelCase; 5 const camelCase = global.yoho.camelCase;
6 const helpers = global.yoho.helpers; 6 const helpers = global.yoho.helpers;
7 -const images = require(`${global.utils}/images`); 7 +
  8 +// const images = require(`${global.utils}/images`);
8 9
9 // NOTE: 这里修改了图片质量的参数 10 // NOTE: 这里修改了图片质量的参数
10 helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90')); 11 helpers.image = _.flow(helpers.image, fp.replace(/\/quality\/\d*$/, '/quality/90'));
@@ -393,7 +394,7 @@ exports.processProduct = (productData, options) => { @@ -393,7 +394,7 @@ exports.processProduct = (productData, options) => {
393 394
394 result.id = productData.product_skn; 395 result.id = productData.product_skn;
395 result.product_id = productData.product_id; 396 result.product_id = productData.product_id;
396 - result.thumb = images.getImageUrl(productData.default_images, options.width, options.height); 397 + result.thumb = helpers.image(productData.default_images, options.width, options.height);
397 result.name = productData.product_name; 398 result.name = productData.product_name;
398 result.price = !productData.market_price ? false : productData.market_price; 399 result.price = !productData.market_price ? false : productData.market_price;
399 result.salePrice = productData.sales_price; 400 result.salePrice = productData.sales_price;