Authored by 郭成尧

Merge remote-tracking branch 'remotes/origin/master' into feature/unionpromotion

@@ -7,6 +7,7 @@ @@ -7,6 +7,7 @@
7 'use strict'; 7 'use strict';
8 8
9 const indexModel = require('../models/market'); 9 const indexModel = require('../models/market');
  10 +const _ = require('lodash');
10 11
11 exports.index = (req, res, next) => { 12 exports.index = (req, res, next) => {
12 13
@@ -21,3 +22,26 @@ exports.index = (req, res, next) => { @@ -21,3 +22,26 @@ exports.index = (req, res, next) => {
21 }).catch(next); 22 }).catch(next);
22 23
23 }; 24 };
  25 +
  26 +/**
  27 + * 市场推广活动升级版,自定义下载渠道
  28 + * @param req
  29 + * @param res
  30 + * @param next
  31 + */
  32 +exports.v2 = (req, res, next) => {
  33 +
  34 + indexModel.index({
  35 +
  36 + }).then((result) => {
  37 + if (_.has(result, 'download[0].url') && req.query.union_type) {
  38 + result.download[0].url = result.download[0].url.split('?')[0] +
  39 + '?union_type=' + req.query.union_type;
  40 + }
  41 + res.render('market/market', Object.assign(result, {
  42 + title: 'Yoho!Buy 有货'
  43 + }));
  44 +
  45 + }).catch(next);
  46 +
  47 +};
@@ -12,3 +12,27 @@ exports.wechatShare = (req, res, next) => { @@ -12,3 +12,27 @@ exports.wechatShare = (req, res, next) => {
12 res.jsonp(result); 12 res.jsonp(result);
13 }).catch(next); 13 }).catch(next);
14 }; 14 };
  15 +
  16 +/**
  17 + * 活动页<http://feature.yoho.cn/1101/1101ITEMBOY/index.html?title=%E7%94%B7%E7%94%9F%E5%88%86%E4%BC%9A%E5%9C%BA&share_id=814&mkt_code=1011111#a_01>
  18 + * <xiaoxiao.hao@yoho.cn>
  19 + * 2016/07/13
  20 + */
  21 +
  22 +// 活动页保存相应cookie的值
  23 +exports.feature = (req, res) => {
  24 + let mktCode = req.query.mkt_code || false;
  25 +
  26 + // 下载浮层,下载按钮会用到该参数
  27 + if (mktCode) {
  28 + res.cookie('mkt_code', mktCode, {
  29 + domain: '.yohobuy.com',
  30 + path: '/'
  31 + });
  32 + res.cookie('unionTypeYas', mktCode, {
  33 + path: '/'
  34 + });
  35 + }
  36 +
  37 + res.json({mktCode: mktCode});
  38 +};
@@ -71,6 +71,7 @@ router.get('/invite', invite.checkType, invite.index); @@ -71,6 +71,7 @@ router.get('/invite', invite.checkType, invite.index);
71 router.get('/invite/index', invite.checkType, invite.index); 71 router.get('/invite/index', invite.checkType, invite.index);
72 72
73 router.get('/market', market.index); // 市场推广活动 73 router.get('/market', market.index); // 市场推广活动
  74 +router.get('/market/v2', market.v2); // 市场推广活动升级版,自定义下载渠道
74 75
75 router.get(/\/invite\/share_([\d]+)_([\d]+)_([\d]+).html/, invite.checkType, invite.share); 76 router.get(/\/invite\/share_([\d]+)_([\d]+)_([\d]+).html/, invite.checkType, invite.share);
76 77
@@ -116,4 +117,7 @@ router.get('/vip-day1028/crazy-luck', vipDay1028.beforeIn, vipDay1028.crazyLuck) @@ -116,4 +117,7 @@ router.get('/vip-day1028/crazy-luck', vipDay1028.beforeIn, vipDay1028.crazyLuck)
116 router.post('/vip-day1028/signin.json', vipDay1028.beforeIn, vipDay1028.signin); 117 router.post('/vip-day1028/signin.json', vipDay1028.beforeIn, vipDay1028.signin);
117 router.post('/vip-day1028/isStudent', vipDay1028.beforeIn, vipDay1028.checkIsStudent); 118 router.post('/vip-day1028/isStudent', vipDay1028.beforeIn, vipDay1028.checkIsStudent);
118 119
  120 +// 获取活动页传来的参数
  121 +router.get('/wechat/1111', wechat.feature);
  122 +
