@smart100/spu-web-plugin 1.0.0 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/index.d.ts +13 -15
- package/dist/spu-web-plugin.mjs +19354 -19345
- package/package.json +2 -2
- package/src/apaasSpuTrack.ts +42 -72
- package/src/axios.ts +136 -132
- package/src/cloudServ.ts +4 -4
- package/src/components/expandexp/index.ts +260 -205
- package/src/core.js +120 -59
- package/src/globalConfig.ts +5 -7
- package/src/index.ts +48 -111
- package/src/location.ts +20 -23
- package/src/login.ts +534 -428
- package/src/nativeApi.ts +7 -10
- package/src/oss/OSSClient.ts +20 -0
- package/src/oss/downloadService.ts +73 -73
- package/src/oss/index.ts +1 -5
- package/src/oss/multiUpload.ts +7 -4
- package/src/oss/servtoken.ts +2 -52
- package/src/oss/uploadService.ts +64 -78
- package/src/spuConfig.ts +7 -10
- package/src/storageProxy.ts +11 -13
- package/src/test.ts +3 -17
- package/src/types/global.d.ts +1 -1
- package/src/types/index.d.ts +13 -15
- package/src/types/shims-lib.d.ts +4 -10
- package/src/urlquery.ts +37 -5
- package/src/utils.ts +15 -31
- package/src/wxworksuitePlugin.ts +25 -0
package/src/login.ts
CHANGED
|
@@ -1,135 +1,135 @@
|
|
|
1
1
|
import { cloneDeep } from 'lodash-es'
|
|
2
2
|
import jwtDecode from 'jwt-decode'
|
|
3
|
-
import { lsProxy
|
|
3
|
+
import { lsProxy } from './storageProxy'
|
|
4
|
+
import { axios } from './axios'
|
|
4
5
|
import cloudServ from './cloudServ'
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
// window.aPaaS = {
|
|
9
|
-
// getWebInitParams (callback: any) {
|
|
10
|
-
// callback && callback({
|
|
11
|
-
// envname: 'xxx'
|
|
12
|
-
// })
|
|
13
|
-
// }
|
|
14
|
-
// }
|
|
15
|
-
|
|
6
|
+
import core from './core'
|
|
7
|
+
import { urlquery } from './urlquery'
|
|
16
8
|
|
|
17
9
|
type JwtResult = {
|
|
18
10
|
LoginUser: IAny
|
|
19
11
|
exp: number
|
|
20
12
|
} | null
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
private cache: IAny = {}
|
|
14
|
+
const cache: IAny = {}
|
|
24
15
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
16
|
+
function getData(key: string) {
|
|
17
|
+
if (cache[key]) {
|
|
18
|
+
return cache[key]
|
|
19
|
+
} else {
|
|
20
|
+
const data = lsProxy.getItem(key)
|
|
21
|
+
cache[key] = data
|
|
22
|
+
return data
|
|
33
23
|
}
|
|
24
|
+
}
|
|
34
25
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
26
|
+
function setData(key: string, value: any) {
|
|
27
|
+
cache[key] = value
|
|
28
|
+
lsProxy.setItem(key, value)
|
|
29
|
+
}
|
|
39
30
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
31
|
+
function removeData(key: string) {
|
|
32
|
+
delete cache[key]
|
|
33
|
+
lsProxy.removeItem(key)
|
|
34
|
+
}
|
|
44
35
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
})
|
|
36
|
+
async function getEnvname(): Promise<string> {
|
|
37
|
+
let envname = ''
|
|
38
|
+
|
|
39
|
+
// web 查 context 的 envname
|
|
40
|
+
let context: any = lsProxy.getItem('context')
|
|
41
|
+
context && (context = JSON.parse(context))
|
|
42
|
+
const contextEnvname = context?.envname || ''
|
|
43
|
+
|
|
44
|
+
// 链接有些spu可能会传 envname
|
|
45
|
+
const queryEnvname = getQueryEnvname()
|
|
46
|
+
|
|
47
|
+
if (contextEnvname) {
|
|
48
|
+
envname = contextEnvname
|
|
49
|
+
} else if (queryEnvname) {
|
|
50
|
+
envname = queryEnvname
|
|
51
|
+
} else if (window?.aPaaS?.getWebInitParams && window?.Native?.setNavigationBarReturnButton) {
|
|
52
|
+
// 手机端 查 envname
|
|
53
|
+
// 只有手机端有 setNavigationBarReturnButton 方法
|
|
54
|
+
envname = await new Promise((resolve, reject) => {
|
|
55
|
+
window.aPaaS.getWebInitParams((params: any) => {
|
|
56
|
+
resolve(params?.envname || '')
|
|
67
57
|
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return envname
|
|
58
|
+
})
|
|
71
59
|
}
|
|
72
60
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
61
|
+
return envname
|
|
62
|
+
}
|
|
76
63
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
64
|
+
function setQueryEnvname(value: string) {
|
|
65
|
+
setData('envname', value)
|
|
66
|
+
}
|
|
80
67
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
68
|
+
function getQueryEnvname() {
|
|
69
|
+
return getData('envname') || ''
|
|
70
|
+
}
|
|
84
71
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
72
|
+
function removeQueryEnvname() {
|
|
73
|
+
removeData('envname')
|
|
74
|
+
}
|
|
89
75
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
76
|
+
function getToken() {
|
|
77
|
+
return getData('token')
|
|
78
|
+
// return lsProxy.getItem('token') as string
|
|
79
|
+
}
|
|
93
80
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
81
|
+
function setToken(value: string) {
|
|
82
|
+
setData('token', value)
|
|
83
|
+
}
|
|
97
84
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
function removeToken() {
|
|
86
|
+
removeData('token')
|
|
87
|
+
}
|
|
101
88
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
89
|
+
function getTokenExpires() {
|
|
90
|
+
return getData('tokenexpires')
|
|
91
|
+
// return lsProxy.getItem('tokenexpires') as string
|
|
92
|
+
}
|
|
105
93
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
94
|
+
function setTokenExpires(value: string) {
|
|
95
|
+
setData('tokenexpires', value)
|
|
96
|
+
}
|
|
109
97
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
98
|
+
function removeTokenExpires() {
|
|
99
|
+
removeData('tokenexpires')
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function getRefreshToken() {
|
|
103
|
+
return getData('refreshtoken')
|
|
104
|
+
// return lsProxy.getItem('refreshtoken') as string
|
|
105
|
+
}
|
|
114
106
|
|
|
115
|
-
|
|
116
|
-
|
|
107
|
+
function setRefreshToken(value: string) {
|
|
108
|
+
setData('refreshtoken', value)
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function removeRefreshToken() {
|
|
112
|
+
removeData('refreshtoken')
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function updateToken() {
|
|
116
|
+
const loginState = getLoginState()
|
|
117
|
+
|
|
118
|
+
if (!loginState.islogin && loginState.type <= 1) {
|
|
119
|
+
console.warn('当前未登录/token过期,不支持自动刷新token。')
|
|
120
|
+
return false
|
|
117
121
|
}
|
|
118
122
|
|
|
119
|
-
|
|
120
|
-
|
|
123
|
+
if (loginState.role === 'center') {
|
|
124
|
+
console.warn('当前登录为产品运营中心用户,不支持自动刷新token。')
|
|
125
|
+
return false
|
|
121
126
|
}
|
|
122
127
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
const token = this.getToken()
|
|
130
|
-
const refreshtoken = this.getRefreshToken()
|
|
131
|
-
const sendToken = this.checkLoginByToken(token) ? token : refreshtoken
|
|
132
|
-
return axios.get('/api/auth/refreshtoken', {
|
|
128
|
+
const token = getToken()
|
|
129
|
+
const refreshtoken = getRefreshToken()
|
|
130
|
+
const sendToken = checkLoginByToken(token) ? token : refreshtoken
|
|
131
|
+
return axios
|
|
132
|
+
.get('/api/auth/refreshtoken', {
|
|
133
133
|
params: {
|
|
134
134
|
refreshtoken: sendToken
|
|
135
135
|
},
|
|
@@ -137,406 +137,512 @@ class Login {
|
|
|
137
137
|
isShowErrorMessage: false,
|
|
138
138
|
isSendToken: false,
|
|
139
139
|
headers: {
|
|
140
|
-
token: sendToken
|
|
140
|
+
token: sendToken,
|
|
141
|
+
tecode: getUser('tenantcode')
|
|
141
142
|
}
|
|
142
|
-
})
|
|
143
|
+
})
|
|
144
|
+
.then((res: any) => {
|
|
143
145
|
// console.log(res)
|
|
144
146
|
const data = res?.data
|
|
145
147
|
if (data) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
148
|
+
setToken(data.token)
|
|
149
|
+
setRefreshToken(data.refreshtoken)
|
|
150
|
+
setTokenExpires(data.tokenexpires)
|
|
149
151
|
}
|
|
150
152
|
})
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
private refreshtokenTimer: number | null = null
|
|
154
|
-
|
|
155
|
-
startRefreshtoken () {
|
|
156
|
-
// 如果是产品运营中心 则不走刷新token流程
|
|
157
|
-
if (this.checkLogin() && this.getRole() === 'center') {
|
|
158
|
-
console.warn('当前登录为产品运营中心用户,不支持自动刷新token。')
|
|
159
|
-
return false
|
|
160
|
-
}
|
|
153
|
+
}
|
|
161
154
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
155
|
+
let refreshtokenTimer: number | null = null
|
|
156
|
+
|
|
157
|
+
function startRefreshtoken() {
|
|
158
|
+
const loginState = getLoginState()
|
|
159
|
+
// 如果是产品运营中心 则不走刷新token流程
|
|
160
|
+
if (loginState.role === 'center') {
|
|
161
|
+
console.warn('当前登录为产品运营中心用户,不支持自动刷新token。')
|
|
162
|
+
return false
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// stopRefreshtoken()
|
|
166
|
+
clearTimeout(refreshtokenTimer as number)
|
|
167
|
+
refreshtokenTimer = null
|
|
168
|
+
|
|
169
|
+
// 如果有登录 但 refreshtoken 不是完整 token 则10秒后【需要等单点登录走完后才刷新不然会被覆盖】刷新一次取到完整 token
|
|
170
|
+
// 如果有登录 且 refreshtoken 是完整 token 如果剩余时间大于10分钟 则每隔10分钟刷一次 否则过期前15秒更新 token
|
|
171
|
+
// 如果没登录 每隔10秒走token更新逻辑(如果刚开始没登录 后面才登录【不需要再在登陆后写刷新token逻辑】)
|
|
172
|
+
let time = 0
|
|
173
|
+
if (loginState.islogin) {
|
|
174
|
+
const user = getUserByToken(getRefreshToken())
|
|
175
|
+
if (user?.tokenId) {
|
|
176
|
+
time = Number(getTokenExpires()) - Date.now() - 1000 * 15
|
|
177
|
+
// 如果剩余时间大于10分钟 则每隔10分钟刷一次
|
|
178
|
+
if (time > 600000) {
|
|
179
|
+
time = 600000
|
|
180
|
+
} else if (time < 0) {
|
|
181
|
+
time = 0
|
|
180
182
|
}
|
|
181
183
|
} else {
|
|
182
|
-
time =
|
|
184
|
+
time = 10000
|
|
185
|
+
}
|
|
186
|
+
} else {
|
|
187
|
+
if (loginState.type === 2) {
|
|
188
|
+
time = 0
|
|
189
|
+
} else {
|
|
190
|
+
time = 10000
|
|
183
191
|
}
|
|
184
|
-
// time = 5000
|
|
185
|
-
this.refreshtokenTimer = window.setTimeout(async () => {
|
|
186
|
-
if (this.checkLogin()) {
|
|
187
|
-
await this.updateToken()
|
|
188
|
-
}
|
|
189
|
-
this.startRefreshtoken()
|
|
190
|
-
}, time)
|
|
191
192
|
}
|
|
193
|
+
// time = 5000
|
|
194
|
+
refreshtokenTimer = window.setTimeout(async () => {
|
|
195
|
+
if (getLoginState().type >= 2) {
|
|
196
|
+
await updateToken()
|
|
197
|
+
}
|
|
198
|
+
startRefreshtoken()
|
|
199
|
+
}, time)
|
|
200
|
+
}
|
|
192
201
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
202
|
+
function getUser(key?: string): any {
|
|
203
|
+
const user = getData('user')
|
|
204
|
+
const userObj = user ? JSON.parse(user) : null
|
|
205
|
+
if (!key) {
|
|
206
|
+
return userObj
|
|
207
|
+
} else {
|
|
208
|
+
return userObj ? userObj[key] || '' : ''
|
|
196
209
|
}
|
|
210
|
+
}
|
|
197
211
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return userObj ? (userObj[key] || '') : ''
|
|
205
|
-
}
|
|
212
|
+
function setUser(value: string | IAny) {
|
|
213
|
+
let res
|
|
214
|
+
if (typeof value === 'string') {
|
|
215
|
+
res = JSON.parse(value)
|
|
216
|
+
} else {
|
|
217
|
+
res = cloneDeep(value)
|
|
206
218
|
}
|
|
207
219
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
res = JSON.parse(value)
|
|
212
|
-
} else {
|
|
213
|
-
res = cloneDeep(value)
|
|
214
|
-
}
|
|
220
|
+
for (const x in res) {
|
|
221
|
+
res[x.toLowerCase()] = res[x]
|
|
222
|
+
}
|
|
215
223
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
224
|
+
setData('user', JSON.stringify(res))
|
|
225
|
+
}
|
|
219
226
|
|
|
220
|
-
|
|
227
|
+
function setUserByToken(token: string) {
|
|
228
|
+
const user = getUserByToken(token)
|
|
229
|
+
if (user) {
|
|
230
|
+
setUser(user)
|
|
231
|
+
} else {
|
|
232
|
+
removeUser()
|
|
221
233
|
}
|
|
234
|
+
}
|
|
222
235
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
236
|
+
function getUserByToken(token: string) {
|
|
237
|
+
const jwtInfo = parseToken(token)
|
|
238
|
+
if (jwtInfo && jwtInfo.LoginUser) {
|
|
239
|
+
return jwtInfo.LoginUser
|
|
240
|
+
} else {
|
|
241
|
+
return null
|
|
230
242
|
}
|
|
243
|
+
}
|
|
231
244
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
return jwtInfo.LoginUser
|
|
236
|
-
} else {
|
|
237
|
-
return null
|
|
238
|
-
}
|
|
239
|
-
}
|
|
245
|
+
function removeUser() {
|
|
246
|
+
removeData('user')
|
|
247
|
+
}
|
|
240
248
|
|
|
241
|
-
|
|
242
|
-
|
|
249
|
+
function parseToken(token?: string) {
|
|
250
|
+
if (!token) {
|
|
251
|
+
console.error('token为空 jwt解析token出错')
|
|
252
|
+
return null
|
|
253
|
+
}
|
|
254
|
+
try {
|
|
255
|
+
return jwtDecode<JwtResult>(token)
|
|
256
|
+
} catch (e) {
|
|
257
|
+
console.error('jwt解析token出错', token, e)
|
|
258
|
+
return null
|
|
243
259
|
}
|
|
260
|
+
}
|
|
244
261
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
262
|
+
// // 产品运营中心token
|
|
263
|
+
// {
|
|
264
|
+
// "LoginUser": {
|
|
265
|
+
// "appId": "100",
|
|
266
|
+
// "tenantCode": "1656652",
|
|
267
|
+
// "productCode": "100000000000000000",
|
|
268
|
+
// "productVersionCode": null,
|
|
269
|
+
// "clientTypeCode": null,
|
|
270
|
+
// "userCode": "6",
|
|
271
|
+
// "accountCode": "6",
|
|
272
|
+
// "username": "庄焕滨",
|
|
273
|
+
// "tokenId": "bd69b4a4-5376-47cd-91c3-f1e1576440e5",
|
|
274
|
+
// "appCodes": null,
|
|
275
|
+
// "appCode": null,
|
|
276
|
+
// "platRoleCodes": ["1637696814759153664"],
|
|
277
|
+
// "metamodeltype": 2,
|
|
278
|
+
// "orgCode": "1751852081616130048",
|
|
279
|
+
// "centerRole": true
|
|
280
|
+
// },
|
|
281
|
+
// "TwoFactorAuthCode": "6f56da978dffe31a3b03a56c446f9467",
|
|
282
|
+
// "exp": 1751694745
|
|
283
|
+
// }
|
|
284
|
+
|
|
285
|
+
// // 租户token
|
|
286
|
+
// {
|
|
287
|
+
// "exp": 1720161305,
|
|
288
|
+
// "LoginUser": {
|
|
289
|
+
// "accountInfoCode": "1803686723986010112",
|
|
290
|
+
// "accountCode": "1803686724107644928",
|
|
291
|
+
// "tenantCode": "3000911",
|
|
292
|
+
// "productCode": "100000000000000000",
|
|
293
|
+
// "productVersionCode": "30000000000000911",
|
|
294
|
+
// "clientTypeCode": 1,
|
|
295
|
+
// "tokenId": "8614059e-69a5-4e1e-a948-f2ef680d0dd5",
|
|
296
|
+
// "orgCode": "1803686397149065216",
|
|
297
|
+
// "userInfoId": "1806591894588108800",
|
|
298
|
+
// "userInfoName": "woOUQJEAAAn4r5-7jffaxad6yotbEZ5A",
|
|
299
|
+
// "positionCode": "1803686397304254473",
|
|
300
|
+
// "positionName": "系统管理员-勿删",
|
|
301
|
+
// "memberCode": "1806591894659411968",
|
|
302
|
+
// "refPositionCode": "1300728614534385664",
|
|
303
|
+
// "categoryCode": "",
|
|
304
|
+
// "orgStructTypeId": "1",
|
|
305
|
+
// "userName": null,
|
|
306
|
+
// "userName1": "woOUQJEAAAn4r5-7jffaxad6yotbEZ5A",
|
|
307
|
+
// "userName2": null,
|
|
308
|
+
// "userName3": null,
|
|
309
|
+
// "tenantName": "智慧100-企微版-V9.1.1开发租户",
|
|
310
|
+
// "appCode": "sales",
|
|
311
|
+
// "appCodes": [
|
|
312
|
+
// "promotion",
|
|
313
|
+
// "distribution",
|
|
314
|
+
// "sales"
|
|
315
|
+
// ],
|
|
316
|
+
// "subPdCodes": [
|
|
317
|
+
// "sfa",
|
|
318
|
+
// "dms",
|
|
319
|
+
// "pmm",
|
|
320
|
+
// "tpm",
|
|
321
|
+
// "ai"
|
|
322
|
+
// ],
|
|
323
|
+
// "codepath": "1.1803686395634921472.1803686397149065216.",
|
|
324
|
+
// "isleaforg": "true",
|
|
325
|
+
// "metamodeltype": 1,
|
|
326
|
+
// "isSmsLogin": false
|
|
327
|
+
// }
|
|
328
|
+
// }
|
|
329
|
+
// 查询token所属登录角色
|
|
330
|
+
// tenant: 普通租户登录 默认
|
|
331
|
+
// center: 产品运营中心登录 单点登录时只带 token 没带 refreshtoken 和 tokenexpires
|
|
332
|
+
function getRoleByToken(token?: string) {
|
|
333
|
+
let loginRole: 'center' | 'tenant' = 'tenant' // center | tenant
|
|
334
|
+
if (token) {
|
|
335
|
+
const jwtInfo = parseToken(token)
|
|
336
|
+
if (jwtInfo?.LoginUser?.centerRole) {
|
|
337
|
+
// 产品运营中心登录
|
|
338
|
+
loginRole = 'center'
|
|
255
339
|
}
|
|
256
340
|
}
|
|
341
|
+
return loginRole
|
|
342
|
+
}
|
|
257
343
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
// "appCode": null,
|
|
272
|
-
// "platRoleCodes": ["1637696814759153664"],
|
|
273
|
-
// "metamodeltype": 2,
|
|
274
|
-
// "orgCode": "1751852081616130048",
|
|
275
|
-
// "centerRole": true
|
|
276
|
-
// },
|
|
277
|
-
// "TwoFactorAuthCode": "6f56da978dffe31a3b03a56c446f9467",
|
|
278
|
-
// "exp": 1751694745
|
|
279
|
-
// }
|
|
280
|
-
|
|
281
|
-
// // 租户token
|
|
282
|
-
// {
|
|
283
|
-
// "exp": 1720161305,
|
|
284
|
-
// "LoginUser": {
|
|
285
|
-
// "accountInfoCode": "1803686723986010112",
|
|
286
|
-
// "accountCode": "1803686724107644928",
|
|
287
|
-
// "tenantCode": "3000911",
|
|
288
|
-
// "productCode": "100000000000000000",
|
|
289
|
-
// "productVersionCode": "30000000000000911",
|
|
290
|
-
// "clientTypeCode": 1,
|
|
291
|
-
// "tokenId": "8614059e-69a5-4e1e-a948-f2ef680d0dd5",
|
|
292
|
-
// "orgCode": "1803686397149065216",
|
|
293
|
-
// "userInfoId": "1806591894588108800",
|
|
294
|
-
// "userInfoName": "woOUQJEAAAn4r5-7jffaxad6yotbEZ5A",
|
|
295
|
-
// "positionCode": "1803686397304254473",
|
|
296
|
-
// "positionName": "系统管理员-勿删",
|
|
297
|
-
// "memberCode": "1806591894659411968",
|
|
298
|
-
// "refPositionCode": "1300728614534385664",
|
|
299
|
-
// "categoryCode": "",
|
|
300
|
-
// "orgStructTypeId": "1",
|
|
301
|
-
// "userName": null,
|
|
302
|
-
// "userName1": "woOUQJEAAAn4r5-7jffaxad6yotbEZ5A",
|
|
303
|
-
// "userName2": null,
|
|
304
|
-
// "userName3": null,
|
|
305
|
-
// "tenantName": "智慧100-企微版-V9.1.1开发租户",
|
|
306
|
-
// "appCode": "sales",
|
|
307
|
-
// "appCodes": [
|
|
308
|
-
// "promotion",
|
|
309
|
-
// "distribution",
|
|
310
|
-
// "sales"
|
|
311
|
-
// ],
|
|
312
|
-
// "subPdCodes": [
|
|
313
|
-
// "sfa",
|
|
314
|
-
// "dms",
|
|
315
|
-
// "pmm",
|
|
316
|
-
// "tpm",
|
|
317
|
-
// "ai"
|
|
318
|
-
// ],
|
|
319
|
-
// "codepath": "1.1803686395634921472.1803686397149065216.",
|
|
320
|
-
// "isleaforg": "true",
|
|
321
|
-
// "metamodeltype": 1,
|
|
322
|
-
// "isSmsLogin": false
|
|
323
|
-
// }
|
|
324
|
-
// }
|
|
325
|
-
// 查询token所属登录角色
|
|
326
|
-
// tenant: 普通租户登录 默认
|
|
327
|
-
// center: 产品运营中心登录 单点登录时只带 token 没带 refreshtoken 和 tokenexpires
|
|
328
|
-
getRoleByToken (token?: string) {
|
|
329
|
-
let loginRole: 'center' | 'tenant' = 'tenant' // center | tenant
|
|
330
|
-
if (token) {
|
|
331
|
-
const jwtInfo = this.jwtDecode(token)
|
|
332
|
-
if (jwtInfo?.LoginUser?.centerRole) {
|
|
333
|
-
// 产品运营中心登录
|
|
334
|
-
loginRole = 'center'
|
|
335
|
-
}
|
|
344
|
+
function getRole() {
|
|
345
|
+
return getRoleByToken(getToken())
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// 检测token是否过期
|
|
349
|
+
function checkLoginByToken(token?: string) {
|
|
350
|
+
let haslogged = false
|
|
351
|
+
if (token) {
|
|
352
|
+
const jwtInfo = parseToken(token)
|
|
353
|
+
if (jwtInfo?.exp) {
|
|
354
|
+
haslogged = Number(jwtInfo.exp + '000') > Date.now()
|
|
355
|
+
} else {
|
|
356
|
+
haslogged = false
|
|
336
357
|
}
|
|
337
|
-
return loginRole
|
|
338
358
|
}
|
|
359
|
+
return haslogged
|
|
360
|
+
}
|
|
339
361
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
362
|
+
// 检测当前用户是否登录状态
|
|
363
|
+
function checkLogin() {
|
|
364
|
+
return checkLoginByToken(getToken())
|
|
365
|
+
// return getLoginState().islogin
|
|
366
|
+
}
|
|
343
367
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
368
|
+
function getLoginState() {
|
|
369
|
+
let role: 'center' | 'tenant' = 'tenant' // center | tenant
|
|
370
|
+
let islogin = false
|
|
371
|
+
// 0: 未登录 缓存中没有token refreshtoken tokenexpires
|
|
372
|
+
// 1: 有登录过 缓存中有token refreshtoken tokenexpires token 过期 refreshtoken 过期
|
|
373
|
+
// 2: 有登录过 缓存中有token refreshtoken tokenexpires token 过期 refreshtoken 未过期
|
|
374
|
+
// 10: 有登录过 缓存中有token refreshtoken tokenexpires token 未过期 refreshtoken 未过期
|
|
375
|
+
let type: 0 | 1 | 2 | 10 = 0
|
|
376
|
+
|
|
377
|
+
const token = getToken()
|
|
378
|
+
|
|
379
|
+
if (token) {
|
|
380
|
+
role = getRoleByToken(token)
|
|
381
|
+
if (role === 'center') {
|
|
382
|
+
// 产品运营中心的token是永久的不会过期 且 没有 refreshtoken 和 tokenexpires
|
|
383
|
+
islogin = checkLoginByToken(token)
|
|
384
|
+
type = 10
|
|
385
|
+
} else {
|
|
386
|
+
const refreshtoken = getRefreshToken()
|
|
387
|
+
const tokenexpires = getTokenExpires()
|
|
388
|
+
const now = Date.now()
|
|
389
|
+
|
|
390
|
+
if (refreshtoken && tokenexpires) {
|
|
391
|
+
if (Number(tokenexpires) > now && checkLoginByToken(token)) {
|
|
392
|
+
islogin = true
|
|
393
|
+
type = 10
|
|
394
|
+
} else {
|
|
395
|
+
islogin = false
|
|
396
|
+
if (checkLoginByToken(refreshtoken)) {
|
|
397
|
+
type = 2
|
|
398
|
+
} else {
|
|
399
|
+
type = 1
|
|
400
|
+
}
|
|
357
401
|
}
|
|
358
402
|
}
|
|
359
403
|
}
|
|
360
|
-
return haslogged
|
|
361
404
|
}
|
|
362
405
|
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const now = Date.now()
|
|
368
|
-
const jwtInfo = this.jwtDecode(token)
|
|
369
|
-
if (jwtInfo?.exp) {
|
|
370
|
-
haslogged = Number(jwtInfo.exp + '000') > now
|
|
371
|
-
} else {
|
|
372
|
-
haslogged = false
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
return haslogged
|
|
406
|
+
return {
|
|
407
|
+
role,
|
|
408
|
+
islogin,
|
|
409
|
+
type
|
|
376
410
|
}
|
|
411
|
+
}
|
|
377
412
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
413
|
+
// 接口请求回来的 userInfo 有 functioncodes 以便做权限校验
|
|
414
|
+
// 有可能是中心角色请求失败 兼容不报错
|
|
415
|
+
async function getAndSetUserInfo() {
|
|
416
|
+
try {
|
|
417
|
+
const accountinfo = await axios
|
|
418
|
+
.post('/api/teapi/rolepermission/account/getaccountinfo', {
|
|
419
|
+
positionid: getUser('positioncode') || '',
|
|
384
420
|
deviceinfo: '',
|
|
385
421
|
sysversion: '',
|
|
386
422
|
clientversion: ''
|
|
387
|
-
})
|
|
423
|
+
})
|
|
424
|
+
.then((res: any) => {
|
|
388
425
|
if (res.code === 200 && res.data) {
|
|
389
426
|
return res.data
|
|
390
427
|
} else {
|
|
391
428
|
return null
|
|
392
429
|
}
|
|
393
430
|
})
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
}
|
|
397
|
-
} catch (e) {
|
|
398
|
-
console.error(e)
|
|
399
|
-
console.warn('获取用户信息失败,当前您登录的帐号可能为非标准租户帐号。')
|
|
431
|
+
if (accountinfo) {
|
|
432
|
+
setUser(accountinfo)
|
|
400
433
|
}
|
|
434
|
+
} catch (e) {
|
|
435
|
+
console.error(e)
|
|
436
|
+
console.warn('获取用户信息失败,当前您登录的帐号可能为非标准租户帐号。')
|
|
401
437
|
}
|
|
438
|
+
}
|
|
402
439
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
}
|
|
440
|
+
function formatTenant(tenant: ITenantInfo) {
|
|
441
|
+
if (!tenant) {
|
|
442
|
+
return null
|
|
443
|
+
}
|
|
444
|
+
const cloundTagMap = ['storage', 'storage-1d', 'storage-1y', 'storage-3m']
|
|
445
|
+
const result: NormalizedCloudServ = {}
|
|
446
|
+
for (const keyItem of cloundTagMap) {
|
|
447
|
+
const cloudServ = tenant.cloudserv[keyItem as StorageEnum]
|
|
448
|
+
if (cloudServ) {
|
|
449
|
+
result[keyItem as StorageEnum] = {
|
|
450
|
+
cloudserv_storage_provider: cloudServ.provider,
|
|
451
|
+
cloudserv_storage_storagebucket: cloudServ.storagebucket,
|
|
452
|
+
cloudserv_storage_storageendpoint: cloudServ.storageendpoint,
|
|
453
|
+
cloudserv_storage_storageurl: cloudServ.storageurl,
|
|
454
|
+
cloudserv_storage_accesskeyid: cloudServ.accesskeyid,
|
|
455
|
+
cloudserv_storage_region: cloudServ.region
|
|
420
456
|
}
|
|
421
457
|
}
|
|
422
|
-
if (Object.keys(result).length === 0) {
|
|
423
|
-
return null
|
|
424
|
-
}
|
|
425
|
-
return result
|
|
426
458
|
}
|
|
459
|
+
if (Object.keys(result).length === 0) {
|
|
460
|
+
return null
|
|
461
|
+
}
|
|
462
|
+
return result
|
|
463
|
+
}
|
|
427
464
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
465
|
+
async function getAndSetTenant(tenantcode?: string) {
|
|
466
|
+
try {
|
|
467
|
+
const tenantsRes: null | ITenantInfo[] = await axios.get('/api/auth/tenantlist', {}).then((res: any) => {
|
|
468
|
+
return res?.data?.tenants
|
|
469
|
+
})
|
|
433
470
|
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
471
|
+
let tenant: ITenantInfo | null = null
|
|
472
|
+
if (tenantsRes?.length) {
|
|
473
|
+
if (!tenantcode) {
|
|
474
|
+
tenant = tenantsRes[0]
|
|
475
|
+
} else {
|
|
476
|
+
tenant = tenantsRes.find((item) => item.code === tenantcode) || null
|
|
441
477
|
}
|
|
478
|
+
}
|
|
442
479
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
480
|
+
if (!tenant) {
|
|
481
|
+
lsProxy.removeItem('tenant')
|
|
482
|
+
cloudServ.remove()
|
|
483
|
+
} else {
|
|
484
|
+
lsProxy.setItem('tenant', JSON.stringify(tenant))
|
|
485
|
+
const normalizedTenant = formatTenant(tenant)
|
|
486
|
+
if (normalizedTenant) {
|
|
487
|
+
cloudServ.set(normalizedTenant)
|
|
452
488
|
}
|
|
453
|
-
} catch (e) {
|
|
454
|
-
console.error(e)
|
|
455
|
-
console.warn('获取租户信息失败,当前您登录的帐号可能为非标准租户帐号。')
|
|
456
489
|
}
|
|
490
|
+
} catch (e) {
|
|
491
|
+
console.error(e)
|
|
492
|
+
console.warn('获取租户信息失败,当前您登录的帐号可能为非标准租户帐号。')
|
|
457
493
|
}
|
|
494
|
+
}
|
|
458
495
|
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
}
|
|
481
|
-
} else {
|
|
482
|
-
// 如果本地已经登录 且 query 登录参数与本地一致 说明是刚登录没多久【token也没刷新过】 视为已经登录 不需再走单点登录流程
|
|
483
|
-
if (this.checkLogin() && token === this.getToken() && refreshtoken === this.getRefreshToken() && tokenexpires === this.getTokenExpires()) {
|
|
484
|
-
isneedlogin = false
|
|
485
|
-
flag = true
|
|
486
|
-
}
|
|
496
|
+
// 单点登录
|
|
497
|
+
async function singleLogin(query: IAny) {
|
|
498
|
+
query = cloneDeep(query)
|
|
499
|
+
|
|
500
|
+
let flag = false // 是否登录成功
|
|
501
|
+
const token = query.token
|
|
502
|
+
const refreshtoken = query.refreshtoken
|
|
503
|
+
const tokenexpires = query.tokenexpires
|
|
504
|
+
const envname = query.envname
|
|
505
|
+
const context = query.context
|
|
506
|
+
|
|
507
|
+
if (checkLoginByToken(token)) {
|
|
508
|
+
let isneedlogin = true // 是否需要走单点登录流程
|
|
509
|
+
const loginRole = getRoleByToken(token)
|
|
510
|
+
|
|
511
|
+
if (loginRole === 'center') {
|
|
512
|
+
// 如果本地已经登录 且 query 登录参数与本地一致 说明是刚登录没多久【token也没刷新过】 视为已经登录 不需再走单点登录流程
|
|
513
|
+
// 之所以不强制校验 refreshtoken tokenexpires 是因为安装卸载配置页面有可能放在产品运营中心 没有这两字段
|
|
514
|
+
if (checkLogin() && token === getToken()) {
|
|
515
|
+
isneedlogin = false
|
|
516
|
+
flag = true
|
|
487
517
|
}
|
|
518
|
+
} else {
|
|
519
|
+
// 如果本地已经登录 且 query 登录参数与本地一致 说明是刚登录没多久【token也没刷新过】 视为已经登录 不需再走单点登录流程
|
|
520
|
+
if (
|
|
521
|
+
checkLogin() &&
|
|
522
|
+
token === getToken() &&
|
|
523
|
+
refreshtoken === getRefreshToken() &&
|
|
524
|
+
tokenexpires === getTokenExpires()
|
|
525
|
+
) {
|
|
526
|
+
isneedlogin = false
|
|
527
|
+
flag = true
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
if (isneedlogin) {
|
|
532
|
+
setToken(token)
|
|
533
|
+
setUserByToken(token) // 解析token为用户信息存入
|
|
534
|
+
|
|
535
|
+
refreshtoken ? setRefreshToken(refreshtoken) : removeRefreshToken()
|
|
536
|
+
tokenexpires ? setTokenExpires(tokenexpires) : removeTokenExpires()
|
|
537
|
+
envname ? setQueryEnvname(envname) : removeQueryEnvname()
|
|
488
538
|
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
context && lsProxy.setItem('context', decodeURIComponent(context))
|
|
500
|
-
|
|
501
|
-
// 单点登录写入 token 之后 换取完整的 refreshtoken
|
|
502
|
-
try {
|
|
503
|
-
if (this.checkLogin()) {
|
|
504
|
-
const user = this.getUserByToken(this.getRefreshToken())
|
|
505
|
-
if (!user?.tokenId) {
|
|
506
|
-
this.updateToken()
|
|
507
|
-
}
|
|
539
|
+
// context 上下文字段 产品运营中心安装 卸载 配置 和 产品配置中心业务配置 页面需要用到
|
|
540
|
+
// web 端有传 app没传 需要做兼容
|
|
541
|
+
context && lsProxy.setItem('context', decodeURIComponent(context))
|
|
542
|
+
|
|
543
|
+
// 单点登录写入 token 之后 换取完整的 refreshtoken
|
|
544
|
+
try {
|
|
545
|
+
if (checkLogin()) {
|
|
546
|
+
const user = getUserByToken(getRefreshToken())
|
|
547
|
+
if (!user?.tokenId) {
|
|
548
|
+
updateToken()
|
|
508
549
|
}
|
|
509
|
-
} catch (err) {
|
|
510
|
-
console.error(err)
|
|
511
550
|
}
|
|
551
|
+
} catch (err) {
|
|
552
|
+
console.error(err)
|
|
553
|
+
}
|
|
512
554
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
555
|
+
// 这里兼容报错
|
|
556
|
+
await getAndSetTenant()
|
|
557
|
+
await getAndSetUserInfo()
|
|
516
558
|
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
flag =
|
|
521
|
-
console.error('没传 token 或所传 token 已过期,无法单点登录。')
|
|
559
|
+
// 单点登录后 获取 web 开发者模式 如果是则设置 isdebugger
|
|
560
|
+
urlquery.dealWebDebugger()
|
|
561
|
+
|
|
562
|
+
flag = true
|
|
522
563
|
}
|
|
564
|
+
} else {
|
|
565
|
+
flag = false
|
|
566
|
+
console.error('没传 token 或所传 token 已过期,无法单点登录。')
|
|
567
|
+
}
|
|
523
568
|
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
569
|
+
// 单点登录后 无论是否成功 都需要删除 query 中相关参数
|
|
570
|
+
token && delete query.token
|
|
571
|
+
refreshtoken && delete query.refreshtoken
|
|
572
|
+
tokenexpires && delete query.tokenexpires
|
|
573
|
+
envname && delete query.envname
|
|
574
|
+
context && delete query.context
|
|
530
575
|
|
|
531
|
-
|
|
576
|
+
// debugger
|
|
532
577
|
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
}
|
|
578
|
+
return {
|
|
579
|
+
flag,
|
|
580
|
+
query
|
|
537
581
|
}
|
|
538
582
|
}
|
|
539
583
|
|
|
540
|
-
|
|
584
|
+
function installAuth(options: any) {
|
|
585
|
+
startRefreshtoken()
|
|
586
|
+
if (options.router) {
|
|
587
|
+
options.router.beforeEach(async (to: any, from: any, next: any) => {
|
|
588
|
+
// console.log(from)
|
|
589
|
+
// console.log(to)
|
|
590
|
+
// const isInitVisit = from.path === '/' && from.name === undefined // 路由初始化访问
|
|
591
|
+
// console.log('isInitVisit', isInitVisit)
|
|
592
|
+
|
|
593
|
+
// 自动登录
|
|
594
|
+
if (to.query.token) {
|
|
595
|
+
const singleLoginRes = await singleLogin(to.query)
|
|
596
|
+
if (singleLoginRes.flag) {
|
|
597
|
+
// debugger
|
|
598
|
+
// next()
|
|
599
|
+
await core.initGetData()
|
|
600
|
+
next({
|
|
601
|
+
path: to.path,
|
|
602
|
+
params: to.params,
|
|
603
|
+
query: singleLoginRes.query
|
|
604
|
+
})
|
|
605
|
+
} else {
|
|
606
|
+
console.error('单点登录失败,请检查链接所传 token 是否非法或过期。')
|
|
607
|
+
next()
|
|
608
|
+
}
|
|
609
|
+
} else {
|
|
610
|
+
next()
|
|
611
|
+
}
|
|
612
|
+
})
|
|
613
|
+
} else {
|
|
614
|
+
console.warn(
|
|
615
|
+
'@smart100/spu-web-plugin 需要传入一个 vue-router 实例以便执行单点登录逻辑,如果您没传 vue-router 实例则需要自行在合适的位置执行单点登录代码。'
|
|
616
|
+
)
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
if (checkLogin()) {
|
|
620
|
+
core.initGetData()
|
|
621
|
+
}
|
|
622
|
+
}
|
|
541
623
|
|
|
542
|
-
export
|
|
624
|
+
export {
|
|
625
|
+
installAuth,
|
|
626
|
+
getEnvname,
|
|
627
|
+
getToken,
|
|
628
|
+
// setToken,
|
|
629
|
+
// removeToken,
|
|
630
|
+
getTokenExpires,
|
|
631
|
+
// setTokenExpires,
|
|
632
|
+
// removeTokenExpires,
|
|
633
|
+
getRefreshToken,
|
|
634
|
+
// setRefreshToken,
|
|
635
|
+
// removeRefreshToken,
|
|
636
|
+
updateToken,
|
|
637
|
+
// startRefreshtoken,
|
|
638
|
+
getUser,
|
|
639
|
+
// setUser,
|
|
640
|
+
getRole,
|
|
641
|
+
// removeUser,
|
|
642
|
+
// getUserByToken,
|
|
643
|
+
// setUserByToken,
|
|
644
|
+
checkLogin,
|
|
645
|
+
getLoginState,
|
|
646
|
+
// checkLoginByToken,
|
|
647
|
+
singleLogin
|
|
648
|
+
}
|