Showing
5 changed files
with
149 additions
and
33 deletions
@@ -8,7 +8,7 @@ | @@ -8,7 +8,7 @@ | ||
8 | const seoModel = require('../models/seo-service'); // seo 页 model | 8 | const seoModel = require('../models/seo-service'); // seo 页 model |
9 | 9 | ||
10 | const hot = (req, res, next) => { | 10 | const hot = (req, res, next) => { |
11 | - return req.ctx(seoModel).getHotKeywordDate(req.query, req.yoho.channel).then(result => { | 11 | + return req.ctx(seoModel).getHotKeywordDate(req.params.id, req.query, req.yoho.channel).then(result => { |
12 | res.render('seo/hot', result); | 12 | res.render('seo/hot', result); |
13 | }).catch(next); | 13 | }).catch(next); |
14 | }; | 14 | }; |
1 | 1 | ||
2 | 2 | ||
3 | +const redis = global.yoho.redis; | ||
4 | +const helpers = global.yoho.helpers; | ||
5 | +const logger = global.yoho.logger; | ||
6 | + | ||
3 | const _ = require('lodash'); | 7 | const _ = require('lodash'); |
4 | const headerModel = require('../../../doraemon/models/header'); | 8 | const headerModel = require('../../../doraemon/models/header'); |
5 | 9 | ||
6 | const SearchApi = require('./search-api'); | 10 | const SearchApi = require('./search-api'); |
7 | - | ||
8 | const searchHandler = require('./search-handler'); | 11 | const searchHandler = require('./search-handler'); |
9 | const utils = '../../../utils'; | 12 | const utils = '../../../utils'; |
10 | const productProcess = require(`${utils}/product-process-simple`); | 13 | const productProcess = require(`${utils}/product-process-simple`); |
@@ -31,8 +34,7 @@ const _setHotKeywordData = (result, params, channel) => { | @@ -31,8 +34,7 @@ const _setHotKeywordData = (result, params, channel) => { | ||
31 | totalCount: data.total, | 34 | totalCount: data.total, |
32 | footPager: searchHandler.handlePagerData(data.total, changeQuery), | 35 | footPager: searchHandler.handlePagerData(data.total, changeQuery), |
33 | goods: productProcess.processProductList(data.product_list, | 36 | goods: productProcess.processProductList(data.product_list, |
34 | - Object.assign({showDiscount: false, from: {type: 'search', params: params}}, params)), | ||
35 | - latestWalk: 6, | 37 | + Object.assign({showDiscount: false, from: {type: 'hot', params: params}}, params)), |
36 | hasNextPage: searchHandler.handleNextPage(changeQuery, data.total) | 38 | hasNextPage: searchHandler.handleNextPage(changeQuery, data.total) |
37 | } | 39 | } |
38 | } | 40 | } |
@@ -41,16 +43,24 @@ const _setHotKeywordData = (result, params, channel) => { | @@ -41,16 +43,24 @@ const _setHotKeywordData = (result, params, channel) => { | ||
41 | finalResult.hotBrands = _.get(data, 'filter.brand', []); | 43 | finalResult.hotBrands = _.get(data, 'filter.brand', []); |
42 | 44 | ||
43 | finalResult.hotBrands.forEach((val) => { | 45 | finalResult.hotBrands.forEach((val) => { |
44 | - val.href = '#'; // TODO | 46 | + val.href = helpers.urlFormat(`/list/bd${val.id}.html`); |
47 | + | ||
45 | return val; | 48 | return val; |
46 | }); | 49 | }); |
47 | 50 | ||
48 | - console.log(_.get(data, 'filter.brand', [])); | ||
49 | - | ||
50 | - // finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))}; | 51 | + finalResult.criteo = {skn: searchHandler.getCriteo(_.get(finalResult.search, 'goods'))}; |
51 | } | 52 | } |
52 | 53 | ||
53 | - // console.log(finalResult); | 54 | + |
55 | + if (result[2].code === 200) { | ||
56 | + let data = result[2].data; | ||
57 | + | ||
58 | + finalResult.latestWalkExtra = [{ | ||
59 | + extraTabName: '相关推荐', | ||
60 | + extraGoodsList: productProcess.processProductList(data.product_list, | ||
61 | + Object.assign({showDiscount: false, from: {type: 'hot', params: params}}, params)) | ||
62 | + }]; | ||
63 | + } | ||
54 | 64 | ||
55 | return finalResult; | 65 | return finalResult; |
56 | }; | 66 | }; |
@@ -62,7 +72,7 @@ module.exports = class extends global.yoho.BaseModel { | @@ -62,7 +72,7 @@ module.exports = class extends global.yoho.BaseModel { | ||
62 | this.searchApi = new SearchApi(ctx); | 72 | this.searchApi = new SearchApi(ctx); |
63 | } | 73 | } |
64 | 74 | ||
65 | - getHotKeywordDate(params, channel) { | 75 | + getSearchProduct(params, channel) { |
66 | let searchParams = searchHandler.getSearchParams(params); | 76 | let searchParams = searchHandler.getSearchParams(params); |
67 | 77 | ||
68 | switch (channel) { | 78 | switch (channel) { |
@@ -83,12 +93,47 @@ module.exports = class extends global.yoho.BaseModel { | @@ -83,12 +93,47 @@ module.exports = class extends global.yoho.BaseModel { | ||
83 | } | 93 | } |
84 | 94 | ||
85 | searchParams.need_filter = 'yes'; | 95 | searchParams.need_filter = 'yes'; |
86 | - searchParams.query = '夹克'; | 96 | + |
87 | return Promise.all([ | 97 | return Promise.all([ |
88 | headerModel.requestHeaderData(channel), | 98 | headerModel.requestHeaderData(channel), |
89 | - this.searchApi.getSeoProductList(searchParams, 'fuzzySearch') | 99 | + this.searchApi.getSeoProductList(searchParams, 'fuzzySearch'), |
100 | + this.searchApi.getSeoProductList(Object.assign(searchParams, { | ||
101 | + order: 's_n_desc', | ||
102 | + limit: 5 | ||
103 | + }), 'fuzzySearch'), | ||
90 | ]).then(result => { | 104 | ]).then(result => { |
91 | return _setHotKeywordData(result, params, channel); | 105 | return _setHotKeywordData(result, params, channel); |
92 | }); | 106 | }); |
93 | } | 107 | } |
108 | + | ||
109 | + getHotKeywordDate(id, params, channel) { | ||
110 | + return redis.all([ | ||
111 | + ['get', `global:yoho:seo:hot:keywords:id:${id}`] | ||
112 | + ]).then(redisData => { | ||
113 | + let keyword = redisData[0]; | ||
114 | + | ||
115 | + try { | ||
116 | + keyword = JSON.parse(keyword); | ||
117 | + } catch (e) { | ||
118 | + logger.debug('getProductList cache data parse fail.'); | ||
119 | + } | ||
120 | + | ||
121 | + if (!_.get(keyword, 'name')) { | ||
122 | + return Promise.reject(`cannot find hot keywords by id(${id})`); | ||
123 | + } | ||
124 | + params.query = keyword.name; | ||
125 | + | ||
126 | + return this.getSearchProduct(params, channel).then(result => { | ||
127 | + result.hotKeys = (keyword.data || []).map(val => { | ||
128 | + val.href = helpers.urlFormat(`/hot/${val.id}.html`); | ||
129 | + return val; | ||
130 | + }); | ||
131 | + | ||
132 | + result.keyword = keyword; | ||
133 | + result.latestWalk = 5; | ||
134 | + | ||
135 | + return result; | ||
136 | + }); | ||
137 | + }) | ||
138 | + } | ||
94 | }; | 139 | }; |
1 | -<div class="yoho-page seo-hot-page"> | 1 | +<div class="yoho-page seo-hot-page product-list-page"> |
2 | {{> common/path-nav}} | 2 | {{> common/path-nav}} |
3 | 3 | ||
4 | <div class="clearfix"> | 4 | <div class="clearfix"> |
5 | <div class="left-content"> | 5 | <div class="left-content"> |
6 | <div class="hot-sort"> | 6 | <div class="hot-sort"> |
7 | + {{# keyword}} | ||
7 | <div class="sort-intro"> | 8 | <div class="sort-intro"> |
8 | <div class="inline"> | 9 | <div class="inline"> |
9 | <p class="name"> | 10 | <p class="name"> |
10 | - <span class="cn">夹克</span> | ||
11 | - <span class="en">JACKETS & COATS</span> | 11 | + <span class="cn">{{name}}</span> |
12 | + {{# nameEn}}<span class="en">{{.}}</span>{{/ nameEn}} | ||
12 | </p> | 13 | </p> |
13 | - <p class="desc">夹克(英语:Jacket),是一种长度至腰部或臀部的上半身衣着。夹克自诞生以来,款式演变千姿百态,形成了庞大的家族。 随着日新月异的世界发展, 夹克以各种各样的姿态永恒不衰,成为经典服饰之一。</p> | 14 | + {{# describe}}<p class="desc">{{.}}</p>{{/ describe}} |
15 | + | ||
16 | + {{#if list}} | ||
14 | <ul class="key"> | 17 | <ul class="key"> |
15 | - <li><a href="#">牛仔夹克户</a></li> | ||
16 | - <li><a href="#">牛仔夹克户</a></li> | ||
17 | - <li><a href="#">牛仔夹克户</a></li> | ||
18 | - <li><a href="#">牛仔夹克户</a></li> | ||
19 | - <li><a href="#">牛仔夹克户</a></li> | ||
20 | - <li><a href="#">牛仔夹克户</a></li> | 18 | + {{# list}} |
19 | + <li><a href="{{href}}">{{name}}</a></li> | ||
20 | + {{/ list}} | ||
21 | </ul> | 21 | </ul> |
22 | + {{/if}} | ||
22 | </div> | 23 | </div> |
23 | </div> | 24 | </div> |
24 | - <img class="thumb" src="//img12.static.yhbimg.com/adpic/2017/05/03/18/0228ed1fb3baf7c9198bfd65024812908a.jpg?imageView2/2/interlace/1/q/75"> | 25 | + <img class="thumb" src="{{image2 goods_img}}"> |
26 | + {{/ keyword}} | ||
25 | </div> | 27 | </div> |
26 | 28 | ||
27 | {{# product}} | 29 | {{# product}} |
@@ -33,21 +35,16 @@ | @@ -33,21 +35,16 @@ | ||
33 | <div class="hot-block"> | 35 | <div class="hot-block"> |
34 | <p class="title">热门关键词</p> | 36 | <p class="title">热门关键词</p> |
35 | <p class="hot-key"> | 37 | <p class="hot-key"> |
36 | - <a href="#">鞋履</a> | ||
37 | - <a href="#">鞋履</a> | ||
38 | - <a href="#">鞋履</a> | ||
39 | - <a href="#">鞋履</a> | ||
40 | - <a href="#">鞋履</a> | ||
41 | - <a href="#">鞋履</a> | ||
42 | - <a href="#">鞋履</a> | ||
43 | - <a href="#">鞋履</a> | 38 | + {{# hotKeys}} |
39 | + <a href="{{href}}">{{keyword}}</a> | ||
40 | + {{/ hotKeys}} | ||
44 | </p> | 41 | </p> |
45 | </div> | 42 | </div> |
46 | <div class="hot-block"> | 43 | <div class="hot-block"> |
47 | <p class="title">热门品牌</p> | 44 | <p class="title">热门品牌</p> |
48 | 45 | ||
49 | {{# hotBrands}} | 46 | {{# hotBrands}} |
50 | - <a href="#" class="brand-item" target="_blank" title="{{brand_name_cn}}"> | 47 | + <a href="{{href}}" class="brand-item" target="_blank" title="{{brand_name_cn}}"> |
51 | <img src="{{image2 brand_ico w=138 h=70}}" alt="{{brand_name_cn}} {{brand_keyword}}"> | 48 | <img src="{{image2 brand_ico w=138 h=70}}" alt="{{brand_name_cn}} {{brand_keyword}}"> |
52 | </a> | 49 | </a> |
53 | {{/ hotBrands}} | 50 | {{/ hotBrands}} |
@@ -55,5 +52,5 @@ | @@ -55,5 +52,5 @@ | ||
55 | </div> | 52 | </div> |
56 | </div> | 53 | </div> |
57 | 54 | ||
58 | - {{> product/latest-walk goodsInfo=@root.recommendKeywordsInfo}} | 55 | + {{> product/latest-walk goodsInfo=@root.recommendGoodsInfo}} |
59 | </div> | 56 | </div> |
@@ -7,6 +7,9 @@ | @@ -7,6 +7,9 @@ | ||
7 | <span class="about tab-item">相关推荐</span> | 7 | <span class="about tab-item">相关推荐</span> |
8 | {{/if}} | 8 | {{/if}} |
9 | 9 | ||
10 | + {{# latestWalkExtra}} | ||
11 | + <span class="tab-item extra-tab-item" data-key="{{@index}}">{{extraTabName}}</span> | ||
12 | + {{/ latestWalkExtra}} | ||
10 | <div class="bottom-line"></div> | 13 | <div class="bottom-line"></div> |
11 | </div> | 14 | </div> |
12 | <div class="bottom-tab-cont"> | 15 | <div class="bottom-tab-cont"> |
@@ -39,5 +42,24 @@ | @@ -39,5 +42,24 @@ | ||
39 | </p> | 42 | </p> |
40 | </div> | 43 | </div> |
41 | {{/if}} | 44 | {{/if}} |
45 | + | ||
46 | + {{# latestWalkExtra}} | ||
47 | + <div class="latest-walk-extra-area extra-area-{{@index}}"> | ||
48 | + <div class="goods clearfix"> | ||
49 | + {{# extraGoodsList}} | ||
50 | + <div class="good"> | ||
51 | + <a href="{{url}}" target="_blank" title="{{product_name}}"> | ||
52 | + <img class="lazy" data-original="{{image2 thumb w=280 h=382}}" alt="{{product_name}}" /> | ||
53 | + </a> | ||
54 | + <a class="name" href="{{url}}" target="_blank">{{product_name}}</a> | ||
55 | + <p class="price"> | ||
56 | + <span class="market-price">¥{{round market_price 2}}</span> | ||
57 | + <span class="sale-price">¥{{round sales_price 2}}</span> | ||
58 | + </p> | ||
59 | + </div> | ||
60 | + {{/ extraGoodsList}} | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + {{/ latestWalkExtra}} | ||
42 | </div> | 64 | </div> |
43 | {{/unless}} | 65 | {{/unless}} |
@@ -33,6 +33,7 @@ | @@ -33,6 +33,7 @@ | ||
33 | font-size: 30px; | 33 | font-size: 30px; |
34 | font-weight: 700; | 34 | font-weight: 700; |
35 | text-align: center; | 35 | text-align: center; |
36 | + margin-top: 0; | ||
36 | 37 | ||
37 | .en { | 38 | .en { |
38 | width: 100%; | 39 | width: 100%; |
@@ -118,4 +119,55 @@ | @@ -118,4 +119,55 @@ | ||
118 | } | 119 | } |
119 | } | 120 | } |
120 | } | 121 | } |
122 | + | ||
123 | + .bottom-tab-cont { | ||
124 | + padding-bottom: 20px; | ||
125 | + | ||
126 | + .latest-walk-extra-area { | ||
127 | + display: none; | ||
128 | + } | ||
129 | + | ||
130 | + .goods { | ||
131 | + width: 110%; | ||
132 | + height: auto; | ||
133 | + margin: 20px 0; | ||
134 | + | ||
135 | + .good { | ||
136 | + float: left; | ||
137 | + width: 220px; | ||
138 | + margin-right: 14px; | ||
139 | + font-size: 12px; | ||
140 | + text-align: center; | ||
141 | + | ||
142 | + img { | ||
143 | + width: 220px; | ||
144 | + height: 300px; | ||
145 | + display: block; | ||
146 | + } | ||
147 | + | ||
148 | + .name { | ||
149 | + display: block; | ||
150 | + max-width: 150px; | ||
151 | + height: 18px; | ||
152 | + line-height: 16px; | ||
153 | + margin: 5px auto; | ||
154 | + color: #222; | ||
155 | + overflow: hidden; | ||
156 | + text-overflow: ellipsis; | ||
157 | + white-space: nowrap; | ||
158 | + } | ||
159 | + | ||
160 | + .market-price { | ||
161 | + color: #999; | ||
162 | + margin-right: 5px; | ||
163 | + text-decoration: line-through; | ||
164 | + } | ||
165 | + | ||
166 | + .sale-price { | ||
167 | + color: #000; | ||
168 | + font-weight: 700; | ||
169 | + } | ||
170 | + } | ||
171 | + } | ||
172 | + } | ||
121 | } | 173 | } |
-
Please register or login to post a comment