Authored by 沈志敏

Merge branch 'release/5.2' of git.yoho.cn:fe/yohobuywap-node into release/5.2

@@ -7,6 +7,9 @@ @@ -7,6 +7,9 @@
7 7
8 const mRoot = '../models'; 8 const mRoot = '../models';
9 const rssModel = require(`${mRoot}/rss`); 9 const rssModel = require(`${mRoot}/rss`);
  10 +const Feed = require('feed');
  11 +const _ = require('lodash');
  12 +const moment = require('moment');
10 const helpers = global.yoho.helpers; 13 const helpers = global.yoho.helpers;
11 14
12 /** 15 /**
@@ -15,18 +18,40 @@ const helpers = global.yoho.helpers; @@ -15,18 +18,40 @@ const helpers = global.yoho.helpers;
15 const index = (req, res, next) => { 18 const index = (req, res, next) => {
16 let gender = req.query.gender || '1,2,3', 19 let gender = req.query.gender || '1,2,3',
17 items = []; 20 items = [];
18 -  
19 - res.setHeader('Content-Type', 'text/xml; charset=utf-8');  
20 return rssModel.getRssArticle(gender).then((result) => { 21 return rssModel.getRssArticle(gender).then((result) => {
21 - return res.render('rss/index', {  
22 - layout: false,  
23 - time: (new Date()).toUTCString(),  
24 - items: result 22 + if (!result) {
  23 + return next();
  24 + }
  25 + res.setHeader('Content-Type', 'text/xml; charset=utf-8');
  26 + var feed = new Feed({
  27 + id: 'http://yohobuy.com',
  28 + title: '有货逛',
  29 + description: 'Yoho!Buy有货 | 年轻人潮流购物中心',
  30 + link: 'http://yohobuy.com',
  31 + copyright: '2015 yoho.inc',
  32 + generator: 'http://m.yohobuy.com',
  33 + updated: new Date(),
  34 + })
  35 + _.forEach(result, item => {
  36 + item.url = item.url.indexOf('http') > 0 ? item.url : 'http://'+item.url
  37 + feed.addItem({
  38 + title: item.title,
  39 + link: `${item.url}&ref=rss`,
  40 + description: item.intro,
  41 + author: [{
  42 + name: (item.author && item.author.name) || ' '
  43 + }],
  44 + date: new Date(item.publishTimeLong && parseFloat(item.publishTimeLong) || moment(item.publishTime, "MM月DD日 HH:mm"))
  45 + });
25 }); 46 });
  47 + if (req.params[0] && req.params[0] === '/atom') {
  48 + return res.send(feed.render('atom-1.0'));
  49 + }
  50 + return res.send(feed.render('rss-2.0'))
26 }); 51 });
27 }; 52 };
28 53
29 54
30 module.exports = { 55 module.exports = {
31 index 56 index
32 -}; 57 +};
@@ -44,7 +44,8 @@ const getRssArticle = (gender) => { @@ -44,7 +44,8 @@ const getRssArticle = (gender) => {
44 44
45 if (typeof value.id !== 'undefined') { 45 if (typeof value.id !== 'undefined') {
46 build = guangProcess.formatArticle(value, false, false, true); 46 build = guangProcess.formatArticle(value, false, false, true);
47 - build.author.name = (build.author && build.author.name) || ''; 47 + build.author = build.author || {};
  48 + build.author.name = (build.author && build.author.name) || ''
48 return _genIntro(value.id).then((intro) => { 49 return _genIntro(value.id).then((intro) => {
49 build.intro = intro; 50 build.intro = intro;
50 result.push(build); 51 result.push(build);
@@ -54,7 +54,7 @@ router.get('/plustar', plustar.getListData); // 国际优选列表页 @@ -54,7 +54,7 @@ router.get('/plustar', plustar.getListData); // 国际优选列表页
54 router.get('/plustar/brandinfo', plustar.getDetailData); // 国际优选详情页 54 router.get('/plustar/brandinfo', plustar.getDetailData); // 国际优选详情页
55 router.post('/plustar/brandinfoAsync', plustar.getDetailDataAsync); // 国际优选详情页异步数据 55 router.post('/plustar/brandinfoAsync', plustar.getDetailDataAsync); // 国际优选详情页异步数据
56 56
57 -router.get('/rss', rss.index); // 订阅资讯 57 +router.get(/^\/rss(\/\w+)?(\/\w+)?/, rss.index); // 订阅资讯
58 58
59 router.get('/info/listData', index.listDynamicData); 59 router.get('/info/listData', index.listDynamicData);
60 router.get('/info/detailData', index.detailDynamicData); 60 router.get('/info/detailData', index.detailDynamicData);
@@ -1744,6 +1744,7 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -1744,6 +1744,7 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
1744 } 1744 }
1745 let soldOut = (origin.storage_sum === 0) || (totalStorageNum === 0); // status 1745 let soldOut = (origin.storage_sum === 0) || (totalStorageNum === 0); // status
1746 let notForSale = origin.attribute === 2; 1746 let notForSale = origin.attribute === 2;
  1747 + let preSale = (origin.status === 0 && origin.advance_shelve_time > 0);
1747 1748
1748 // 悬浮的购物车信息 1749 // 悬浮的购物车信息
1749 dest.cartInfo = { 1750 dest.cartInfo = {
@@ -1753,7 +1754,7 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -1753,7 +1754,7 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
1753 }; 1754 };
1754 1755
1755 // 显示加入购物车链接 1756 // 显示加入购物车链接
1756 - if (!soldOut && !notForSale || origin.isLimitBuy) { 1757 + if (!soldOut && !notForSale && !preSale || origin.isLimitBuy) {
1757 _.orderBy(colorGroup); 1758 _.orderBy(colorGroup);
1758 Object.assign(dest.cartInfo, { 1759 Object.assign(dest.cartInfo, {
1759 productId: origin.product_id, 1760 productId: origin.product_id,
@@ -1808,12 +1809,15 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => { @@ -1808,12 +1809,15 @@ let _detailDataPkgAsync = (origin, uid, vipLevel, ua) => {
1808 origin.goods_id + '.html'); 1809 origin.goods_id + '.html');
1809 return callback(); 1810 return callback();
1810 } 1811 }
1811 - } else if (notForSale) { 1812 + } else if (notForSale && !preSale) {
1812 dest.cartInfo.notForSale = true; 1813 dest.cartInfo.notForSale = true;
1813 return callback(); 1814 return callback();
1814 - } else if (soldOut) { 1815 + } else if (soldOut && !preSale) {
1815 dest.cartInfo.soldOut = true; 1816 dest.cartInfo.soldOut = true;
1816 return callback(); 1817 return callback();
  1818 + } else if (preSale) {
  1819 + dest.cartInfo.preSale = true;
  1820 + return callback();
1817 } 1821 }
1818 1822
1819 // 是否收藏 使用单独收藏接口获取 1823 // 是否收藏 使用单独收藏接口获取
@@ -140,6 +140,7 @@ @@ -140,6 +140,7 @@
140 <a id="soldOut" href="javascript:;" class="sold-out data-bind">已售罄</a> 140 <a id="soldOut" href="javascript:;" class="sold-out data-bind">已售罄</a>
141 <a id="notForSale" href="javascript:;" class="sold-out data-bind">非卖品</a> 141 <a id="notForSale" href="javascript:;" class="sold-out data-bind">非卖品</a>
142 <a id="limitNotForSale" href="javascript:;" class="sold-out limit data-bind">即将发售</a> 142 <a id="limitNotForSale" href="javascript:;" class="sold-out limit data-bind">即将发售</a>
  143 + <a id="preSale" href="javascript:;" class="sold-out limit data-bind">即将开售</a>
143 <a href="javascript:;" id="addtoCart" class="addto-cart can-buy-limit data-bind">立即购买</a> 144 <a href="javascript:;" id="addtoCart" class="addto-cart can-buy-limit data-bind">立即购买</a>
144 <a id="noLimitCode" href="javascript:;" class="sold-out limit data-bind">立即购买</a> 145 <a id="noLimitCode" href="javascript:;" class="sold-out limit data-bind">立即购买</a>
145 <input type="hidden" id="limitCodeUrl" name="limitCodeUrl" value=""> 146 <input type="hidden" id="limitCodeUrl" name="limitCodeUrl" value="">
@@ -17,9 +17,9 @@ @@ -17,9 +17,9 @@
17 </li> 17 </li>
18 {{/data}} 18 {{/data}}
19 </ul> 19 </ul>
20 - {{/if}}  
21 - <div class="swiper-pagination">  
22 - <div class="pagination-inner"> 20 + <div class="swiper-pagination">
  21 + <div class="pagination-inner">
  22 + </div>
23 </div> 23 </div>
24 - </div> 24 + {{/if}}
25 </div> 25 </div>
@@ -27,6 +27,7 @@ @@ -27,6 +27,7 @@
27 "cookie-parser": "^1.4.3", 27 "cookie-parser": "^1.4.3",
28 "cookie-session": "^1.2.0", 28 "cookie-session": "^1.2.0",
29 "express": "^4.14.0", 29 "express": "^4.14.0",
  30 + "feed": "^0.3.0",
30 "lodash": "^4.16.1", 31 "lodash": "^4.16.1",
31 "md5": "^2.1.0", 32 "md5": "^2.1.0",
32 "moment": "^2.15.1", 33 "moment": "^2.15.1",
@@ -11,8 +11,7 @@ var $ = require('yoho-jquery'), @@ -11,8 +11,7 @@ var $ = require('yoho-jquery'),
11 11
12 var bannerSwiper; 12 var bannerSwiper;
13 13
14 -var C_ID,  
15 - getChannel; 14 +var C_ID;
16 15
17 // 获取url中的参数 16 // 获取url中的参数
18 function getUrlParam(name) { 17 function getUrlParam(name) {
@@ -120,6 +120,9 @@ function render(data) { @@ -120,6 +120,9 @@ function render(data) {
120 if (data.cartInfo.canNotBuy) { 120 if (data.cartInfo.canNotBuy) {
121 $('#noLimitCode').removeClass(dbClass); 121 $('#noLimitCode').removeClass(dbClass);
122 } 122 }
  123 + if (data.cartInfo.preSale) {
  124 + $('#preSale').removeClass(dbClass);
  125 + }
123 $('.cart-bar').removeClass('data-bind'); 126 $('.cart-bar').removeClass('data-bind');
124 $('#limitCodeUrl').val(data.cartInfo.limitCodeUrl); 127 $('#limitCodeUrl').val(data.cartInfo.limitCodeUrl);
125 $('#limitProductPay').val(data.cartInfo.limitProductPay); 128 $('#limitProductPay').val(data.cartInfo.limitProductPay);
@@ -202,7 +202,7 @@ $search.on('touchend', function() { @@ -202,7 +202,7 @@ $search.on('touchend', function() {
202 */ 202 */
203 function getQueryString(name) { 203 function getQueryString(name) {
204 var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); 204 var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
205 - var r = window.location.search.substr(1).match(reg); 205 + var r = decodeURI(window.location.search).substr(1).match(reg);
206 206
207 if (r !== null) { 207 if (r !== null) {
208 return window.unescape(r[2]); 208 return window.unescape(r[2]);
1 .banner-center { 1 .banner-center {
2 position: relative; 2 position: relative;
3 height: 200px; 3 height: 200px;
4 - border-bottom: 1px solid #e0e0e0;  
5 overflow: hidden; 4 overflow: hidden;
6 5
7 img { 6 img {
@@ -47,7 +46,6 @@ @@ -47,7 +46,6 @@
47 background: #fff; 46 background: #fff;
48 width: 100%; 47 width: 100%;
49 height: 200px; 48 height: 200px;
50 - border-top: 1px solid #e0e0e0;  
51 overflow: hidden; 49 overflow: hidden;
52 50
53 .banner-list { 51 .banner-list {
@@ -10,7 +10,6 @@ @@ -10,7 +10,6 @@
10 } 10 }
11 11
12 &-goods-list { 12 &-goods-list {
13 - height: 330px;  
14 width: 100%; 13 width: 100%;
15 overflow-x: scroll; 14 overflow-x: scroll;
16 overflow-y: hidden; 15 overflow-y: hidden;
@@ -39,28 +38,30 @@ @@ -39,28 +38,30 @@
39 38
40 .goods-info { 39 .goods-info {
41 position: relative; 40 position: relative;
42 - height: 84px;  
43 - width: 100%; 41 + height: 168px;
  42 + width: 200%;
44 background: #fff; 43 background: #fff;
45 - padding: 12px 0 10px 10px; 44 + padding: 24px 0 20px 20px;
  45 + transform: scale(0.5);
  46 + transform-origin: 0 0 0;
46 47
47 .price { 48 .price {
48 color: #444; 49 color: #444;
49 - font-size: 20px; 50 + font-size: 40px;
50 line-height: 1; 51 line-height: 1;
51 } 52 }
52 53
53 .view-num { 54 .view-num {
54 color: #b0b0b0; 55 color: #b0b0b0;
55 - font-size: 15px;  
56 - margin-top: 10px; 56 + font-size: 30px;
  57 + margin-top: 20px;
57 line-height: 1; 58 line-height: 1;
58 } 59 }
59 60
60 .view-status { 61 .view-status {
61 color: #b0b0b0; 62 color: #b0b0b0;
62 - font-size: 15px;  
63 - margin-top: 7px; 63 + font-size: 30px;
  64 + margin-top: 14px;
64 line-height: 1; 65 line-height: 1;
65 } 66 }
66 67
@@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
3 position: relative; 3 position: relative;
4 background: #fff; 4 background: #fff;
5 -webkit-overflow-scrolling: touch; 5 -webkit-overflow-scrolling: touch;
  6 +
6 7
7 &-banner { 8 &-banner {
8 height: 200px; 9 height: 200px;
@@ -11,7 +12,6 @@ @@ -11,7 +12,6 @@
11 } 12 }
12 13
13 &-goods-list { 14 &-goods-list {
14 - height: 330px;  
15 width: 100%; 15 width: 100%;
16 overflow-x: scroll; 16 overflow-x: scroll;
17 overflow-y: hidden; 17 overflow-y: hidden;
@@ -40,31 +40,33 @@ @@ -40,31 +40,33 @@
40 40
41 .goods-info { 41 .goods-info {
42 position: relative; 42 position: relative;
43 - height: 84px;  
44 - width: 100%; 43 + height: 168px;
  44 + width: 200%;
45 background: #fff; 45 background: #fff;
46 - padding: 14px 0 10px 10px; 46 + padding: 28px 0 20px 20px;
  47 + transform: scale(0.5);
  48 + transform-origin: 0 0 0;
47 49
48 .vip-price { 50 .vip-price {
49 display: none; 51 display: none;
50 color: #d0021b; 52 color: #d0021b;
51 - font-size: 20px; 53 + font-size: 40px;
52 line-height: 1; 54 line-height: 1;
53 } 55 }
54 56
55 .sale-price { 57 .sale-price {
56 color: #b0b0b0; 58 color: #b0b0b0;
57 - font-size: 15px;  
58 - line-height: 20px; 59 + font-size: 30px;
  60 + line-height: 40px;
59 text-decoration: line-through; 61 text-decoration: line-through;
60 - margin-top: 12px; 62 + margin-top: 24px;
61 } 63 }
62 64
63 .vip-icon { 65 .vip-icon {
64 display: inline-block; 66 display: inline-block;
65 - height: 20px;  
66 - width: 50px;  
67 - margin-left: 8px; 67 + height: 40px;
  68 + width: 100px;
  69 + margin-left: 16px;
68 vertical-align: middle; 70 vertical-align: middle;
69 background: resolve('channel/vip.png'); 71 background: resolve('channel/vip.png');
70 background-size: 100% 100%; 72 background-size: 100% 100%;
@@ -97,7 +97,8 @@ @@ -97,7 +97,8 @@
97 } 97 }
98 98
99 .open-icon-1 { 99 .open-icon-1 {
100 - background: url("/home/installment-icon1.png") no-repeat; 100 + background: resolve("home/installment-icon1.png") no-repeat;
  101 + background-size: contain;
101 width: 67px; 102 width: 67px;
102 height: 67px; 103 height: 67px;
103 display: block; 104 display: block;
@@ -105,7 +106,8 @@ @@ -105,7 +106,8 @@
105 } 106 }
106 107
107 .open-icon-2 { 108 .open-icon-2 {
108 - background: url("/home/installment-icon2.png") no-repeat; 109 + background: resolve("home/installment-icon2.png") no-repeat;
  110 + background-size: contain;
109 width: 67px; 111 width: 67px;
110 height: 67px; 112 height: 67px;
111 display: block; 113 display: block;
@@ -113,7 +115,8 @@ @@ -113,7 +115,8 @@
113 } 115 }
114 116
115 .open-icon-3 { 117 .open-icon-3 {
116 - background: url("/home/installment-icon3.png") no-repeat; 118 + background: resolve("home/installment-icon3.png") no-repeat;
  119 + background-size: contain;
117 width: 67px; 120 width: 67px;
118 height: 67px; 121 height: 67px;
119 display: block; 122 display: block;
@@ -431,7 +434,7 @@ @@ -431,7 +434,7 @@
431 color: #fff; 434 color: #fff;
432 display: block; 435 display: block;
433 margin: 30px auto 0; 436 margin: 30px auto 0;
434 - font-size: 26px; 437 + font-size: 22px;
435 } 438 }
436 } 439 }
437 440
@@ -498,7 +501,7 @@ @@ -498,7 +501,7 @@
498 501
499 .usable-area { 502 .usable-area {
500 position: relative; 503 position: relative;
501 - height: 330px; 504 + height: 325px;
502 505
503 .replay-status { 506 .replay-status {
504 position: absolute; 507 position: absolute;
@@ -68,6 +68,7 @@ const formatArticle = (articleData, showTag, isApp, showAuthor, uid, reqQueryStr @@ -68,6 +68,7 @@ const formatArticle = (articleData, showTag, isApp, showAuthor, uid, reqQueryStr
68 title: articleData.title, 68 title: articleData.title,
69 text: articleData.intro, 69 text: articleData.intro,
70 publishTime: articleData.publish_time, 70 publishTime: articleData.publish_time,
  71 + publishTimeLong: articleData.publish_time_long,
71 pageView: articleData.views_num 72 pageView: articleData.views_num
72 }; 73 };
73 74