Authored by 李奇

商品详情页为你优选完成提交、大数据暂未实现暂时使用开关屏该模块

@@ -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 })