Authored by 毕凯

Merge branch 'gray' into 'master'

Gray



See merge request !806
@@ -108,67 +108,7 @@ app.use(bodyParser.urlencoded({ @@ -108,67 +108,7 @@ app.use(bodyParser.urlencoded({
108 app.use(cookieParser()); 108 app.use(cookieParser());
109 app.use(compression()); 109 app.use(compression());
110 110
111 -const sessionStore = new MemcachedStore({  
112 - hosts: config.memcache.session,  
113 - prefix: 'yohobuy_session:',  
114 - reconnect: 5000,  
115 - timeout: 1000,  
116 - retries: 0  
117 -});  
118 -  
119 -app.use(memcachedSession({  
120 - proxy: true,  
121 - resave: false,  
122 - saveUninitialized: true,  
123 - unset: 'destroy',  
124 - secret: '82dd7e724f2c6870472c89dfa43cf48d',  
125 - name: 'yohobuy_session',  
126 - cookie: {  
127 - domain: 'yohobuy.com',  
128 - httpOnly: false  
129 - },  
130 - store: sessionStore  
131 -}));  
132 -  
133 -app.use(cookieSession({  
134 - requestKey: 'session2',  
135 - cookieName: 'yohobuy_session_cookie',  
136 - secret: '82dd7e724f2c6870472c89dfa43cf48d',  
137 - cookie: {  
138 - domain: 'yohobuy.com',  
139 - ephemeral: true  
140 - }  
141 -}));  
142 -  
143 -app.use((req, res, next) => {  
144 - if (req.session) {  
145 - let sessionKeys = Object.keys(req.session || {});  
146 - let backSessionKeys = Object.keys(req.session2.sessionBack || {});  
147 -  
148 - if (backSessionKeys.length > sessionKeys.length) {  
149 - let differences = _.difference(backSessionKeys, sessionKeys);  
150 -  
151 - _.forEach(differences, d => {  
152 - req.session[d] = req.session2.sessionBack[d];  
153 - });  
154 - }  
155 - req.session2.sessionBack = req.session;  
156 - } else {  
157 - req.session = new memcachedSession.Session(req);  
158 - req.session.cookie = new memcachedSession.Cookie({  
159 - domain: 'yohobuy.com',  
160 - httpOnly: false  
161 - });  
162 - req.session = _.assign(req.session, req.session2.sessionBack);  
163 - }  
164 -  
165 - if (!req.sessionID) {  
166 - req.sessionID = uuid.v4();  
167 - }  
168 -  
169 - next();  
170 -});  
171 - 111 +require('./doraemon/middleware/yoho-session')(app);
172 112
173 app.use((req, res, next) => { 113 app.use((req, res, next) => {
174 req.user = {}; // 全局的用户数据 114 req.user = {}; // 全局的用户数据
@@ -53,7 +53,7 @@ module.exports = { @@ -53,7 +53,7 @@ module.exports = {
53 yh_channel: params.yh_channel, 53 yh_channel: params.yh_channel,
54 limit: params.limit, 54 limit: params.limit,
55 need_filter: 'null', 55 need_filter: 'null',
56 - rec_pos: '100008', 56 + rec_pos: '100004',
57 gender: params.gender || gender[params.yh_channel] 57 gender: params.gender || gender[params.yh_channel]
58 }, { 58 }, {
59 cache: true 59 cache: true
  1 +const config = global.yoho.config;
  2 +const memcachedSession = require('yoho-express-session');
  3 +const _ = require('lodash');
  4 +const uuid = require('uuid');
  5 +
  6 +const cookieSession = require('client-sessions');
  7 +const memcached = require('connect-memcached');
  8 +const MemcachedStore = memcached(memcachedSession);
  9 +
  10 +/**
  11 + * 该中间件主要把 express-session 和 client-session 集中起来处理,如果 memcached 出错了,使用 cookie session
  12 + * @param opts.backSession cookieSession 的键名
  13 + * @returns {function(*=, *=, *)}
  14 + */
  15 +function yohoSession(opts) {
  16 + return (req, res, next) => {
  17 + let notUseMemcached = _.get(req.app.locals.wap, 'session.removeMemcached', false);
  18 +
  19 + opts.backSession = opts.backSession || 'session2';
  20 +
  21 + if (req.session && !notUseMemcached) {
  22 + req.sessionError = false;
  23 + } else {
  24 + // 重建 session
  25 + res.emit('sessionError');
  26 + req.sessionError = true;
  27 +
  28 + req.sessionID = uuid.v4();
  29 + req.session = new memcachedSession.Session(req, req[opts.backSession].sessionBack);
  30 + req.session.cookie = new memcachedSession.Cookie({
  31 + domain: 'yohobuy.com',
  32 + httpOnly: false
  33 + });
  34 + }
  35 +
  36 + Object.defineProperty(req.session, 'reset', {
  37 + configurable: true,
  38 + enumerable: false,
  39 + value: function() {
  40 + req.session.destroy();
  41 + req[opts.backSession].reset();
  42 + },
  43 + writable: false
  44 + });
  45 +
  46 + // 备份数据
  47 + req[opts.backSession].sessionBack = req.session;
  48 +
  49 + next();
  50 + };
  51 +}
  52 +
  53 +module.exports = (app) => {
  54 + app.use(memcachedSession({ // eslint-disable-line
  55 + proxy: true,
  56 + resave: false,
  57 + saveUninitialized: true,
  58 + unset: 'destroy',
  59 + secret: '82dd7e724f2c6870472c89dfa43cf48d',
  60 + name: 'yohobuy_session',
  61 + cookie: {
  62 + domain: 'yohobuy.com',
  63 + httpOnly: false
  64 + },
  65 + store: new MemcachedStore({
  66 + hosts: config.memcache.session,
  67 + prefix: 'yohobuy_session:',
  68 + reconnect: 5000,
  69 + timeout: 1000,
  70 + retries: 0
  71 + })
  72 + }));
  73 +
  74 + app.use(cookieSession({ // eslint-disable-line
  75 + requestKey: 'session2',
  76 + cookieName: 'yohobuy_session_cookie',
  77 + secret: '82dd7e724f2c6870472c89dfa43cf48d',
  78 + cookie: {
  79 + domain: 'yohobuy.com',
  80 + ephemeral: true
  81 + }
  82 + }));
  83 +
  84 + app.use(yohoSession({
  85 + backSession: 'session2'
  86 + }));
  87 +};
1 { 1 {
2 "name": "m-yohobuy-node", 2 "name": "m-yohobuy-node",
3 - "version": "6.0.1", 3 + "version": "6.0.2",
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": {
1 -const store = require('store');  
2 -const expirePlugin = require('store/plugins/expire');  
3 -  
4 -store.addPlugin(expirePlugin); 1 +const engine = require('store/src/store-engine');
  2 +const storages = [
  3 + require('store/storages/sessionStorage')
  4 +];
  5 +const plugins = [
  6 + require('store/plugins/defaults'),
  7 + require('store/plugins/expire')
  8 +];
  9 +const store = engine.createStore(storages, plugins);
5 10
6 module.exports = { 11 module.exports = {
7 get: (...params) => { 12 get: (...params) => {
8 - store.enabled = false; // 暂时屏蔽  
9 return store.enabled ? store.get(...params) : false; 13 return store.enabled ? store.get(...params) : false;
10 }, 14 },
11 15
12 set: (...params) => { 16 set: (...params) => {
13 - store.enabled = false; // 暂时屏蔽  
14 return store.enabled ? store.set(...params, new Date().getTime() + 180000) : false; 17 return store.enabled ? store.set(...params, new Date().getTime() + 180000) : false;
15 } 18 }
16 }; 19 };
@@ -150,6 +150,14 @@ class ProductListWithFilter { @@ -150,6 +150,14 @@ class ProductListWithFilter {
150 }); 150 });
151 } 151 }
152 152
  153 + // 点击排序,重新筛选
  154 + if (params && params.navTouch) {
  155 + delete params.navTouch;
  156 + this.nav.end = false;
  157 + } else if (this.nav && this.nav.end) { // 滚动加载,加载结束标识
  158 + return false;
  159 + }
  160 +
153 // 有参数,参数优先,滚动加载相关参数重置 161 // 有参数,参数优先,滚动加载相关参数重置
154 if (params && !params.filtering) { 162 if (params && !params.filtering) {
155 Object.assign(this.defaultOpt, params); 163 Object.assign(this.defaultOpt, params);
@@ -160,10 +168,6 @@ class ProductListWithFilter { @@ -160,10 +168,6 @@ class ProductListWithFilter {
160 this.beforeScroll = document.body.scrollTop; 168 this.beforeScroll = document.body.scrollTop;
161 } 169 }
162 170
163 - if (this.nav && this.nav.end) {  
164 - return false;  
165 - }  
166 -  
167 if (!this.onSearching) { 171 if (!this.onSearching) {
168 let catchKey = this.searchUrl + '?' + $.param(this.defaultOpt); 172 let catchKey = this.searchUrl + '?' + $.param(this.defaultOpt);
169 173
@@ -193,8 +197,11 @@ class ProductListWithFilter { @@ -193,8 +197,11 @@ class ProductListWithFilter {
193 }); 197 });
194 }, 198 },
195 success: (result) => { 199 success: (result) => {
196 - cacheStore.set(catchKey, result);  
197 this.dataRender(result); 200 this.dataRender(result);
  201 +
  202 + if (result && result.length) {
  203 + cacheStore.set(catchKey, result);
  204 + }
198 }, 205 },
199 error: () => { 206 error: () => {
200 let $divide = $('.search-divide'); 207 let $divide = $('.search-divide');
@@ -364,7 +371,7 @@ class ProductListWithFilter { @@ -364,7 +371,7 @@ class ProductListWithFilter {
364 this.defaultOpt.type = this.navType; 371 this.defaultOpt.type = this.navType;
365 Object.assign(this.defaultOpt, this.nav); 372 Object.assign(this.defaultOpt, this.nav);
366 373
367 - this.getGoodsList(); 374 + this.getGoodsList({navTouch: true});
368 } 375 }
369 } 376 }
370 377
@@ -74,9 +74,9 @@ @@ -74,9 +74,9 @@
74 74
75 .coupon-left { 75 .coupon-left {
76 position: absolute; 76 position: absolute;
77 - width: 158px; 77 + width: 185px;
78 overflow: hidden; 78 overflow: hidden;
79 - margin: 0 35px; 79 + margin: 0 0 0 35px;
80 height: inherit; 80 height: inherit;
81 } 81 }
82 82
@@ -74,9 +74,9 @@ @@ -74,9 +74,9 @@
74 74
75 .coupon-left { 75 .coupon-left {
76 position: absolute; 76 position: absolute;
77 - width: 165px; 77 + width: 160px;
78 overflow: hidden; 78 overflow: hidden;
79 - margin: 0 30px; 79 + margin: 0 0 0 30px;
80 height: inherit; 80 height: inherit;
81 } 81 }
82 82