119 module.exports = router; 123 module.exports = router;
@@ -60,13 +60,14 @@ exports.ensure = (req, res, next) => { @@ -60,13 +60,14 @@ exports.ensure = (req, res, next) => {
60 let view; 60 let view;
61 61
62 if (paymentInfo.code !== 200) { 62 if (paymentInfo.code !== 200) {
63 - if (paymentInfo.message) {  
64 view = { 63 view = {
65 orderEnsure: false, 64 orderEnsure: false,
66 message: paymentInfo.message 65 message: paymentInfo.message
67 }; 66 };
68 - } else {  
69 - return Promise.reject(paymentInfo); 67 +
  68 + // hotfix: nginx 接口限流, code:9999991时没message 信息
  69 + if (!view.message) {
  70 + view.message = '挤爆啦,系统繁忙';
70 } 71 }
71 } else { 72 } else {
72 // 渲染 73 // 渲染
@@ -12,10 +12,6 @@ @@ -12,10 +12,6 @@
12 {{/if}} 12 {{/if}}
13 <!--/tab-nav--> 13 <!--/tab-nav-->
14 14
15 - {{#if isApp}}  
16 - <div class='empty-height'></div>  
17 - {{/if}}  
18 -  
19 <div class="plusstar-resources"> 15 <div class="plusstar-resources">
20 <!--资源位数据模板--> 16 <!--资源位数据模板-->
21 </div><!--/plusstar-resources--> 17 </div><!--/plusstar-resources-->
@@ -136,7 +136,7 @@ const _shop = (req, res, shopId) => { @@ -136,7 +136,7 @@ const _shop = (req, res, shopId) => {
136 _.forEach(result.hotList, (value, key) => { 136 _.forEach(result.hotList, (value, key) => {
137 result.hotList[key].tags = {}; 137 result.hotList[key].tags = {};
138 result.hotList[key].is_soon_sold_out = false; 138 result.hotList[key].is_soon_sold_out = false;
139 - result.hotList[key].tags.isHot = true; 139 + result.hotList[key].tags.is_hot = true;
140 }); 140 });
141 141
142 // 有领券功能,不缓存 142 // 有领券功能,不缓存
@@ -495,6 +495,9 @@ const userCoupon = (req, res, next) => { @@ -495,6 +495,9 @@ const userCoupon = (req, res, next) => {
495 } 495 }
496 } 496 }
497 497
  498 + cryptCouponId = parseInt(cryptCouponId, 10);
  499 + uid = parseInt(uid, 10);
  500 +
498 if (uid) { 501 if (uid) {
499 listModel.receiveCoupon( 502 listModel.receiveCoupon(
500 uid, 503 uid,
@@ -25,20 +25,20 @@ const list = (req, res, next) => { @@ -25,20 +25,20 @@ const list = (req, res, next) => {
25 let isQuerySecondClass = false; // 标识用户搜的是不是二级品类 25 let isQuerySecondClass = false; // 标识用户搜的是不是二级品类
26 let domain = null; 26 let domain = null;
27 27
28 - if (params.query) {  
29 - let activity = _.get(searchModel.searchKeyActivity(params.query), 'data.urlobj.appUrl', '');  
30 -  
31 - if (activity) {  
32 - res.redirect(activity);  
33 - }  
34 - }  
35 -  
36 if (params.shop_id) { 28 if (params.shop_id) {
37 params.shopId = params.shop_id; 29 params.shopId = params.shop_id;
38 } 30 }
39 31
  32 + if (params.query) {
  33 + return searchModel.searchKeyActivity(params.query).then(activityResult => {
  34 + let activity = _.get(activityResult, 'urlobj.appUrl', '');
  35 +
  36 + if (activity) {
  37 + return res.redirect(activity);
  38 + } else {
  39 +
40 /* 判断是不是品牌, 是品牌跳到品牌列表页(显示搜索框),判断是不是品类, 是品类加导航标题(不显示搜索框) */ 40 /* 判断是不是品牌, 是品牌跳到品牌列表页(显示搜索框),判断是不是品类, 是品类加导航标题(不显示搜索框) */
41 - Promise.all([ 41 + return Promise.all([
42 searchModel.getAllBrandNames(), 42 searchModel.getAllBrandNames(),
43 searchModel.getClassNames() 43 searchModel.getClassNames()
44 ]).then(result => { 44 ]).then(result => {
@@ -125,6 +125,9 @@ const list = (req, res, next) => { @@ -125,6 +125,9 @@ const list = (req, res, next) => {
125 pageFooter: true 125 pageFooter: true
126 }); 126 });
127 }).catch(next); 127 }).catch(next);
  128 + }
  129 + });
  130 + }
128 }; 131 };
129 132
130 /** 133 /**
@@ -132,6 +135,7 @@ const list = (req, res, next) => { @@ -132,6 +135,7 @@ const list = (req, res, next) => {
132 */ 135 */
133 const index = (req, res, next) => { 136 const index = (req, res, next) => {
134 let title = '搜索'; 137 let title = '搜索';
  138 +
135 ((render) => { 139 ((render) => {
136 if (_.get(req, 'app.locals.wap.search.removeHotSearch', false)) { 140 if (_.get(req, 'app.locals.wap.search.removeHotSearch', false)) {
137 render([]); 141 render([]);
@@ -156,7 +160,7 @@ const index = (req, res, next) => { @@ -156,7 +160,7 @@ const index = (req, res, next) => {
156 } 160 }
157 161
158 }); 162 });
159 - }) 163 + });
160 164
161 }; 165 };
162 166
1 -  
2 'use strict'; 1 'use strict';
3 2
4 const SECOND = 1; 3 const SECOND = 1;
@@ -43,6 +42,7 @@ const cachePage = { @@ -43,6 +42,7 @@ const cachePage = {
43 42
44 // 秒杀列表 43 // 秒杀列表
45 '/product/seckill': 30 * SECOND, 44 '/product/seckill': 30 * SECOND,
  45 + '/product/seckill/list': 30 * SECOND,
46 46
47 // 秒杀详情 47 // 秒杀详情
48 '/product/^\\/seckill\\/pro_([\\d]+)_([\\d]+)/': 30 * MINUTE, 48 '/product/^\\/seckill\\/pro_([\\d]+)_([\\d]+)/': 30 * MINUTE,
@@ -64,10 +64,17 @@ const cachePage = { @@ -64,10 +64,17 @@ const cachePage = {
64 '/brands': 5 * MINUTE, 64 '/brands': 5 * MINUTE,
65 '/brands/search': 1 * MINUTE, 65 '/brands/search': 1 * MINUTE,
66 66
67 - //活动 67 + // 直播活动
  68 + '/activity/live': 1 * MINUTE,
  69 +
  70 + // 单品日
68 '/activity/single-day': 1 * MINUTE, 71 '/activity/single-day': 1 * MINUTE,
  72 + '/activity/single-day/getSingleData': 30 * SECOND,
  73 + '/activity/single-day/getProductData': 30 * SECOND,
  74 +
  75 + // 店铺收藏
69 '/activity/shopCollect': 1 * MINUTE, 76 '/activity/shopCollect': 1 * MINUTE,
70 - '/activity/live': 1 * MINUTE 77 + '/activity/shopNav': 30 * SECOND
71 78
72 }; 79 };
73 80
1 { 1 {
2 "name": "m-yohobuy-node", 2 "name": "m-yohobuy-node",
3 - "version": "5.1.7", 3 + "version": "5.1.10",
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": {
@@ -127,6 +127,8 @@ var singleDay = { @@ -127,6 +127,8 @@ var singleDay = {
127 $swiperTab.on('click', function() { 127 $swiperTab.on('click', function() {
128 var index = $(this).index(); 128 var index = $(this).index();
129 129
  130 + $('body').scrollTop(0);
  131 +
130 $swiperTab.removeClass('active').eq(index).addClass('active'); 132 $swiperTab.removeClass('active').eq(index).addClass('active');
131 133
132 if (self.$productTab.eq(index).find('li').length > 0) { 134 if (self.$productTab.eq(index).find('li').length > 0) {
@@ -398,6 +398,8 @@ function givePoint(parameter) { @@ -398,6 +398,8 @@ function givePoint(parameter) {
398 } 398 }
399 break; 399 break;
400 } 400 }
  401 + } else {
  402 + header.removeClass('girls', 'life-style', 'kids').addClass('boys');
401 } 403 }
402 }()); 404 }());
403 405
@@ -4,8 +4,7 @@ var $ = require('yoho-jquery'), @@ -4,8 +4,7 @@ var $ = require('yoho-jquery'),
4 loading = require('../plugin/loading'), 4 loading = require('../plugin/loading'),
5 debounce = require('lodash/debounce'); 5 debounce = require('lodash/debounce');
6 6
7 -var plusstar = {},  
8 - $footer = $('#yoho-footer'); 7 +var plusstar = {};
9 8
10 var windowHeight = $(window).height(); 9 var windowHeight = $(window).height();
11 var scrollFn, 10 var scrollFn,
@@ -186,6 +185,9 @@ plusstar = { @@ -186,6 +185,9 @@ plusstar = {
186 return true; 185 return true;
187 } 186 }
188 187
  188 + // 固定底部去除
  189 + window.rePosFooter();
  190 +
189 // 记录切换tab位置 191 // 记录切换tab位置
190 $(document).scrollTop(window.cookie(code) || 0); 192 $(document).scrollTop(window.cookie(code) || 0);
191 193
@@ -303,23 +305,17 @@ $(function() { @@ -303,23 +305,17 @@ $(function() {
303 apt: window.queryString.client_type || '', 305 apt: window.queryString.client_type || '',
304 sid: window.queryString.session_id || '', 306 sid: window.queryString.session_id || '',
305 }; 307 };
306 - }  
307 -  
308 - // 男:1,女:2,潮童:3,创意生活:4  
309 - speckParamApp.CID = window.queryString.yh_channel || window._ChannelVary[window.cookie('_Channel')] || 1;  
310 308
311 - if (!isApp) { 309 + $('.plusstar-resources').css({'margin-top': $('.tab-nav').height()});
  310 + } else {
312 $('.tab-nav').css({ 311 $('.tab-nav').css({
313 position: 'relative' 312 position: 'relative'
314 }); 313 });
315 -  
316 - $footer.css({  
317 - 'max-width': '650px'  
318 - }).before(  
319 - '<div style="height: ' + parseInt($footer.css('height'), 0) + 'px"></div>'  
320 - );  
321 } 314 }
322 315
  316 + // 男:1,女:2,潮童:3,创意生活:4
  317 + speckParamApp.CID = window.queryString.yh_channel || window._ChannelVary[window.cookie('_Channel')] || 1;
  318 +
323 plusstar.init(); 319 plusstar.init();
324 320
325 // 滚动翻页 321 // 滚动翻页
@@ -14,6 +14,8 @@ var tip = require('../../plugin/tip'); @@ -14,6 +14,8 @@ var tip = require('../../plugin/tip');
14 var trim = $.trim; 14 var trim = $.trim;
15 var showErrTip = tip.show; 15 var showErrTip = tip.show;
16 16
  17 +require('../../common');
  18 +
17 api.bindEyesEvt({ 19 api.bindEyesEvt({
18 status: 'open' // 默认眼睛打开 20 status: 'open' // 默认眼睛打开
19 }); 21 });
@@ -49,6 +51,16 @@ $btnSure.on('touchstart', function() { @@ -49,6 +51,16 @@ $btnSure.on('touchstart', function() {
49 var res = data.data; 51 var res = data.data;
50 52
51 if (data.code === 200) { 53 if (data.code === 200) {
  54 + // 统计代码:用于统计从哪个渠道注册成功的
  55 + if (window._yas && window._yas.sendCustomInfo) {
  56 + window._yas.sendCustomInfo({
  57 + op: 'YB_REGISTER_SUCCESS_L',
  58 + param: JSON.stringify({
  59 + C_ID: window._ChannelVary[window.cookie('_Channel')] || 1,
  60 + UNION_TYPE: window.queryString.union_type || window.cookie('unionTypeYas') || false
  61 + })
  62 + }, true);
  63 + }
52 showErrTip('注册成功'); 64 showErrTip('注册成功');
53 65
54 location.href = res.href; 66 location.href = res.href;
@@ -127,7 +127,7 @@ function render(data) { @@ -127,7 +127,7 @@ function render(data) {
127 $('#limitProductCode').val(data.cartInfo.limitProductCode).removeClass(dbClass); 127 $('#limitProductCode').val(data.cartInfo.limitProductCode).removeClass(dbClass);
128 } 128 }
129 } 129 }
130 - if (data.isCollect) { 130 + if (data.isCollect === true) {
131 $('#likeBtn').addClass('liked'); 131 $('#likeBtn').addClass('liked');
132 } 132 }
133 if (data.tickets) { 133 if (data.tickets) {
@@ -242,6 +242,7 @@ seckillObj = { @@ -242,6 +242,7 @@ seckillObj = {
242 data = $.extend(data, {isApp: yoho.isApp}); 242 data = $.extend(data, {isApp: yoho.isApp});
243 $('.product-list').html(self.listTemplate(data)); 243 $('.product-list').html(self.listTemplate(data));
244 lazyload('img.lazy'); 244 lazyload('img.lazy');
  245 + window.scrollTo(0, 0);
245 window.rePosFooter(); 246 window.rePosFooter();
246 }, 247 },
247 error: function(data) { 248 error: function(data) {
@@ -199,7 +199,7 @@ function getPageGoods(info) { @@ -199,7 +199,7 @@ function getPageGoods(info) {
199 url: info.url, 199 url: info.url,
200 data: info.data, 200 data: info.data,
201 success: function(data) { 201 success: function(data) {
202 - if (data === ' ') { 202 + if (data === '') {
203 nav.end = true; 203 nav.end = true;
204 } 204 }
205 205
@@ -325,6 +325,7 @@ var theY; @@ -325,6 +325,7 @@ var theY;
325 */ 325 */
326 function reNav1Pos() { 326 function reNav1Pos() {
327 var sTop = theY ? theY : 0; 327 var sTop = theY ? theY : 0;
  328 +
328 if (sTop < imgH + main1oH + nav1H) { 329 if (sTop < imgH + main1oH + nav1H) {
329 if ($nav1.hasClass('hide')) { 330 if ($nav1.hasClass('hide')) {
330 $nav1.removeClass('hide'); 331 $nav1.removeClass('hide');
@@ -385,6 +386,7 @@ function scrollHandler() { @@ -385,6 +386,7 @@ function scrollHandler() {
385 if (sTop + winH * 2 > scH) { 386 if (sTop + winH * 2 > scH) {
386 scrollCall = function() { 387 scrollCall = function() {
387 var translate = 'translate3d(0, ' + (-scH) + 'px, 0)'; 388 var translate = 'translate3d(0, ' + (-scH) + 'px, 0)';
  389 +
388 $nav1.css({ 390 $nav1.css({
389 transform: translate, 391 transform: translate,
390 '-moz-transform': translate, 392 '-moz-transform': translate,
@@ -681,7 +683,7 @@ function search(opt) { @@ -681,7 +683,7 @@ function search(opt) {
681 break; 683 break;
682 } 684 }
683 685
684 - if (data === ' ') { 686 + if (data === '') {
685 nav.end = true; 687 nav.end = true;
686 688
687 if (nav.reload) { 689 if (nav.reload) {
@@ -929,6 +931,7 @@ $nav2.on('touchstart', 'li', function(e) { @@ -929,6 +931,7 @@ $nav2.on('touchstart', 'li', function(e) {
929 931
930 $('.shop-foot-wrapper .buriedpoint').click(function() { 932 $('.shop-foot-wrapper .buriedpoint').click(function() {
931 var subGroup = $(this).find('.sub-group'); 933 var subGroup = $(this).find('.sub-group');
  934 +
932 if (subGroup.hasClass('hide')) { 935 if (subGroup.hasClass('hide')) {
933 subGroup.removeClass('hide'); 936 subGroup.removeClass('hide');
934 } else { 937 } else {
@@ -18,12 +18,13 @@ @@ -18,12 +18,13 @@
18 position: fixed; 18 position: fixed;
19 z-index: 10; 19 z-index: 10;
20 background-color: #fff; 20 background-color: #fff;
  21 + top: 0;
21 22
22 li { 23 li {
23 display: block; 24 display: block;
24 float: left; 25 float: left;
25 height: 100%; 26 height: 100%;
26 - width: 33.33%; 27 + width: 50%;
27 line-height: 60px; 28 line-height: 60px;
28 color: #999; 29 color: #999;
29 white-space: nowrap; 30 white-space: nowrap;