Authored by ccbikai(👎🏻🍜)

Merge branch 'feature/crm' into release/5.7

@@ -4,7 +4,8 @@ const model = require('../models/feature'); @@ -4,7 +4,8 @@ const model = require('../models/feature');
4 exports.index = function(req, res, next) { 4 exports.index = function(req, res, next) {
5 model.index({ 5 model.index({
6 code: req.params.code, 6 code: req.params.code,
7 - type: req.query.type 7 + type: req.query.type,
  8 + user_id: req.user.uid || 0
8 }).then((result) => { 9 }).then((result) => {
9 if (!result) { 10 if (!result) {
10 return next(); 11 return next();
@@ -8,38 +8,53 @@ const channels = { @@ -8,38 +8,53 @@ const channels = {
8 }; 8 };
9 9
10 exports.productLst = function(req, res, next) { 10 exports.productLst = function(req, res, next) {
11 - let keys = ['sort', 'misort', 'msort', 'gender', 'brand'],  
12 - params = {  
13 - uid: req.user.uid || req.query.uid,  
14 - udid: req.query.udid,  
15 - promotion: req.query.pid, 11 + let uid = req.user.uid || req.query.uid;
  12 + let udid = req.query.udid;
  13 + let getProductList;
  14 +
  15 + if (req.query.maybeLike) {
  16 + getProductList = model.maybeLikeList(Object.assign({
  17 + uid: uid,
  18 + udid: udid,
16 yh_channel: req.query.yh_channel || (req.cookies._Channel && channels[req.cookies._Channel]) || 1, 19 yh_channel: req.query.yh_channel || (req.cookies._Channel && channels[req.cookies._Channel]) || 1,
17 - specified_sort: req.query.enum,  
18 - stocknumber: req.query.sn,  
19 - p_d: req.query.pd,  
20 - noDup: req.query.noDup,  
21 - limit: req.query.limit || 10  
22 - }; 20 + limit: req.query.limit
  21 + }, req.query));
  22 + } else {
  23 + let keys = ['sort', 'misort', 'msort', 'gender', 'brand'],
  24 + params = {
  25 + uid: uid,
  26 + udid: udid,
  27 + promotion: req.query.pid,
  28 + yh_channel: req.query.yh_channel || (req.cookies._Channel && channels[req.cookies._Channel]) || 1,
  29 + specified_sort: req.query.enum,
  30 + stocknumber: req.query.sn,
  31 + p_d: req.query.pd,
  32 + noDup: req.query.noDup,
  33 + limit: req.query.limit || 10
  34 + };
23 35
24 - keys.forEach(function(k) {  
25 - if (req.query[k]) {  
26 - params[k] = req.query[k];  
27 - }  
28 - }); 36 + keys.forEach(function(k) {
  37 + if (req.query[k]) {
  38 + params[k] = req.query[k];
  39 + }
  40 + });
29 41
30 - if (params.specified_sort) {  
31 - if (params.brand) {  
32 - params.limit = params.brand.split(',').length;  
33 - } else if (params.sort) {  
34 - params.limit = params.sort.split(',').length;  
35 - } else if (params.misort) {  
36 - params.limit = params.misort.split(',').length;  
37 - } else if (params.msort) {  
38 - params.limit = params.msort.split(',').length; 42 + if (params.specified_sort) {
  43 + if (params.brand) {
  44 + params.limit = params.brand.split(',').length;
  45 + } else if (params.sort) {
  46 + params.limit = params.sort.split(',').length;
  47 + } else if (params.misort) {
  48 + params.limit = params.misort.split(',').length;
  49 + } else if (params.msort) {
  50 + params.limit = params.msort.split(',').length;
  51 + }
39 } 52 }
  53 +
  54 + getProductList = model.productLst(params);
40 } 55 }
41 56
42 - model.productLst(params).then((result) => { 57 + getProductList.then((result) => {
43 res.jsonp(result); 58 res.jsonp(result);
44 }).catch(next); 59 }).catch(next);
45 }; 60 };
@@ -359,12 +359,24 @@ exports.receiveCoupon = (receiveData, uid) => { @@ -359,12 +359,24 @@ exports.receiveCoupon = (receiveData, uid) => {
359 }; 359 };
360 360
361 exports.couponSend = (uid, token) => { 361 exports.couponSend = (uid, token) => {
362 -  
363 - return api.get('', { 362 + let data = {
364 method: 'app.coupons.couponSend', 363 method: 'app.coupons.couponSend',
365 uid: uid, 364 uid: uid,
366 coupon_send_token: token 365 coupon_send_token: token
367 - }).then(result => { 366 + };
  367 +
  368 + if (/:/.test(token)) {
  369 + let [couponId, personCouponId] = token.split(':');
  370 +
  371 + data = {
  372 + method: 'app.promotion.getCoupon',
  373 + uid: uid,
  374 + couponId: couponId,
  375 + personCouponId: personCouponId
  376 + };
  377 + }
  378 +
  379 + return api.get('', data).then(result => {
368 380
369 if (!result) { 381 if (!result) {
370 result.code = 404; 382 result.code = 404;
@@ -10,10 +10,8 @@ const _getProductBySkns = function(productObj) { @@ -10,10 +10,8 @@ const _getProductBySkns = function(productObj) {
10 productObj.defaultPros = []; 10 productObj.defaultPros = [];
11 if (result && result.data && result.data.product_list && result.code === 200) { 11 if (result && result.data && result.data.product_list && result.code === 200) {
12 result.data.product_list.forEach(function(val) { 12 result.data.product_list.forEach(function(val) {
13 - var goods_id = Array.isArray(val.goods_list) &&  
14 - val.goods_list.length ? val.goods_list[0].goods_id : null;  
15 var obj = { 13 var obj = {
16 - producturl: `//m.yohobuy.com/product/pro_${val.product_id}_${goods_id}/${val.cn_alphabet}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${val.product_skn}}}`, // eslint-disable-line 14 + producturl: `//m.yohobuy.com/product/${val.product_skn}.html?openby:yohobuy={"action":"go.productDetail","params":{"product_skn":${val.product_skn}}}`, // eslint-disable-line
17 productimg: helpers.image(val.default_images, 213, 284, 2, 60).replace('quality/80', 'quality/60'), 15 productimg: helpers.image(val.default_images, 213, 284, 2, 60).replace('quality/80', 'quality/60'),
18 productname: val.product_name, 16 productname: val.product_name,
19 vipprice: val.vip_price, 17 vipprice: val.vip_price,
@@ -47,12 +45,14 @@ module.exports = { @@ -47,12 +45,14 @@ module.exports = {
47 if (params.type === 'preview') { // 开发/预览模式 45 if (params.type === 'preview') { // 开发/预览模式
48 data = yield api.get('', { 46 data = yield api.get('', {
49 method: 'app.activity.template.ignoreCache', 47 method: 'app.activity.template.ignoreCache',
50 - activity_id: params.code 48 + activity_id: params.code,
  49 + user_id: params.user_id
51 }); 50 });
52 } else { 51 } else {
53 data = yield api.get('', { // 生产模式 52 data = yield api.get('', { // 生产模式
54 method: 'app.activity.template', 53 method: 'app.activity.template',
55 - activity_id: params.code 54 + activity_id: params.code,
  55 + user_id: params.user_id
56 }, { 56 }, {
57 cache: true 57 cache: true
58 }); 58 });
@@ -67,6 +67,14 @@ module.exports = { @@ -67,6 +67,14 @@ module.exports = {
67 f.component[0].type === 'productGroup' && f.component[0].defaultSkns) { 67 f.component[0].type === 'productGroup' && f.component[0].defaultSkns) {
68 sknsArr.push(_getProductBySkns(f.component[0])); 68 sknsArr.push(_getProductBySkns(f.component[0]));
69 } 69 }
  70 +
  71 + if (f.component && f.component[0] &&
  72 + f.component[0].type === 'productGroup' && f.component[0].favourite_prds_enable === '1') {
  73 + f.component[0].searchCondition = Object.assign({
  74 + maybeLike: '1',
  75 + limit: '12'
  76 + }, f.component[0].searchCondition || {});
  77 + }
70 }); 78 });
71 } 79 }
72 80
@@ -39,5 +39,25 @@ module.exports = { @@ -39,5 +39,25 @@ module.exports = {
39 }); 39 });
40 return data; 40 return data;
41 }); 41 });
  42 + },
  43 + maybeLikeList: function(params) {
  44 + return api.get('', {
  45 + method: 'app.search.newLast7day',
  46 + uid: params.uid || 0,
  47 + udid: params.udid || 0,
  48 + yh_channel: params.yh_channel,
  49 + limit: params.limit,
  50 + need_filter: 'null'
  51 + }, {
  52 + cache: true
  53 + }).then(res => {
  54 + var data = [],
  55 + lst = (res && res.data && res.data.product_list) || [];
  56 +
  57 + lst.forEach(function(o) {
  58 + o && data.push(_getProduct(o));
  59 + });
  60 + return data;
  61 + });
42 } 62 }
43 }; 63 };
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 {{#content.floors}} 14 {{#content.floors}}
15 {{#isEqualOr type 'sidebar'}} 15 {{#isEqualOr type 'sidebar'}}
16 {{! 侧悬浮}} 16 {{! 侧悬浮}}
17 - <div id="sidebar" pageid="{{param.sidebarPageId}}"></div> 17 + <div id="sidebar" pageid="{{param.sidebarPageId}}"></div>
18 {{/isEqualOr}} 18 {{/isEqualOr}}
19 {{#isEqualOr type '' 'common_floor' 'fix'}} 19 {{#isEqualOr type '' 'common_floor' 'fix'}}
20 {{! 普通楼层 顶悬浮}} 20 {{! 普通楼层 顶悬浮}}
@@ -41,7 +41,14 @@ @@ -41,7 +41,14 @@
41 41
42 {{#isEqualOr type 'coupon'}} 42 {{#isEqualOr type 'coupon'}}
43 {{! 优惠券}} 43 {{! 优惠券}}
44 - <a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-token="{{token}}" href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a> 44 + {{#if personCoupon}}
  45 + {{! 个性化优惠券,使用:分割}}
  46 + <a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-token="{{personCoupon.couponId}}:{{personCoupon.personCouponId}}"
  47 + href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
  48 + {{else}}
  49 + <a class="anchor yoho-conpon" style="{{styleFormat this percent=1}}" data-token="{{token}}"
  50 + href="{{#if url}}{{url}}{{else}}javascript:void(0);{{/if}}" fp="{{getAnalysis ../this @index}}"></a>
  51 + {{/if}}
45 {{/isEqualOr}} 52 {{/isEqualOr}}
46 53
47 {{#isEqualOr type 'yohoCoin'}} 54 {{#isEqualOr type 'yohoCoin'}}
@@ -84,12 +91,12 @@ @@ -84,12 +91,12 @@
84 {{/repeat}} 91 {{/repeat}}
85 </div> 92 </div>
86 {{/isEqualOr}} 93 {{/isEqualOr}}
87 - 94 +
88 {{#isEqualOr type 'productGroup'}} 95 {{#isEqualOr type 'productGroup'}}
89 {{! 商品池}} 96 {{! 商品池}}
90 - <div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{image2 proBgImg q=60}})repeat;"{{/if}}> 97 + <div class="product-container item{{numOfOneRow}}" {{#if proBgImg}}style="background:url({{image2 proBgImg q=60}}) repeat;background-size:100%;"{{/if}}>
91 <div class="product-source" condition='{{stringify searchCondition}}' fp="{{getAnalysis ../this @index}}" 98 <div class="product-source" condition='{{stringify searchCondition}}' fp="{{getAnalysis ../this @index}}"
92 - {{#unless defaultPros.length}} 99 + {{#unless defaultPros.length}}
93 {{#if searchCondition.item}} 100 {{#if searchCondition.item}}
94 cloneitem="{{searchCondition.item}}" 101 cloneitem="{{searchCondition.item}}"
95 {{else}} 102 {{else}}
@@ -130,7 +137,7 @@ @@ -130,7 +137,7 @@
130 <img class="brand-img lazy" data-original="{{image2 ../brandImg q=60}}"> 137 <img class="brand-img lazy" data-original="{{image2 ../brandImg q=60}}">
131 </a> 138 </a>
132 {{/if}} 139 {{/if}}
133 - </div> 140 + </div>
134 {{/defaultPros}} 141 {{/defaultPros}}
135 {{else}} 142 {{else}}
136 <div class="feature-product-info novisible"> 143 <div class="feature-product-info novisible">
@@ -158,7 +165,7 @@ @@ -158,7 +165,7 @@
158 {{#if brandImg}} 165 {{#if brandImg}}
159 <a class="second-part {{#isEqualOr showBrandUrl '1'}}product-brand{{else}}product-detail{{/isEqualOr}}" href=''> 166 <a class="second-part {{#isEqualOr showBrandUrl '1'}}product-brand{{else}}product-detail{{/isEqualOr}}" href=''>
160 <div class="brand-div"> 167 <div class="brand-div">
161 - <span class="brand-name" {{#if fontColor}}style="color:{{fontColor}};"{{/if}}></span> 168 + <span class="brand-name" {{#if fontColor}}style="color:{{fontColor}};"{{/if}}></span>
162 </div> 169 </div>
163 <img class="brand-img" src="{{image2 brandImg q=60}}"> 170 <img class="brand-img" src="{{image2 brandImg q=60}}">
164 </a> 171 </a>
@@ -171,6 +178,6 @@ @@ -171,6 +178,6 @@
171 {{/component}} 178 {{/component}}
172 </div> 179 </div>
173 {{/isEqualOr}} 180 {{/isEqualOr}}
174 - {{/content.floors}} 181 + {{/content.floors}}
175 {{/unless}} 182 {{/unless}}
176 -</div>  
  183 +</div>
@@ -33,6 +33,11 @@ const _getUserProfile = (uid) => { @@ -33,6 +33,11 @@ const _getUserProfile = (uid) => {
33 uid: uid 33 uid: uid
34 }, { 34 }, {
35 cache: true 35 cache: true
  36 + }).catch(function() {
  37 + return {
  38 + code: 200,
  39 + data: {}
  40 + };
36 }); 41 });
37 }; 42 };
38 43
@@ -88,7 +88,7 @@ @@ -88,7 +88,7 @@
88 <div class="margin-bottom"></div> 88 <div class="margin-bottom"></div>
89 {{/if}} 89 {{/if}}
90 {{/isEqual}} 90 {{/isEqual}}
91 - {{#isEqual module_type 'RecommentProduct'}} 91 + {{#isEqual module_type 'AppRecommendProduct'}}
92 <div class="index-goods-container" data-type="{{../type}}" data-skns="{{../skns}}" data-order="{{../order}}"></div> 92 <div class="index-goods-container" data-type="{{../type}}" data-skns="{{../skns}}" data-order="{{../order}}"></div>
93 {{#if ../isModuleMargin}} 93 {{#if ../isModuleMargin}}
94 <div class="margin-bottom"></div> 94 <div class="margin-bottom"></div>
@@ -11,17 +11,12 @@ const isProduction = process.env.NODE_ENV === 'production'; @@ -11,17 +11,12 @@ const isProduction = process.env.NODE_ENV === 'production';
11 const isTest = process.env.NODE_ENV === 'test'; 11 const isTest = process.env.NODE_ENV === 'test';
12 12
13 const domains = { 13 const domains = {
14 - liveApi: 'http://testapi.live.yohops.com:9999/',  
15 - singleApi: 'http://api-test3.yohops.com:9999/',  
16 -  
17 api: 'http://api-test3.yohops.com:9999/', 14 api: 'http://api-test3.yohops.com:9999/',
18 service: 'http://service-test3.yohops.com:9999/', 15 service: 'http://service-test3.yohops.com:9999/',
19 - global: 'http://api-global.yohobuy.com',  
20 - store: 'http://192.168.102.210:8080/portal-gateway/',  
21 -  
22 - // liveApi: 'http://api.live.yoho.cn/',  
23 - // singleApi: 'http://single.yoho.cn/',  
24 16
  17 + global: 'http://global-test-soa.yohops.com:9999',
  18 + liveApi: 'http://testapi.live.yohops.com:9999/',
  19 + singleApi: 'http://api-test3.yohops.com:9999/',
25 imSocket: 'ws://socket.yohobuy.com:10240', 20 imSocket: 'ws://socket.yohobuy.com:10240',
26 imCs: 'http://im.yohobuy.com/api' 21 imCs: 'http://im.yohobuy.com/api'
27 }; 22 };
@@ -48,7 +48,9 @@ module.exports = () => { @@ -48,7 +48,9 @@ module.exports = () => {
48 yoho.channel = channel; 48 yoho.channel = channel;
49 49
50 // 判断请求是否来自app 50 // 判断请求是否来自app
51 - yoho.isApp = req.query.app_version || req.query.appVersion || req.cookies.app_version; 51 + yoho.isApp = (req.query.app_version && req.query.app_version !== 'false') ||
  52 + (req.query.appVersion && req.query.appVersion !== 'false') ||
  53 + req.cookies.app_version;
52 yoho.isWechat = /micromessenger/i.test(req.get('User-Agent') || ''); 54 yoho.isWechat = /micromessenger/i.test(req.get('User-Agent') || '');
53 yoho.isWeibo = ua.indexOf('weibo') !== -1; 55 yoho.isWeibo = ua.indexOf('weibo') !== -1;
54 yoho.isqq = /MQQBrowser/i.test(req.get('User-Agent') || ''); 56 yoho.isqq = /MQQBrowser/i.test(req.get('User-Agent') || '');
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 * @Author: Targaryen 2 * @Author: Targaryen
3 * @Date: 2017-03-23 11:31:51 3 * @Date: 2017-03-23 11:31:51
4 * @Last Modified by: Targaryen 4 * @Last Modified by: Targaryen
5 - * @Last Modified time: 2017-04-25 11:45:13 5 + * @Last Modified time: 2017-05-02 11:17:31
6 */ 6 */
7 7
8 /** ***************** 8 /** *****************
@@ -95,7 +95,7 @@ $.each($goodsContainer, function(index, elem) { @@ -95,7 +95,7 @@ $.each($goodsContainer, function(index, elem) {
95 let $result = $(result); 95 let $result = $(result);
96 96
97 lazyLoad($result.find('img[class=lazy]')); 97 lazyLoad($result.find('img[class=lazy]'));
98 - $(elem).html(result); 98 + $(elem).html($result);
99 } 99 }
100 }); 100 });
101 }); 101 });
@@ -2,7 +2,7 @@ @@ -2,7 +2,7 @@
2 * @Author: Targaryen 2 * @Author: Targaryen
3 * @Date: 2017-03-23 11:02:31 3 * @Date: 2017-03-23 11:02:31
4 * @Last Modified by: Targaryen 4 * @Last Modified by: Targaryen
5 - * @Last Modified time: 2017-04-26 16:33:07 5 + * @Last Modified time: 2017-05-02 11:09:37
6 */ 6 */
7 /* 红人店铺数据处理 */ 7 /* 红人店铺数据处理 */
8 8
@@ -174,14 +174,14 @@ const _tools = { @@ -174,14 +174,14 @@ const _tools = {
174 }, 174 },
175 175
176 /** 176 /**
177 - * 商品列表 177 + * 推荐商品列表
178 * @param {*} moduleData 178 * @param {*} moduleData
179 */ 179 */
180 - recommentProduct(moduleData) { 180 + appRecommendProduct(moduleData) {
181 let displayType = _.parseInt(_.get(moduleData, 'properties.displayType', 0)); 181 let displayType = _.parseInt(_.get(moduleData, 'properties.displayType', 0));
182 182
183 let result = { 183 let result = {
184 - module_type: 'RecommentProduct', 184 + module_type: 'AppRecommendProduct',
185 type: displayType 185 type: displayType
186 }; 186 };
187 187
@@ -206,10 +206,7 @@ const _tools = { @@ -206,10 +206,7 @@ const _tools = {
206 break; 206 break;
207 } 207 }
208 208
209 - return {  
210 - module_type: 'RecommentProduct',  
211 - skns: skns,  
212 - }; 209 + return result;
213 } 210 }
214 }; 211 };
215 212
@@ -256,8 +253,8 @@ const floor = (decoratorsData) => { @@ -256,8 +253,8 @@ const floor = (decoratorsData) => {
256 case 'SknList': 253 case 'SknList':
257 skns = _.get(value, 'module_data.data').join(','); 254 skns = _.get(value, 'module_data.data').join(',');
258 break; 255 break;
259 - case 'RecommentProduct':  
260 - decorators.push(_tools.recommentProduct(value.module_data)); 256 + case 'AppRecommendProduct':
  257 + decorators.push(_tools.appRecommendProduct(value.module_data));
261 break; 258 break;
262 default: 259 default:
263 break; 260 break;