Merge branch 'release/newSearch'
Showing
12 changed files
with
199 additions
and
78 deletions
apps/cart/controllers/count.js
0 → 100644
1 | +// 购物车数量 | ||
2 | + | ||
3 | +'use strict'; | ||
4 | + | ||
5 | +const countModel = require('../models/count'); | ||
6 | + | ||
7 | +let cartCount = (req, res, next) => { | ||
8 | + | ||
9 | + let uid = req.user.uid; | ||
10 | + let shoppingKey = req.cookies._SPK || ''; | ||
11 | + | ||
12 | + countModel.cartCount(uid, shoppingKey).then((result) => { | ||
13 | + res.json(result); | ||
14 | + }).catch(next); | ||
15 | +}; | ||
16 | + | ||
17 | +module.exports = { | ||
18 | + cartCount | ||
19 | +}; |
apps/cart/index.js
0 → 100644
1 | +/** | ||
2 | + * sub app channel | ||
3 | + * @author: Bi Kai<kai.bi@yoho.cn> | ||
4 | + * @date: 2016/05/09 | ||
5 | + */ | ||
6 | + | ||
7 | +var express = require('express'), | ||
8 | + path = require('path'), | ||
9 | + hbs = require('express-handlebars'); | ||
10 | + | ||
11 | +var app = express(); | ||
12 | + | ||
13 | +// set view engin | ||
14 | +var doraemon = path.join(__dirname, '../../doraemon/views'); // parent view root | ||
15 | + | ||
16 | +app.on('mount', function(parent) { | ||
17 | + delete parent.locals.settings; // 不继承父 App 的设置 | ||
18 | + Object.assign(app.locals, parent.locals); | ||
19 | +}); | ||
20 | + | ||
21 | +app.set('views', path.join(__dirname, 'views/action')); | ||
22 | +app.engine('.hbs', hbs({ | ||
23 | + extname: '.hbs', | ||
24 | + defaultLayout: 'layout', | ||
25 | + layoutsDir: doraemon, | ||
26 | + partialsDir: [path.join(__dirname, 'views/partial'), `${doraemon}/partial`], | ||
27 | + helpers: global.yoho.helpers | ||
28 | +})); | ||
29 | + | ||
30 | +// router | ||
31 | +app.use(require('./router')); | ||
32 | + | ||
33 | +module.exports = app; |
apps/cart/models/count.js
0 → 100644
1 | +'use strict'; | ||
2 | + | ||
3 | +const api = global.yoho.API; | ||
4 | + | ||
5 | +const cartCount = (uid, shoppingKey) => { | ||
6 | + | ||
7 | + return api.get('', { | ||
8 | + method: 'app.Shopping.count', | ||
9 | + uid: uid, | ||
10 | + shopping_key: shoppingKey | ||
11 | + }).then((result) => { | ||
12 | + return result; | ||
13 | + }); | ||
14 | +}; | ||
15 | + | ||
16 | +module.exports = { | ||
17 | + cartCount | ||
18 | +}; |
apps/cart/router.js
0 → 100644
1 | +/** | ||
2 | + * router of sub app channel | ||
3 | + * @author: Bi Kai<kai.bi@yoho.cn> | ||
4 | + * @date: 2016/05/09 | ||
5 | + */ | ||
6 | + | ||
7 | +'use strict'; | ||
8 | + | ||
9 | +const express = require('express'); | ||
10 | +const router = express.Router(); | ||
11 | +const cRoot = './controllers'; | ||
12 | +const countController = require(`${cRoot}/count`); | ||
13 | + | ||
14 | +router.get('/index/count', countController.cartCount); | ||
15 | + | ||
16 | +module.exports = router; |
@@ -5,12 +5,14 @@ | @@ -5,12 +5,14 @@ | ||
5 | */ | 5 | */ |
6 | 6 | ||
7 | 'use strict'; | 7 | 'use strict'; |
8 | +const utils = '../../../utils'; | ||
8 | const mRoot = '../models'; | 9 | const mRoot = '../models'; |
9 | const headerModel = require('../../../doraemon/models/header'); | 10 | const headerModel = require('../../../doraemon/models/header'); |
10 | const listModel = require(`${mRoot}/list`); | 11 | const listModel = require(`${mRoot}/list`); |
11 | const _ = require('lodash'); | 12 | const _ = require('lodash'); |
12 | const crypto = global.yoho.crypto; | 13 | const crypto = global.yoho.crypto; |
13 | const helpers = global.yoho.helpers; | 14 | const helpers = global.yoho.helpers; |
15 | +const productProcess = require(`${utils}/product-process`); | ||
14 | 16 | ||
15 | /** | 17 | /** |
16 | * 店铺 - 基础模板 | 18 | * 店铺 - 基础模板 |
@@ -80,40 +82,37 @@ const _shop = (req, res, shopId) => { | @@ -80,40 +82,37 @@ const _shop = (req, res, shopId) => { | ||
80 | }; | 82 | }; |
81 | } | 83 | } |
82 | 84 | ||
83 | - // uid = req.user.uid; | ||
84 | - // } else { | ||
85 | - // uid = req.query.uid; | ||
86 | - // req.session.appUid = uid; | ||
87 | - // res.cookie('appUid', uid, { | ||
88 | - // domain: 'yohobuy.com', | ||
89 | - // expires: new Date(Date.now() + 2592000000) // 有效期一年 | ||
90 | - // }); | ||
91 | - // } | ||
92 | - | ||
93 | listModel.getShopData(req, shopId, uid, isApp).then(result => { | 85 | listModel.getShopData(req, shopId, uid, isApp).then(result => { |
94 | if (result.goBrand) { | 86 | if (result.goBrand) { |
95 | 87 | ||
96 | /* 若店铺使用基础模板跳转基础模板 */ | 88 | /* 若店铺使用基础模板跳转基础模板 */ |
97 | _baseShop(req, res, result.goBrand, shopId); | 89 | _baseShop(req, res, result.goBrand, shopId); |
98 | } else { | 90 | } else { |
99 | - result = _.assign(result, pageHeader); | ||
100 | - | ||
101 | - res.render('shop/index', { | ||
102 | - module: 'product', | ||
103 | - page: 'shop', | ||
104 | - shopIndex: result, | ||
105 | - shopHeadHide: true, | ||
106 | - gender: req.query.gender, | ||
107 | - channel: req.query.channel, | ||
108 | - | ||
109 | - // pageHeader: headerModel.setNav({ | ||
110 | - // navTitle: result.storeName | ||
111 | - // }), | ||
112 | - title: result.storeName + '|' + result.storeName + '潮流服装服饰-Yoho!Buy有货', | ||
113 | - keywords: result.storeName + ',' + result.storeName + '服装服饰,' + result.storeName + '潮流服装服饰', | ||
114 | - description: result.storeName + '|Yoho!Buy有货' + result.storeName + '潮流服饰官方授权店!100%品牌正品保证,支持货到付款。', | ||
115 | - shopId: shopId, | ||
116 | - shopPage: true | 91 | + listModel.searchProductBySkn(result.hotListproductSkn).then(hotList => { |
92 | + result = _.assign(result, pageHeader, { | ||
93 | + hotList: productProcess.processProductList(hotList) | ||
94 | + }); | ||
95 | + | ||
96 | + _.forEach(result.hotList, (value, key) => { | ||
97 | + result.hotList[key].tags = {}; | ||
98 | + result.hotList[key].is_soon_sold_out = false; | ||
99 | + result.hotList[key].tags.isHot = true; | ||
100 | + }); | ||
101 | + | ||
102 | + res.render('shop/index', { | ||
103 | + module: 'product', | ||
104 | + page: 'shop', | ||
105 | + shopIndex: result, | ||
106 | + shopHeadHide: true, | ||
107 | + gender: req.query.gender, | ||
108 | + channel: req.query.channel, | ||
109 | + title: result.storeName + '|' + result.storeName + '潮流服装服饰-Yoho!Buy有货', | ||
110 | + keywords: result.storeName + ',' + result.storeName + '服装服饰,' + result.storeName + '潮流服装服饰', | ||
111 | + description: result.storeName + '|Yoho!Buy有货' + result.storeName + '潮流服饰官方授权店!100%品牌正品保证,支持货到付款。', | ||
112 | + shopId: shopId, | ||
113 | + shopPage: true | ||
114 | + }); | ||
115 | + | ||
117 | }); | 116 | }); |
118 | } | 117 | } |
119 | }); | 118 | }); |
@@ -4,6 +4,7 @@ | @@ -4,6 +4,7 @@ | ||
4 | * @date: 2016/07/21 | 4 | * @date: 2016/07/21 |
5 | */ | 5 | */ |
6 | 'use strict'; | 6 | 'use strict'; |
7 | +const utils = '../../../utils'; | ||
7 | const logger = global.yoho.logger; | 8 | const logger = global.yoho.logger; |
8 | const crypto = global.yoho.crypto; | 9 | const crypto = global.yoho.crypto; |
9 | const camelCase = global.yoho.camelCase; | 10 | const camelCase = global.yoho.camelCase; |
@@ -11,6 +12,7 @@ const _ = require('lodash'); | @@ -11,6 +12,7 @@ const _ = require('lodash'); | ||
11 | const helpers = global.yoho.helpers; | 12 | const helpers = global.yoho.helpers; |
12 | const api = global.yoho.API; | 13 | const api = global.yoho.API; |
13 | const searchModel = require('./search'); | 14 | const searchModel = require('./search'); |
15 | +const productProcess = require(`${utils}/product-process`); | ||
14 | 16 | ||
15 | /** | 17 | /** |
16 | * 频道 | 18 | * 频道 |
@@ -222,13 +224,28 @@ const getShopBrands = (shopId) => { | @@ -222,13 +224,28 @@ const getShopBrands = (shopId) => { | ||
222 | }); | 224 | }); |
223 | }; | 225 | }; |
224 | 226 | ||
227 | +/** | ||
228 | + * 通过 skn 搜索商品 | ||
229 | + * @param productSkn | ||
230 | + * @returns {*|Promise.<TResult>} | ||
231 | + * @private | ||
232 | + */ | ||
233 | +const searchProductBySkn = (productSkn) => { | ||
234 | + return api.get('', { | ||
235 | + method: 'h5.product.batch', | ||
236 | + productSkn: productSkn, | ||
237 | + }).then(result => { | ||
238 | + return _.get(result, 'data.product_list', []); | ||
239 | + }); | ||
240 | +}; | ||
241 | + | ||
225 | 242 | ||
226 | /** | 243 | /** |
227 | * 组织店铺页面数据 | 244 | * 组织店铺页面数据 |
228 | * @param {array} data 接口返回的店铺页所需数据 | 245 | * @param {array} data 接口返回的店铺页所需数据 |
229 | * @param {int} shopId 店铺id | 246 | * @param {int} shopId 店铺id |
230 | * @param {int} isApp app版本 | 247 | * @param {int} isApp app版本 |
231 | - * @return array | 248 | + * @return {shopId: int, appVersion: int} |
232 | */ | 249 | */ |
233 | const _formShopData = (data, shopId, isApp) => { | 250 | const _formShopData = (data, shopId, isApp) => { |
234 | let formatData = { | 251 | let formatData = { |
@@ -350,25 +367,13 @@ const _formShopData = (data, shopId, isApp) => { | @@ -350,25 +367,13 @@ const _formShopData = (data, shopId, isApp) => { | ||
350 | 367 | ||
351 | // 人气单品 | 368 | // 人气单品 |
352 | if (floor.hotProductsApp) { | 369 | if (floor.hotProductsApp) { |
353 | - let goods = []; | ||
354 | - | ||
355 | - _.forEach(resData, (item) => { | ||
356 | - let url = '//item.yohobuy.com/product/pro_'; | 370 | + let productSkn = ''; |
357 | 371 | ||
358 | - if (!item.cnAlphabet) { | ||
359 | - item.cnAlphabet = 'goods.html'; | ||
360 | - } | ||
361 | - url += item.productId + '_' + item.goodsId + '/' + item.cnAlphabet + '.html'; | ||
362 | - goods.push({ | ||
363 | - url: url + (isApp ? `?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${item.productSkn}}}` : ''),//eslint-disable-line | ||
364 | - img: helpers.image(item.src, 235, 314), | ||
365 | - productName: item.productName, | ||
366 | - salesPrice: item.salesPrice, | ||
367 | - presentPrice: item.salesPrice | ||
368 | - }); | 372 | + _.forEach(resData, value => { |
373 | + productSkn += value.productSkn + ','; | ||
369 | }); | 374 | }); |
370 | 375 | ||
371 | - formatData.hotList = goods; | 376 | + formatData.hotListproductSkn = productSkn; |
372 | } | 377 | } |
373 | }); | 378 | }); |
374 | } | 379 | } |
@@ -527,12 +532,7 @@ const getShopData = (req, shopId, uid, isApp) => { | @@ -527,12 +532,7 @@ const getShopData = (req, shopId, uid, isApp) => { | ||
527 | 532 | ||
528 | return Promise.all([ | 533 | return Promise.all([ |
529 | _getShopDecorator(shopId), | 534 | _getShopDecorator(shopId), |
530 | - searchModel.getFilterData({ | ||
531 | - shop_id: shopId, | ||
532 | - gender: req.query.gender || '1,3', | ||
533 | - channel: channel | ||
534 | - }), | ||
535 | - searchModel.getSearchData({ | 535 | + searchModel.getFilterSearchData({ |
536 | shop_id: shopId, | 536 | shop_id: shopId, |
537 | gender: req.query.gender || '1,3', | 537 | gender: req.query.gender || '1,3', |
538 | channel: channel | 538 | channel: channel |
@@ -544,8 +544,19 @@ const getShopData = (req, shopId, uid, isApp) => { | @@ -544,8 +544,19 @@ const getShopData = (req, shopId, uid, isApp) => { | ||
544 | shopInfo: shopInfoResult // 店铺信息 | 544 | shopInfo: shopInfoResult // 店铺信息 |
545 | }; | 545 | }; |
546 | 546 | ||
547 | + /* 获取一次分类和商品数据 */ | ||
548 | + let shopFilterSearchData = { | ||
549 | + filter: [], | ||
550 | + goods: [] | ||
551 | + }; | ||
552 | + | ||
553 | + if (result[1]) { | ||
554 | + shopFilterSearchData.filter = productProcess.processFilter(result[1].filter || []); | ||
555 | + shopFilterSearchData.goods = productProcess.processProductList(result[1].product_list || []); | ||
556 | + } | ||
557 | + | ||
547 | /* 店鋪優惠券 */ | 558 | /* 店鋪優惠券 */ |
548 | - let shopCoupons = result[3] || []; | 559 | + let shopCoupons = result[2] || []; |
549 | 560 | ||
550 | // 店铺分类 | 561 | // 店铺分类 |
551 | return _getShopCategory(shopId, channel).then((shopCategory) => { | 562 | return _getShopCategory(shopId, channel).then((shopCategory) => { |
@@ -554,14 +565,16 @@ const getShopData = (req, shopId, uid, isApp) => { | @@ -554,14 +565,16 @@ const getShopData = (req, shopId, uid, isApp) => { | ||
554 | }, shopData); | 565 | }, shopData); |
555 | 566 | ||
556 | // noinspection JSCheckFunctionSignatures | 567 | // noinspection JSCheckFunctionSignatures |
557 | - return Object.assign(_formShopData(shopData, shopId, isApp), { | ||
558 | - filter: result[1], | ||
559 | - goods: result[2], | ||
560 | - shopId: shopId, | ||
561 | - coverChannel: channel, | ||
562 | - shopCoupons: shopCoupons, | ||
563 | - shopCouponsOne: shopCoupons.length === 1 | ||
564 | - }); | 568 | + return Object.assign( |
569 | + _formShopData(shopData, shopId, isApp), | ||
570 | + shopFilterSearchData, | ||
571 | + { | ||
572 | + shopId: shopId, | ||
573 | + coverChannel: channel, | ||
574 | + shopCoupons: shopCoupons, | ||
575 | + shopCouponsOne: shopCoupons.length === 1 | ||
576 | + } | ||
577 | + ); | ||
565 | }); | 578 | }); |
566 | }); | 579 | }); |
567 | 580 | ||
@@ -573,10 +586,9 @@ const getShopData = (req, shopId, uid, isApp) => { | @@ -573,10 +586,9 @@ const getShopData = (req, shopId, uid, isApp) => { | ||
573 | * @param req | 586 | * @param req |
574 | * @param shopId | 587 | * @param shopId |
575 | * @param uid | 588 | * @param uid |
576 | - * @param isApp | ||
577 | * @returns {Promise.<TResult>|*} | 589 | * @returns {Promise.<TResult>|*} |
578 | */ | 590 | */ |
579 | -const getShopFav = (req, shopId, uid, isApp) => { | 591 | +const getShopFav = (req, shopId, uid) => { |
580 | return _getShopInfo(shopId, uid).then(shopInfoResult => { | 592 | return _getShopInfo(shopId, uid).then(shopInfoResult => { |
581 | return shopInfoResult; | 593 | return shopInfoResult; |
582 | }); | 594 | }); |
@@ -802,5 +814,6 @@ module.exports = { | @@ -802,5 +814,6 @@ module.exports = { | ||
802 | getShopBrands, | 814 | getShopBrands, |
803 | getShopCategory, | 815 | getShopCategory, |
804 | receiveCoupon, | 816 | receiveCoupon, |
805 | - getShopFav | 817 | + getShopFav, |
818 | + searchProductBySkn | ||
806 | }; | 819 | }; |
@@ -144,6 +144,22 @@ const getFilterData = (params) => { | @@ -144,6 +144,22 @@ const getFilterData = (params) => { | ||
144 | }; | 144 | }; |
145 | 145 | ||
146 | /** | 146 | /** |
147 | + * 获取筛选数据 | ||
148 | + * @param {[object]} params | ||
149 | + * @return {[array]} | ||
150 | + */ | ||
151 | +const getFilterSearchData = (params) => { | ||
152 | + return _searchGoods(params).then((result) => { | ||
153 | + if (result && result.code === 200) { | ||
154 | + return result.data; | ||
155 | + } else { | ||
156 | + logger.error('get filter data api return code is not 200'); | ||
157 | + return []; | ||
158 | + } | ||
159 | + }); | ||
160 | +}; | ||
161 | + | ||
162 | +/** | ||
147 | * 获取所有的品类名称 | 163 | * 获取所有的品类名称 |
148 | **/ | 164 | **/ |
149 | const getClassNames = () => { | 165 | const getClassNames = () => { |
@@ -235,6 +251,7 @@ const searchKeyActivity = (params) => { | @@ -235,6 +251,7 @@ const searchKeyActivity = (params) => { | ||
235 | module.exports = { | 251 | module.exports = { |
236 | getSearchData, | 252 | getSearchData, |
237 | getFilterData, | 253 | getFilterData, |
254 | + getFilterSearchData, | ||
238 | getAllBrandNames, | 255 | getAllBrandNames, |
239 | getClassNames, | 256 | getClassNames, |
240 | getSearchIndex, | 257 | getSearchIndex, |
@@ -112,21 +112,11 @@ | @@ -112,21 +112,11 @@ | ||
112 | </a> | 112 | </a> |
113 | </div> | 113 | </div> |
114 | <div class="product-warp"> | 114 | <div class="product-warp"> |
115 | - <ul class="product-list first"> | ||
116 | - {{#each hotList}} | ||
117 | - <li class="buriedpoint" data-bp-id="shop_hotList_{{url}}"> | ||
118 | - <a href="{{url}}"> | ||
119 | - <img src="{{img}}"> | ||
120 | - </a> | ||
121 | - <div class="list-price"> | ||
122 | - <p>{{productName}}</p> | ||
123 | - <p><span class="red">{{originalPrice}}</span> | ||
124 | - <span>{{presentPrice}}</span> | ||
125 | - </p> | ||
126 | - </div> | ||
127 | - </li> | ||
128 | - {{/each}} | ||
129 | - </ul> | 115 | + <div class="goods-container clearfix"> |
116 | + {{# hotList}} | ||
117 | + {{> common/goods}} | ||
118 | + {{/ hotList}} | ||
119 | + </div> | ||
130 | </div> | 120 | </div> |
131 | </div> | 121 | </div> |
132 | 122 |
@@ -17,6 +17,7 @@ module.exports = app => { | @@ -17,6 +17,7 @@ module.exports = app => { | ||
17 | app.use('/product', require('./apps/product')); | 17 | app.use('/product', require('./apps/product')); |
18 | app.use('/guang', require('./apps/guang')); | 18 | app.use('/guang', require('./apps/guang')); |
19 | app.use('/activity', require('./apps/activity')); | 19 | app.use('/activity', require('./apps/activity')); |
20 | + app.use('/cart', require('./apps/cart')); | ||
20 | 21 | ||
21 | // 分期付款 | 22 | // 分期付款 |
22 | app.use('/home', require('./apps/home')); | 23 | app.use('/home', require('./apps/home')); |
@@ -5,6 +5,9 @@ | @@ -5,6 +5,9 @@ | ||
5 | {{# isNew}} | 5 | {{# isNew}} |
6 | <p class="good-tag new-tag">NEW</p> | 6 | <p class="good-tag new-tag">NEW</p> |
7 | {{/ isNew}} | 7 | {{/ isNew}} |
8 | + {{# isHot}} | ||
9 | + <p class="good-tag hot-tag">HOT</p> | ||
10 | + {{/ isHot}} | ||
8 | {{# isAdvance}} | 11 | {{# isAdvance}} |
9 | <p class="good-tag renew-tag">再到着</p> | 12 | <p class="good-tag renew-tag">再到着</p> |
10 | {{/ isAdvance}} | 13 | {{/ isAdvance}} |
@@ -30,6 +30,12 @@ | @@ -30,6 +30,12 @@ | ||
30 | color: #fff; | 30 | color: #fff; |
31 | } | 31 | } |
32 | 32 | ||
33 | + .hot-tag { | ||
34 | + width: 60px; | ||
35 | + background-color: #ff575c; | ||
36 | + color: #fff; | ||
37 | + } | ||
38 | + | ||
33 | .renew-tag { | 39 | .renew-tag { |
34 | width: 90px; | 40 | width: 90px; |
35 | background-color: #78dc7e; | 41 | background-color: #78dc7e; |
@@ -145,6 +145,12 @@ $basicBtnC: #eb0313; | @@ -145,6 +145,12 @@ $basicBtnC: #eb0313; | ||
145 | color: #fff; | 145 | color: #fff; |
146 | } | 146 | } |
147 | 147 | ||
148 | + .hot-tag { | ||
149 | + width: 60px; | ||
150 | + background-color: #ff575c; | ||
151 | + color: #fff; | ||
152 | + } | ||
153 | + | ||
148 | .renew-tag { | 154 | .renew-tag { |
149 | background-color: #78dc7e; | 155 | background-color: #78dc7e; |
150 | color: #fff; | 156 | color: #fff; |
-
Please register or login to post a comment