商品详情页为你优选完成提交、大数据暂未实现暂时使用开关屏该模块
Showing
4 changed files
with
155 additions
and
17 deletions
@@ -9,10 +9,19 @@ | @@ -9,10 +9,19 @@ | ||
9 | 9 | ||
10 | // const helpers = global.yoho.helpers; | 10 | // const helpers = global.yoho.helpers; |
11 | const api = global.yoho.API; | 11 | const api = global.yoho.API; |
12 | +const md5 = require('md5'); | ||
12 | const _ = require('lodash'); | 13 | const _ = require('lodash'); |
14 | +const requestIp = require('request-ip'); | ||
13 | const model = require('../models/detail'); | 15 | const model = require('../models/detail'); |
14 | const searchModel = require('../models/search'); | 16 | const searchModel = require('../models/search'); |
15 | 17 | ||
18 | +// 频道映射 | ||
19 | +const CHANNEL_MAP = { | ||
20 | + 'men': 1, | ||
21 | + 'women': 2, | ||
22 | + 'lifestyle': 4 | ||
23 | +}; | ||
24 | + | ||
16 | // 保存在 gids 和 skns ,最近流览功能 | 25 | // 保存在 gids 和 skns ,最近流览功能 |
17 | const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { | 26 | const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { |
18 | // oldSkns = oldSkns ? oldSkns.split(',') : []; | 27 | // oldSkns = oldSkns ? oldSkns.split(',') : []; |
@@ -28,6 +37,25 @@ const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { | @@ -28,6 +37,25 @@ const saveRecentGoodInCookies = (oldSkns, res, addSkns) => { | ||
28 | }; | 37 | }; |
29 | 38 | ||
30 | /** | 39 | /** |
40 | + * 获取客户端唯一标识 | ||
41 | + * @param req | ||
42 | + * @param res | ||
43 | + * @returns {*|string} | ||
44 | + */ | ||
45 | +const getUdid = (req, res) => { | ||
46 | + let udid = req.cookies.udid; | ||
47 | + | ||
48 | + if (!udid) { | ||
49 | + udid = md5(req.ip || requestIp.getClientIp(req)); | ||
50 | + | ||
51 | + if (res && res.cookie) { | ||
52 | + res.cookie('udid', udid); | ||
53 | + } | ||
54 | + } | ||
55 | + return udid; | ||
56 | +}; | ||
57 | + | ||
58 | +/** | ||
31 | * 商品详情 | 59 | * 商品详情 |
32 | */ | 60 | */ |
33 | const component = { | 61 | const component = { |
@@ -175,7 +203,6 @@ const component = { | @@ -175,7 +203,6 @@ const component = { | ||
175 | 203 | ||
176 | /** | 204 | /** |
177 | * 是否支持退换货 | 205 | * 是否支持退换货 |
178 | - * | ||
179 | * @param req | 206 | * @param req |
180 | * @param res | 207 | * @param res |
181 | * @param next | 208 | * @param next |
@@ -188,6 +215,29 @@ const component = { | @@ -188,6 +215,29 @@ const component = { | ||
188 | model.refundExchange(params).then(result => { | 215 | model.refundExchange(params).then(result => { |
189 | res.json(result); | 216 | res.json(result); |
190 | }).catch(next); | 217 | }).catch(next); |
218 | + }, | ||
219 | + | ||
220 | + /** | ||
221 | + * 为你优选 | ||
222 | + * @param req | ||
223 | + * @param res | ||
224 | + * @param next | ||
225 | + */ | ||
226 | + prefer: (req, res, next) => { | ||
227 | + let udid = getUdid(req, res); | ||
228 | + let channel = req.query.channel || req.cookies._Channel || 'men'; | ||
229 | + let params = { | ||
230 | + udid, | ||
231 | + yh_channel: CHANNEL_MAP[channel] || 1, | ||
232 | + limit: 30, | ||
233 | + page: 1, | ||
234 | + rec_pos: 100003 | ||
235 | + }; | ||
236 | + | ||
237 | + model.preferList(params) | ||
238 | + .then((list) => { | ||
239 | + res.json(list); | ||
240 | + }).catch(next); | ||
191 | } | 241 | } |
192 | }; | 242 | }; |
193 | 243 |
@@ -6,6 +6,52 @@ | @@ -6,6 +6,52 @@ | ||
6 | 'use strict'; | 6 | 'use strict'; |
7 | 7 | ||
8 | const api = global.yoho.API; | 8 | const api = global.yoho.API; |
9 | +const _ = require('lodash'); | ||
10 | + | ||
11 | +/** | ||
12 | + * | ||
13 | + * @param product | ||
14 | + * @returns {*|string} | ||
15 | + * @private | ||
16 | + */ | ||
17 | +const _procProductImg = (product) => { | ||
18 | + if (product.gender === '2,3' || product.gender === '2' || product.gender === '3') { | ||
19 | + return product.cover_2 || product.images_url || product.cover_1 || ''; | ||
20 | + } | ||
21 | + | ||
22 | + return product.cover_1 || product.images_url || product.cover_2 || ''; | ||
23 | +}; | ||
24 | + | ||
25 | +/** | ||
26 | + * | ||
27 | + * @param list | ||
28 | + * @returns {Array} | ||
29 | + * @private | ||
30 | + */ | ||
31 | +const _processProduct = (list) => { | ||
32 | + let newRes = []; | ||
33 | + | ||
34 | + list = list || []; | ||
35 | + | ||
36 | + list.forEach(item => { | ||
37 | + let defaultGoods = _.find(item.goods_list, {is_default: 'Y'}); | ||
38 | + | ||
39 | + // 无默认商品取商品列表第一个 | ||
40 | + if (!defaultGoods) { | ||
41 | + defaultGoods = item.goods_list[0]; | ||
42 | + } | ||
43 | + | ||
44 | + item.default_images = _procProductImg(defaultGoods); | ||
45 | + item.goodsUrl = `${config.siteUrl}/product/pro_${item.product_id}_${defaultGoods.goods_id}/${item.cn_alphabet}.html`; // eslint-disable-line | ||
46 | + }); | ||
47 | + | ||
48 | + _.chunk(list, 5).forEach(item => { | ||
49 | + newRes.push({ | ||
50 | + list: item | ||
51 | + }); | ||
52 | + }); | ||
53 | + return newRes; | ||
54 | +}; | ||
9 | 55 | ||
10 | /** | 56 | /** |
11 | * 商品详情 | 57 | * 商品详情 |
@@ -83,13 +129,30 @@ const model = { | @@ -83,13 +129,30 @@ const model = { | ||
83 | 129 | ||
84 | /** | 130 | /** |
85 | * 是否支持退换货 | 131 | * 是否支持退换货 |
86 | - * | ||
87 | * @param params | 132 | * @param params |
88 | */ | 133 | */ |
89 | refundExchange(params) { | 134 | refundExchange(params) { |
90 | return api.get('', Object.assign({ | 135 | return api.get('', Object.assign({ |
91 | method: 'app.product.refundExchange' | 136 | method: 'app.product.refundExchange' |
92 | }, params)); | 137 | }, params)); |
138 | + }, | ||
139 | + | ||
140 | + /** | ||
141 | + * 为你优选 | ||
142 | + * @param params | ||
143 | + * @param uid | ||
144 | + * @returns {Array} | ||
145 | + */ | ||
146 | + preferList(params, uid) { | ||
147 | + if (uid !== 0 && uid !== null) { | ||
148 | + params.uid = uid; | ||
149 | + } | ||
150 | + | ||
151 | + return api.get('', Object.assign({ | ||
152 | + method: 'app.home.newPreference' | ||
153 | + }, params)).then(data => { | ||
154 | + return _processProduct(data.data.product_list); | ||
155 | + }); | ||
93 | } | 156 | } |
94 | }; | 157 | }; |
95 | 158 |
@@ -47,6 +47,7 @@ router.get(/\/product\/pro_([\d]+)_([\d]+)\/(.*).html/, detail.index); // 商品 | @@ -47,6 +47,7 @@ router.get(/\/product\/pro_([\d]+)_([\d]+)\/(.*).html/, detail.index); // 商品 | ||
47 | router.get(/\/product\/product_([\d]+)\.json/, detail.product); | 47 | router.get(/\/product\/product_([\d]+)\.json/, detail.product); |
48 | router.get(/\/product\/intro_([\d]+)\.json/, detail.intro); | 48 | router.get(/\/product\/intro_([\d]+)\.json/, detail.intro); |
49 | router.get('/product/refundExchange/:skn', detail.supportRefundExchange); // 是否支持7天无理由退换货 | 49 | router.get('/product/refundExchange/:skn', detail.supportRefundExchange); // 是否支持7天无理由退换货 |
50 | +router.get('/product/prefer', detail.prefer); // 为你优选列表 | ||
50 | router.post(/\product\/cart.json/, detail.addToCart); | 51 | router.post(/\product\/cart.json/, detail.addToCart); |
51 | router.post(/\product\/favorite.json/, auth, detail.favorite); | 52 | router.post(/\product\/favorite.json/, auth, detail.favorite); |
52 | router.get(/\/product\/cart-count.json/, detail.getCartCount); | 53 | router.get(/\/product\/cart-count.json/, detail.getCartCount); |
@@ -28,12 +28,8 @@ | @@ -28,12 +28,8 @@ | ||
28 | <show-box> | 28 | <show-box> |
29 | <ul class="service"> | 29 | <ul class="service"> |
30 | <li><i class="icon icon-real"></i>100%品牌正品</li> | 30 | <li><i class="icon icon-real"></i>100%品牌正品</li> |
31 | - <li v-if="intro.supportRefundExchange" class="return"> | ||
32 | - <i class="icon icon-seven"></i>支持7天无理由退换货 | ||
33 | - </li> | ||
34 | - <li class="return"> | ||
35 | - <i class="icon icon-unsupport-seven"></i>不支持7天无理由退换货 | ||
36 | - </li> | 31 | + <li class="return" v-if="intro.supportRefundExchange"><i class="icon icon-seven"></i>支持7天无理由退换货</li> |
32 | + <li class="return"><i class="icon icon-unsupport-seven"></i>不支持7天无理由退换货</li> | ||
37 | <li><i class="icon icon-onlineservice"></i>便捷在线客服</li> | 33 | <li><i class="icon icon-onlineservice"></i>便捷在线客服</li> |
38 | </ul> | 34 | </ul> |
39 | </show-box> | 35 | </show-box> |
@@ -180,6 +176,10 @@ | @@ -180,6 +176,10 @@ | ||
180 | 176 | ||
181 | </show-box> | 177 | </show-box> |
182 | 178 | ||
179 | + <show-box v-if="showPrefer" class="prefer-detail" :is-last="true"> | ||
180 | + <prefer-list :title="preferTitle" :list="preferList"></prefer-list> | ||
181 | + </show-box> | ||
182 | + | ||
183 | <div class="control-box" v-if="isApp && isReady"> | 183 | <div class="control-box" v-if="isApp && isReady"> |
184 | <button class="button control-button"> | 184 | <button class="button control-button"> |
185 | <span @click="yoho.goShopingCart()" style="position: relative;"> | 185 | <span @click="yoho.goShopingCart()" style="position: relative;"> |
@@ -261,23 +261,20 @@ | @@ -261,23 +261,20 @@ | ||
261 | font-size: 0; | 261 | font-size: 0; |
262 | li { | 262 | li { |
263 | font-size: 24px; | 263 | font-size: 24px; |
264 | - width: 200px; | ||
265 | - line-height: 40px; | 264 | + width: 195px; |
265 | + line-height: 22px; | ||
266 | text-align: center; | 266 | text-align: center; |
267 | display: inline-block; | 267 | display: inline-block; |
268 | 268 | ||
269 | - &.quality { | 269 | + i.icon { |
270 | + margin-right: 6px; | ||
270 | } | 271 | } |
271 | 272 | ||
272 | &.return { | 273 | &.return { |
273 | - width: 290px; | 274 | + width: 300px; |
274 | border-left: 1px solid #eee; | 275 | border-left: 1px solid #eee; |
275 | border-right: 1px solid #eee; | 276 | border-right: 1px solid #eee; |
276 | } | 277 | } |
277 | - | ||
278 | - &.cs { | ||
279 | - | ||
280 | - } | ||
281 | } | 278 | } |
282 | } | 279 | } |
283 | 280 | ||
@@ -490,7 +487,10 @@ | @@ -490,7 +487,10 @@ | ||
490 | }, | 487 | }, |
491 | isApp: yoho.isApp, | 488 | isApp: yoho.isApp, |
492 | isSoldOut: false, | 489 | isSoldOut: false, |
493 | - isReady: false | 490 | + isReady: false, |
491 | + showPrefer: true, // TODO 为你优选大数据暂未实现,本期暂时屏蔽 | ||
492 | + preferTitle: '为你优选', | ||
493 | + preferList: [] | ||
494 | }; | 494 | }; |
495 | }, | 495 | }, |
496 | computed: { | 496 | computed: { |
@@ -501,6 +501,7 @@ | @@ -501,6 +501,7 @@ | ||
501 | showBox: require('./show-box.vue'), | 501 | showBox: require('./show-box.vue'), |
502 | topNav: require('./top-nav.vue'), | 502 | topNav: require('./top-nav.vue'), |
503 | shareBottom: require('component/tool/share-bottom.vue'), | 503 | shareBottom: require('component/tool/share-bottom.vue'), |
504 | + preferList: require('component/product/preferList.vue') | ||
504 | }, | 505 | }, |
505 | methods: { | 506 | methods: { |
506 | /** | 507 | /** |
@@ -598,6 +599,29 @@ | @@ -598,6 +599,29 @@ | ||
598 | $.get(`/product/refundExchange/${data.product_skn}`).then(sd => { | 599 | $.get(`/product/refundExchange/${data.product_skn}`).then(sd => { |
599 | this.intro['supportRefundExchange'] = sd[data.product_skn] === "Y"; | 600 | this.intro['supportRefundExchange'] = sd[data.product_skn] === "Y"; |
600 | }); | 601 | }); |
602 | + | ||
603 | + if(self.showPrefer) { | ||
604 | + $.get('/product/prefer').then(list => { | ||
605 | + console.log(list.length) | ||
606 | + self.preferList = list || [ | ||
607 | + { | ||
608 | + goodsUrl: '//m.yohoblk.com', | ||
609 | + default_images: '//img11.static.yhbimg.com/goodsimg/2016/12/26/17/01a77e16890169159034327b40ed95e0d9.png?imageMogr2/thumbnail/750x1000/extent/750x1000/background/d2hpdGU=/position/center/quality/80/interlace/1', | ||
610 | + product_name: '测试产品fd测试产品fdsssfdssddfsdfsdfsssfdssddfsdfsdf', | ||
611 | + market_price: '100', | ||
612 | + sales_price: '50' | ||
613 | + | ||
614 | + },{ | ||
615 | + goodsUrl: '//m.yohoblk.com', | ||
616 | + default_images: '//img11.static.yhbimg.com/goodsimg/2016/12/26/17/01a77e16890169159034327b40ed95e0d9.png?imageMogr2/thumbnail/750x1000/extent/750x1000/background/d2hpdGU=/position/center/quality/80/interlace/1', | ||
617 | + product_name: '测试产品测试产品fdsssfdssddfsdfsdffdsssfdssddfsdfsdf测试产品fdsssfdssddfsdfsdf', | ||
618 | + market_price: '100', | ||
619 | + sales_price: '50' | ||
620 | + | ||
621 | + } | ||
622 | + ]; | ||
623 | + }); | ||
624 | + } | ||
601 | }); | 625 | }); |
602 | } | 626 | } |
603 | }) | 627 | }) |
-
Please register or login to post a comment