Showing
8 changed files
with
103 additions
and
23 deletions
@@ -5,7 +5,8 @@ | @@ -5,7 +5,8 @@ | ||
5 | {{userInfo.name}} | 5 | {{userInfo.name}} |
6 | </Col> | 6 | </Col> |
7 | <Col :span="12" class="shop-info"> | 7 | <Col :span="12" class="shop-info"> |
8 | - <span class="name">{{userInfo.currentShop.shopName}}</span> | 8 | + <span v-if="!showLoading" class="name">{{userInfo.currentShop.shopName}}</span> |
9 | + <span v-if="showLoading" class="loading">切换中...</span> | ||
9 | <span>|</span> | 10 | <span>|</span> |
10 | <Dropdown @on-click="switchShop" trigger="click"> | 11 | <Dropdown @on-click="switchShop" trigger="click"> |
11 | <a class="swtich-shop" href="javascript:void(0)"> | 12 | <a class="swtich-shop" href="javascript:void(0)"> |
@@ -22,12 +23,14 @@ | @@ -22,12 +23,14 @@ | ||
22 | 23 | ||
23 | <script> | 24 | <script> |
24 | import Vue from 'vue'; | 25 | import Vue from 'vue'; |
26 | +import userService from 'user-service'; | ||
25 | 27 | ||
26 | export default { | 28 | export default { |
27 | name: 'UserInfo', | 29 | name: 'UserInfo', |
28 | data() { | 30 | data() { |
29 | return { | 31 | return { |
30 | - userInfo: this.$user | 32 | + userInfo: this.$user, |
33 | + showLoading: false | ||
31 | }; | 34 | }; |
32 | }, | 35 | }, |
33 | methods: { | 36 | methods: { |
@@ -36,9 +39,18 @@ export default { | @@ -36,9 +39,18 @@ export default { | ||
36 | }, | 39 | }, |
37 | switchShop(id) { | 40 | switchShop(id) { |
38 | if (this.userInfo.currentShop.shopsId !== id) { | 41 | if (this.userInfo.currentShop.shopsId !== id) { |
42 | + this.showLoading = true; | ||
43 | + userService.switchShop(id).then(res => { | ||
44 | + this.showLoading = false; | ||
45 | + if (res.code === 200) { | ||
39 | this.userInfo.currentShop = this.userInfo.shops.find(shop => shop.shopsId === id); | 46 | this.userInfo.currentShop = this.userInfo.shops.find(shop => shop.shopsId === id); |
40 | Vue.switchShop(id); | 47 | Vue.switchShop(id); |
41 | this.$emit('shop-change', this.userInfo.currentShop); | 48 | this.$emit('shop-change', this.userInfo.currentShop); |
49 | + this.$Message.success(`当前店铺切换为:${this.userInfo.currentShop.shopName}`); | ||
50 | + } else { | ||
51 | + this.$Message.error(`切换失败:${res.message}`); | ||
52 | + } | ||
53 | + }); | ||
42 | } | 54 | } |
43 | } | 55 | } |
44 | } | 56 | } |
@@ -85,6 +97,10 @@ export default { | @@ -85,6 +97,10 @@ export default { | ||
85 | margin-right: 5px; | 97 | margin-right: 5px; |
86 | } | 98 | } |
87 | 99 | ||
100 | + .loading { | ||
101 | + color: #ccc; | ||
102 | + } | ||
103 | + | ||
88 | .swtich-shop { | 104 | .swtich-shop { |
89 | margin-left: 5px; | 105 | margin-left: 5px; |
90 | font-size: 12px; | 106 | font-size: 12px; |
@@ -3,8 +3,5 @@ const page = r => require.ensure([], () => r(require('./overview')), 'home.overv | @@ -3,8 +3,5 @@ const page = r => require.ensure([], () => r(require('./overview')), 'home.overv | ||
3 | export default { | 3 | export default { |
4 | path: '/overview.html', | 4 | path: '/overview.html', |
5 | name: 'overview', | 5 | name: 'overview', |
6 | - component: page, | ||
7 | - meta: { | ||
8 | - authPass: true | ||
9 | - } | 6 | + component: page |
10 | }; | 7 | }; |
@@ -31,6 +31,13 @@ const userService = { | @@ -31,6 +31,13 @@ const userService = { | ||
31 | } | 31 | } |
32 | }); | 32 | }); |
33 | return purs; | 33 | return purs; |
34 | + }, | ||
35 | + switchShop(shopId) { | ||
36 | + return axios.post('/switchShop', { | ||
37 | + shopId | ||
38 | + }).then(res => { | ||
39 | + return res.data; | ||
40 | + }); | ||
34 | } | 41 | } |
35 | }; | 42 | }; |
36 | 43 |
@@ -55,7 +55,8 @@ let domainApis = { | @@ -55,7 +55,8 @@ let domainApis = { | ||
55 | getRemoteImageUrlBySku: '/product/getRemoteImageUrlBySku' | 55 | getRemoteImageUrlBySku: '/product/getRemoteImageUrlBySku' |
56 | }, | 56 | }, |
57 | shop: { | 57 | shop: { |
58 | - login: '/loginInter' | 58 | + login: '/loginInter', |
59 | + switchShop: '/index/ajaxshop' | ||
59 | } | 60 | } |
60 | }; | 61 | }; |
61 | 62 |
@@ -83,7 +83,8 @@ class Api extends Context { | @@ -83,7 +83,8 @@ class Api extends Context { | ||
83 | logger.error(`api call ${err.statusCode} [${err.options.method}] | 83 | logger.error(`api call ${err.statusCode} [${err.options.method}] |
84 | ${err.options.url} ${err.response.body || ''}`); | 84 | ${err.options.url} ${err.response.body || ''}`); |
85 | } else { | 85 | } else { |
86 | - logger.error(`api call ${err}`); | 86 | + logger.error(`api call [${options.method || 'get'}] ${options.url} |
87 | + ${JSON.stringify(options.qs || options.body)} ${err}`); | ||
87 | } | 88 | } |
88 | return Promise.reject(API_INTERNAL_ERROR); | 89 | return Promise.reject(API_INTERNAL_ERROR); |
89 | }); | 90 | }); |
@@ -10,6 +10,8 @@ const Express = require('express'); | @@ -10,6 +10,8 @@ const Express = require('express'); | ||
10 | const UserController = require('./user-controller'); | 10 | const UserController = require('./user-controller'); |
11 | const FileController = require('./file-controller'); | 11 | const FileController = require('./file-controller'); |
12 | const middleware = require('../framework/middleware'); | 12 | const middleware = require('../framework/middleware'); |
13 | +const before = require('../middleware/before'); | ||
14 | +const auth = require('../middleware/auth'); | ||
13 | const multipart = require('connect-multiparty'); | 15 | const multipart = require('connect-multiparty'); |
14 | const multipartMiddleware = multipart(); | 16 | const multipartMiddleware = multipart(); |
15 | 17 | ||
@@ -17,7 +19,8 @@ let router = Express.Router(); // eslint-disable-line | @@ -17,7 +19,8 @@ let router = Express.Router(); // eslint-disable-line | ||
17 | 19 | ||
18 | router.post('/login', middleware(UserController, 'login')); | 20 | router.post('/login', middleware(UserController, 'login')); |
19 | router.post('/logout', middleware(UserController, 'logout')); | 21 | router.post('/logout', middleware(UserController, 'logout')); |
20 | -router.post('/upload/image', multipartMiddleware, middleware(FileController, 'uploadImage')); | ||
21 | -router.post('/upload/xlsx', multipartMiddleware, middleware(FileController, 'uploadXlsx')); | 22 | +router.post('/switchShop', before, auth, middleware(UserController, 'switchShop')); |
23 | +router.post('/upload/image', before, auth, multipartMiddleware, middleware(FileController, 'uploadImage')); | ||
24 | +router.post('/upload/xlsx', before, auth, multipartMiddleware, middleware(FileController, 'uploadXlsx')); | ||
22 | 25 | ||
23 | module.exports = router; | 26 | module.exports = router; |
@@ -26,9 +26,8 @@ class UserController extends Context { | @@ -26,9 +26,8 @@ class UserController extends Context { | ||
26 | let currentShop = _.first(result.data); | 26 | let currentShop = _.first(result.data); |
27 | 27 | ||
28 | this.syncSession({req, res}, Object.assign(user, { | 28 | this.syncSession({req, res}, Object.assign(user, { |
29 | - shops: result.data, | ||
30 | - currentShop: currentShop | ||
31 | - }), sess); | 29 | + shops: result.data |
30 | + }), sess, currentShop); | ||
32 | 31 | ||
33 | return res.json({ | 32 | return res.json({ |
34 | code: 200, | 33 | code: 200, |
@@ -68,26 +67,62 @@ class UserController extends Context { | @@ -68,26 +67,62 @@ class UserController extends Context { | ||
68 | data: '登出成功' | 67 | data: '登出成功' |
69 | }); | 68 | }); |
70 | } | 69 | } |
70 | + switchShop(req, res) { | ||
71 | + let shopId = req.body.shopId; | ||
71 | 72 | ||
72 | - syncSession(context, user, sess) { | 73 | + if (!shopId) { |
74 | + return res.json({ | ||
75 | + code: 400, | ||
76 | + message: '参数错误' | ||
77 | + }); | ||
78 | + } | ||
79 | + let shop = _.find(req.session.USER.shops, s => s.shopsId === shopId); | ||
80 | + | ||
81 | + if (!shop) { | ||
82 | + return res.json({ | ||
83 | + code: 400, | ||
84 | + message: '不存在的店铺' | ||
85 | + }); | ||
86 | + } | ||
87 | + this.userService.switchShop({ | ||
88 | + shopId, | ||
89 | + cookies: { | ||
90 | + PHPSESSID: encodeURIComponent(req.cookies.PHPSESSID), | ||
91 | + 'connect.sid': encodeURIComponent(req.cookies['connect.sid']) | ||
92 | + } | ||
93 | + }).then(response => { | ||
94 | + this.syncShopSession({ | ||
95 | + req, | ||
96 | + res | ||
97 | + }, response); | ||
98 | + return res.json({ | ||
99 | + code: 200 | ||
100 | + }); | ||
101 | + }); | ||
102 | + } | ||
103 | + | ||
104 | + syncSession(context, user, sess, currentShop) { | ||
73 | context.req.session.USER = user; | 105 | context.req.session.USER = user; |
74 | context.req.session.LOGIN_UID = user.pid; // pid 为用户名 | 106 | context.req.session.LOGIN_UID = user.pid; // pid 为用户名 |
75 | 107 | ||
108 | + this.syncShopSession(context, sess); | ||
109 | + context.res.cookie('_isLogin', true, { | ||
110 | + path: '/' | ||
111 | + }); | ||
112 | + context.res.cookie('_sign', currentShop.shopsId, { | ||
113 | + path: '/' | ||
114 | + }); | ||
115 | + } | ||
116 | + | ||
117 | + syncShopSession(context, sess) { | ||
76 | _.each(sess, (v, k) => { | 118 | _.each(sess, (v, k) => { |
77 | context.res.cookie(k, v, { | 119 | context.res.cookie(k, v, { |
78 | path: '/', | 120 | path: '/', |
79 | domain: '.yohobuy.com', | 121 | domain: '.yohobuy.com', |
80 | httpOnly: true, | 122 | httpOnly: true, |
81 | - overwrite: false, | ||
82 | encode: val => val | 123 | encode: val => val |
83 | }); | 124 | }); |
84 | }); | 125 | }); |
85 | - context.res.cookie('_isLogin', true, { | ||
86 | - path: '/' | ||
87 | - }); | ||
88 | - context.res.cookie('_sign', user.currentShop.shopsId, { | ||
89 | - path: '/' | ||
90 | - }); | ||
91 | } | 126 | } |
92 | } | 127 | } |
93 | 128 |
@@ -39,9 +39,14 @@ class UserService extends Context { | @@ -39,9 +39,14 @@ class UserService extends Context { | ||
39 | password: password | 39 | password: password |
40 | } | 40 | } |
41 | }).then(response => { | 41 | }).then(response => { |
42 | + return this._getShopsSession(response.rawHeaders); | ||
43 | + }); | ||
44 | + } | ||
45 | + | ||
46 | + _getShopsSession(rawHeaders) { | ||
42 | let sessId = '', sid = ''; | 47 | let sessId = '', sid = ''; |
43 | 48 | ||
44 | - _.each(response.rawHeaders, header => { | 49 | + _.each(rawHeaders, header => { |
45 | let sessIdMatched = header.match(new RegExp(regSession.replace('${0}', 'PHPSESSID'))); | 50 | let sessIdMatched = header.match(new RegExp(regSession.replace('${0}', 'PHPSESSID'))); |
46 | let sidMatched = header.match(new RegExp(regSession.replace('${0}', 'connect\.sid'))); | 51 | let sidMatched = header.match(new RegExp(regSession.replace('${0}', 'connect\.sid'))); |
47 | 52 | ||
@@ -56,7 +61,6 @@ class UserService extends Context { | @@ -56,7 +61,6 @@ class UserService extends Context { | ||
56 | PHPSESSID: sessId, | 61 | PHPSESSID: sessId, |
57 | 'connect.sid': sid | 62 | 'connect.sid': sid |
58 | }; | 63 | }; |
59 | - }); | ||
60 | } | 64 | } |
61 | 65 | ||
62 | getShops(pid) { | 66 | getShops(pid) { |
@@ -68,6 +72,22 @@ class UserService extends Context { | @@ -68,6 +72,22 @@ class UserService extends Context { | ||
68 | }); | 72 | }); |
69 | } | 73 | } |
70 | 74 | ||
75 | + switchShop(opts) { | ||
76 | + let options = { | ||
77 | + url: `${config.apiDomain.shop.switchShop}?shops_id=${opts.shopId}`, | ||
78 | + resolveWithFullResponse: true, | ||
79 | + }; | ||
80 | + let jar = rp.jar(); | ||
81 | + | ||
82 | + _.each(opts.cookies, (val, key) => { | ||
83 | + jar.setCookie(rp.cookie(`${key}=${val}`), options.url); | ||
84 | + }); | ||
85 | + options.jar = jar; | ||
86 | + return rp.get(options).then(response => { | ||
87 | + return this._getShopsSession(response.rawHeaders); | ||
88 | + }); | ||
89 | + } | ||
90 | + | ||
71 | profile(pid) { | 91 | profile(pid) { |
72 | return this.instance(Api).get(config.apiDomain.shop.profile.url, {userId: pid}); | 92 | return this.instance(Api).get(config.apiDomain.shop.profile.url, {userId: pid}); |
73 | } | 93 | } |
-
Please register or login to post a comment