Authored by 周少峰

Merge branch 'master' into feature/students

@@ -9,6 +9,8 @@ @@ -9,6 +9,8 @@
9 const helpers = global.yoho.helpers; 9 const helpers = global.yoho.helpers;
10 const mRoot = '../models'; 10 const mRoot = '../models';
11 const service = require(`${mRoot}/detail-service`); 11 const service = require(`${mRoot}/detail-service`);
  12 +const detailHelper = require(`${mRoot}/detail-helper`);
  13 +
12 const Actions = require('./lib/actions'); 14 const Actions = require('./lib/actions');
13 const YohoAction = require('./lib/yoho-action'); 15 const YohoAction = require('./lib/yoho-action');
14 const moment = require('moment'); 16 const moment = require('moment');
@@ -26,7 +28,7 @@ class DetailAction extends YohoAction { @@ -26,7 +28,7 @@ class DetailAction extends YohoAction {
26 let pid = req.params[0]; 28 let pid = req.params[0];
27 let gid = req.params[1]; 29 let gid = req.params[1];
28 let uid = req.user.uid || ''; 30 let uid = req.user.uid || '';
29 - let vipLevel = req.user.vip || ''; 31 + let vipLevel = detailHelper.vipLevel(req.user.vip);
30 32
31 return service.showMainAsync({ 33 return service.showMainAsync({
32 pid: pid, 34 pid: pid,
@@ -43,9 +45,7 @@ class DetailAction extends YohoAction { @@ -43,9 +45,7 @@ class DetailAction extends YohoAction {
43 this.setDescription(seo.description, true); 45 this.setDescription(seo.description, true);
44 46
45 this.setEntry('product', 'detail'); 47 this.setEntry('product', 'detail');
46 - this.renderTemplate('product/detail', Object.assign({  
47 - headerData: result.headerData  
48 - }, result)); 48 + this.renderTemplate('product/detail', result);
49 }).catch(err => { 49 }).catch(err => {
50 if (err.code === 404) { 50 if (err.code === 404) {
51 return this.next(); 51 return this.next();
@@ -46,12 +46,29 @@ const getGenderByCookie = (req) => { @@ -46,12 +46,29 @@ const getGenderByCookie = (req) => {
46 return gender; 46 return gender;
47 }; 47 };
48 48
  49 +const vipLevel = (vipTitle) => {
  50 + return (function(title) {
  51 + if (title === '普通会员') {
  52 + return 0;
  53 + } else if (title === '银卡会员') {
  54 + return 1;
  55 + } else if (title === '金卡会员') {
  56 + return 2;
  57 + } else if (title === '白金会员') {
  58 + return 3;
  59 + } else {
  60 + return 0;
  61 + }
  62 + }(vipTitle));
  63 +};
  64 +
49 module.exports = { 65 module.exports = {
50 COOKIE_NAME_BOYS, 66 COOKIE_NAME_BOYS,
51 COOKIE_DOMAIN, 67 COOKIE_DOMAIN,
52 DEFAULT_AVATAR_ICO, 68 DEFAULT_AVATAR_ICO,
53 IMAGE_SERVICE_URL, 69 IMAGE_SERVICE_URL,
54 setSwitchToCookie, 70 setSwitchToCookie,
55 - getGenderByCookie 71 + getGenderByCookie,
  72 + vipLevel
56 }; 73 };
57 74
@@ -31,7 +31,7 @@ const BLANK_STR = ' '; @@ -31,7 +31,7 @@ const BLANK_STR = ' ';
31 const cachedRequestData = {}; 31 const cachedRequestData = {};
32 32
33 // 展览票 33 // 展览票
34 -const EXHIBITION_TICKET = 512579596; 34 +const EXHIBITION_TICKET = 51335912;
35 35
36 const _getProductAdditionInfoAsync = (data) => { 36 const _getProductAdditionInfoAsync = (data) => {
37 return co(function * () { 37 return co(function * () {
@@ -381,19 +381,19 @@ const _getSkuDataByProductBaseInfo = (data) => { @@ -381,19 +381,19 @@ const _getSkuDataByProductBaseInfo = (data) => {
381 goodsGroup.size.push({ 381 goodsGroup.size.push({
382 name: size.sizeName, 382 name: size.sizeName,
383 sku: size.goodsSizeSkuId, 383 sku: size.goodsSizeSkuId,
384 - num: parseInt(size.goodsSizeStorageNum, 10), 384 + num: parseInt(size.goodsSizeStorageNum),
385 goodsId: size.goodsId 385 goodsId: size.goodsId
386 }); 386 });
387 387
388 // 单个sku商品的总数 388 // 单个sku商品的总数
389 - goodsGroup.total += parseInt(size.goodsSizeStorageNum, 10); 389 + goodsGroup.total += parseInt(size.goodsSizeStorageNum);
390 390
391 if (goodsGroup.total > 0 && !chooseSkuFlag) { // 默认选中该sku商品 391 if (goodsGroup.total > 0 && !chooseSkuFlag) { // 默认选中该sku商品
392 goodsGroup.focus = true; 392 goodsGroup.focus = true;
393 chooseSkuFlag = true;// 选中sku商品 393 chooseSkuFlag = true;// 选中sku商品
394 } 394 }
395 395
396 - totalStorageNum += parseInt(size.goodsSizeStorageNum, 10); 396 + totalStorageNum += parseInt(size.goodsSizeStorageNum);
397 397
398 }); 398 });
399 399
@@ -423,14 +423,14 @@ const _getSkuDataByProductBaseInfo = (data) => { @@ -423,14 +423,14 @@ const _getSkuDataByProductBaseInfo = (data) => {
423 const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => { 423 const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
424 // 潮流尖货状态 424 // 潮流尖货状态
425 // getLimitedCode //限购码状态 425 // getLimitedCode //限购码状态
426 - // hasLimitedCode //是否已经获取限购码 426 + // hadLimitedCode //是否已经获取限购码
427 // limitedCodeSoldOut //限购码是否已经抢光 427 // limitedCodeSoldOut //限购码是否已经抢光
428 // openSoon//即将开售 428 // openSoon//即将开售
429 // dis //失效 429 // dis //失效
430 // buyNow //是否立即购买 430 // buyNow //是否立即购买
431 let result = { 431 let result = {
432 getLimitedCode: true, 432 getLimitedCode: true,
433 - hasLimitedCode: false, 433 + hadLimitedCode: false,
434 limitedCodeSoldOut: false, 434 limitedCodeSoldOut: false,
435 openSoon: false, 435 openSoon: false,
436 dis: false, 436 dis: false,
@@ -447,7 +447,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => { @@ -447,7 +447,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
447 result.dis = true; 447 result.dis = true;
448 } else { 448 } else {
449 result.openSoon = true; 449 result.openSoon = true;
450 - result.hasLimitedCode = false; 450 + result.hadLimitedCode = false;
451 } 451 }
452 break; 452 break;
453 case 2: // 开售后,限购码已抢光(用户未领取限购码) 453 case 2: // 开售后,限购码已抢光(用户未领取限购码)
@@ -455,7 +455,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => { @@ -455,7 +455,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
455 result.dis = true; 455 result.dis = true;
456 result.limitedCodeSoldOut = true; 456 result.limitedCodeSoldOut = true;
457 result.getLimitedCode = false; 457 result.getLimitedCode = false;
458 - result.hasLimitedCode = false; 458 + result.hadLimitedCode = false;
459 break; 459 break;
460 case 3: // 开售后,商品已经售罄 460 case 3: // 开售后,商品已经售罄
461 result.soldOut = true; 461 result.soldOut = true;
@@ -464,20 +464,20 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => { @@ -464,20 +464,20 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
464 case 4:// 开售后,立即购买(用户已领取限购码) 464 case 4:// 开售后,立即购买(用户已领取限购码)
465 result.buyNow = true; 465 result.buyNow = true;
466 result.dis = false; 466 result.dis = false;
467 - result.hasLimitedCode = true; 467 + result.hadLimitedCode = true;
468 if (uid) { // 限购码失效 468 if (uid) { // 限购码失效
469 result.getLimitedCodeDis = true; 469 result.getLimitedCodeDis = true;
470 } 470 }
471 break; 471 break;
472 case 5: // 开售前,限购码已被抢光(用户未领取限购码) 472 case 5: // 开售前,限购码已被抢光(用户未领取限购码)
473 result.openSoon = true; 473 result.openSoon = true;
474 - result.hasLimitedCode = true; 474 + result.hadLimitedCode = true;
475 result.limitedCodeSoldOut = true; 475 result.limitedCodeSoldOut = true;
476 result.getLimitedCode = false; 476 result.getLimitedCode = false;
477 break; 477 break;
478 case 6: // 开售前,即将开售(用户已领取限购码) 478 case 6: // 开售前,即将开售(用户已领取限购码)
479 result.openSoon = true; 479 result.openSoon = true;
480 - result.hasLimitedCode = true; 480 + result.hadLimitedCode = true;
481 if (uid) { // 限购码失效 481 if (uid) { // 限购码失效
482 result.getLimitedCodeDis = true; 482 result.getLimitedCodeDis = true;
483 } 483 }
@@ -485,7 +485,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => { @@ -485,7 +485,7 @@ const _getFashionTopGoodsStatus = (uid, showStatus, isBeginSale) => {
485 case 7: // 开售后,用户已经用获得的限购码购买过商品 485 case 7: // 开售后,用户已经用获得的限购码购买过商品
486 result.buyNow = true; 486 result.buyNow = true;
487 result.dis = true; 487 result.dis = true;
488 - result.hasLimitedCode = true; 488 + result.hadLimitedCode = true;
489 if (uid) { // 限购码失效 489 if (uid) { // 限购码失效
490 result.getLimitedCodeDis = true; 490 result.getLimitedCodeDis = true;
491 } 491 }
@@ -571,7 +571,7 @@ const _detailDataPkg = (origin, uid, vipLevel) => { @@ -571,7 +571,7 @@ const _detailDataPkg = (origin, uid, vipLevel) => {
571 result.tags = _getTagsDataByProductInfo(origin); 571 result.tags = _getTagsDataByProductInfo(origin);
572 572
573 // 商品促销短语 573 // 商品促销短语
574 - if (origin.salesPhase) { 574 + if (origin.salesPhrase) {
575 result.saleTip = origin.salesPhrase; 575 result.saleTip = origin.salesPhrase;
576 } 576 }
577 577
@@ -596,7 +596,6 @@ const _detailDataPkg = (origin, uid, vipLevel) => { @@ -596,7 +596,6 @@ const _detailDataPkg = (origin, uid, vipLevel) => {
596 // VIP学生数据 596 // VIP学生数据
597 result.vipPrice = _getVipDataByProductBaseInfo(origin, vipLevel, uid); 597 result.vipPrice = _getVipDataByProductBaseInfo(origin, vipLevel, uid);
598 } 598 }
599 -  
600 // 促销活动banner,虚拟商品无促销 599 // 促销活动banner,虚拟商品无促销
601 if (origin.attribute !== 3) { 600 if (origin.attribute !== 3) {
602 result.activity = _getActivityDataByProductBaseInfo(origin); 601 result.activity = _getActivityDataByProductBaseInfo(origin);
@@ -662,9 +661,9 @@ const _detailDataPkg = (origin, uid, vipLevel) => { @@ -662,9 +661,9 @@ const _detailDataPkg = (origin, uid, vipLevel) => {
662 661
663 let fashTopGoods = _getFashionTopGoodsStatus(uid, showStatus, isBeginSale); 662 let fashTopGoods = _getFashionTopGoodsStatus(uid, showStatus, isBeginSale);
664 663
665 - result.fashTopGoods = { 664 + result.fashionTopGoods = {
666 getLimitedCode: fashTopGoods.getLimitedCode, // 限购码状态 665 getLimitedCode: fashTopGoods.getLimitedCode, // 限购码状态
667 - hasLimitedCode: fashTopGoods.hasLimitedCode, // 是否已经获取限购码 666 + hadLimitedCode: fashTopGoods.hadLimitedCode, // 是否已经获取限购码
668 limitedCodeSoldOut: fashTopGoods.limitedCodeSoldOut, // 限购码是否已经抢光 667 limitedCodeSoldOut: fashTopGoods.limitedCodeSoldOut, // 限购码是否已经抢光
669 getLimitedCodeDis: fashTopGoods.getLimitedCodeDis // 限购码是否失效 668 getLimitedCodeDis: fashTopGoods.getLimitedCodeDis // 限购码是否失效
670 }; 669 };
@@ -757,7 +756,9 @@ const _detailDataPkg = (origin, uid, vipLevel) => { @@ -757,7 +756,9 @@ const _detailDataPkg = (origin, uid, vipLevel) => {
757 banner.bgImg = basisData.shopTopBanner.banner || banner.bgImg; 756 banner.bgImg = basisData.shopTopBanner.banner || banner.bgImg;
758 break; 757 break;
759 default: 758 default:
760 - break; 759 + {
  760 + break;
  761 + }
761 } 762 }
762 } 763 }
763 } 764 }
@@ -765,7 +766,7 @@ const _detailDataPkg = (origin, uid, vipLevel) => { @@ -765,7 +766,7 @@ const _detailDataPkg = (origin, uid, vipLevel) => {
765 statGoodsInfo.imageUrl = result.img; 766 statGoodsInfo.imageUrl = result.img;
766 statGoodsInfo.productUrl = result.weixinUrl; 767 statGoodsInfo.productUrl = result.weixinUrl;
767 statGoodsInfo.smallSortId = result.smallSortId; 768 statGoodsInfo.smallSortId = result.smallSortId;
768 - statGoodsInfo.soldOut = parseInt(soldOut, 10); 769 + statGoodsInfo.soldOut = parseInt(soldOut);
769 770
770 return { 771 return {
771 goodsInfo: result, 772 goodsInfo: result,
@@ -1130,8 +1131,8 @@ const _getDetailDataBySizeInfo = (sizeInfo) => { @@ -1130,8 +1131,8 @@ const _getDetailDataBySizeInfo = (sizeInfo) => {
1130 let details = ''; 1131 let details = '';
1131 1132
1132 // 详情配图 1133 // 详情配图
1133 - if (sizeInfo.productIntroBo.productIntro) {  
1134 - if (sizeInfo.productDescBo.phrase) { 1134 + if (_.get(sizeInfo, 'productIntroBo.productIntro', null)) {
  1135 + if (_.get(sizeInfo, 'productIntroBo.phrase', null)) {
1135 details += `${sizeInfo.productDescBo.phrase}<br/>`; 1136 details += `${sizeInfo.productDescBo.phrase}<br/>`;
1136 } 1137 }
1137 } 1138 }
@@ -1144,7 +1145,7 @@ const _getDetailDataBySizeInfo = (sizeInfo) => { @@ -1144,7 +1145,7 @@ const _getDetailDataBySizeInfo = (sizeInfo) => {
1144 '///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw==" data-original=' 1145 '///93d3f///yH5BAEAAAMALAAAAAABAAEAAAICVAEAOw==" data-original='
1145 }; 1146 };
1146 1147
1147 - let intro = sizeInfo.productIntroBo.productIntro; 1148 + let intro = _.get(sizeInfo, 'productIntroBo.productIntro', '');
1148 1149
1149 _(replacePairs).forEach((value, key)=> { 1150 _(replacePairs).forEach((value, key)=> {
1150 intro = _.replace(intro, key, value); 1151 intro = _.replace(intro, key, value);
@@ -5,14 +5,26 @@ @@ -5,14 +5,26 @@
5 'use strict'; 5 'use strict';
6 6
7 const api = global.yoho.API; 7 const api = global.yoho.API;
  8 +const favApi = global.yoho.FavAPI;
8 9
9 const isFavoriteAsync = (uid, pid) => { 10 const isFavoriteAsync = (uid, pid) => {
10 - return api.get('', {  
11 - method: 'app.favorite.isFavorite',  
12 - id: pid,  
13 - uid: uid,  
14 - type: 'product'  
15 - }); 11 + let onNewApi = false;
  12 +
  13 + if (onNewApi) {
  14 + return favApi.get('', {
  15 + method: 'app.favorite.isFavoriteNew',
  16 + id: pid,
  17 + uid: uid,
  18 + type: 'product'
  19 + });
  20 + } else {
  21 + return api.get('', {
  22 + method: 'app.favorite.isFavorite',
  23 + id: pid,
  24 + uid: uid,
  25 + type: 'product'
  26 + });
  27 + }
16 }; 28 };
17 29
18 const createAsync = (uid, pid) => { 30 const createAsync = (uid, pid) => {
@@ -37,6 +37,7 @@ const discountSplit = (text) => { @@ -37,6 +37,7 @@ const discountSplit = (text) => {
37 i; 37 i;
38 38
39 text = text || ''; 39 text = text || '';
  40 +
40 for (i = 0; i < text.length; i++) { 41 for (i = 0; i < text.length; i++) {
41 if (/^([0-9]|\%)*$/.test(text[i])) { 42 if (/^([0-9]|\%)*$/.test(text[i])) {
42 endNum = i + 1; 43 endNum = i + 1;
@@ -224,7 +224,7 @@ @@ -224,7 +224,7 @@
224 {{/unless}} 224 {{/unless}}
225 225
226 <span class="size-warn warn-tip hide"> 226 <span class="size-warn warn-tip hide">
227 - <i class="iconfont">&#xe62c;</i> 227 + <i class="iconfont">&#xe61f;</i>
228 请选择尺码 228 请选择尺码
229 </span> 229 </span>
230 </ul> 230 </ul>
@@ -15,8 +15,7 @@ module.exports = { @@ -15,8 +15,7 @@ module.exports = {
15 port: 6002, 15 port: 6002,
16 siteUrl: 'http://www.yohobuy.com', 16 siteUrl: 'http://www.yohobuy.com',
17 domains: { 17 domains: {
18 - // api: 'http://devapi.yoho.cn:58078/',  
19 - // service: 'http://devservice.yoho.cn:58077/', 18 + favApi: 'http://192.168.102.31:8092/brower',
20 api: 'http://api-test3.yohops.com:9999/', 19 api: 'http://api-test3.yohops.com:9999/',
21 service: 'http://service-test3.yohops.com:9999/', 20 service: 'http://service-test3.yohops.com:9999/',
22 search: 'http://192.168.102.216:8080/yohosearch/' 21 search: 'http://192.168.102.216:8080/yohosearch/'
@@ -99,12 +98,24 @@ if (isProduction) { @@ -99,12 +98,24 @@ if (isProduction) {
99 timeout: 3000 98 timeout: 3000
100 }, 99 },
101 useOneapm: true, 100 useOneapm: true,
102 - useCache: true 101 + useCache: true,
  102 + interfaceShunt: {
  103 + useInterfaceShunt: true,
  104 + tencentServers: {
  105 + api: ['123.206.1.98', '123.206.2.80'],
  106 + service: ['123.206.1.98', '123.206.2.80']
  107 + },
  108 + awsServers: {
  109 + api: 'app-java-168863769.cn-north-1.elb.amazonaws.com.cn',
  110 + service: 'service-yoho-579825100.cn-north-1.elb.amazonaws.com.cn'
  111 + }
  112 + }
103 }); 113 });
104 } else if (isTest) { 114 } else if (isTest) {
105 Object.assign(module.exports, { 115 Object.assign(module.exports, {
106 appName: 'www.yohobuy.com for test', 116 appName: 'www.yohobuy.com for test',
107 domains: { 117 domains: {
  118 + favApi: 'http://192.168.102.31:8092/brower',
108 api: 'http://api-test3.yohops.com:9999/', 119 api: 'http://api-test3.yohops.com:9999/',
109 service: 'http://service-test3.yohops.com:9999/', 120 service: 'http://service-test3.yohops.com:9999/',
110 search: 'http://192.168.102.216:8080/yohosearch/' 121 search: 'http://192.168.102.216:8080/yohosearch/'
@@ -15,7 +15,7 @@ exports.notFound = () => { @@ -15,7 +15,7 @@ exports.notFound = () => {
15 } 15 }
16 16
17 headerModel.requestHeaderData().then((result) => { 17 headerModel.requestHeaderData().then((result) => {
18 - return res.render('error/404', { 18 + return res.status(404).render('error/404', {
19 module: 'common', 19 module: 'common',
20 page: 'error', 20 page: 'error',
21 title: '页面不存在 | Yoho!Buy有货 | 潮流购物逛不停', 21 title: '页面不存在 | Yoho!Buy有货 | 潮流购物逛不停',
@@ -43,7 +43,7 @@ exports.serverError = () => { @@ -43,7 +43,7 @@ exports.serverError = () => {
43 } 43 }
44 44
45 const renderErrPage = (result) => { 45 const renderErrPage = (result) => {
46 - res.render('error/500', { 46 + res.status(500).render('error/500', {
47 module: 'common', 47 module: 'common',
48 page: 'error', 48 page: 'error',
49 err: err, 49 err: err,
@@ -18,7 +18,7 @@ module.exports = () => { @@ -18,7 +18,7 @@ module.exports = () => {
18 18
19 // 获得vip 信息 19 // 获得vip 信息
20 if (req.user.uid && req.cookies._UID) { 20 if (req.user.uid && req.cookies._UID) {
21 - let getVip = Fp.pipe(Fp.split('::'), Fp.take(2)); 21 + let getVip = Fp.pipe(Fp.split('::'), Fp.nth(2));
22 22
23 req.user.vip = getVip(req.cookies._UID); 23 req.user.vip = getVip(req.cookies._UID);
24 } 24 }
1 { 1 {
2 "name": "yohobuy-node", 2 "name": "yohobuy-node",
3 - "version": "4.8.17", 3 + "version": "4.8.18",
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": {
@@ -59,7 +59,7 @@ @@ -59,7 +59,7 @@
59 "uuid": "^2.0.2", 59 "uuid": "^2.0.2",
60 "winston": "^2.2.0", 60 "winston": "^2.2.0",
61 "winston-daily-rotate-file": "^1.1.4", 61 "winston-daily-rotate-file": "^1.1.4",
62 - "yoho-node-lib": "0.0.38" 62 + "yoho-node-lib": "0.0.40"
63 }, 63 },
64 "devDependencies": { 64 "devDependencies": {
65 "autoprefixer": "^6.3.6", 65 "autoprefixer": "^6.3.6",