cloud-web-corejs 1.0.54-dev.770 → 1.0.54-dev.771
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/package.json +1 -2
- package/src/components/luckysheet/view.vue +3 -25
- package/src/index.js +359 -204
- package/src/permission.js +18 -74
- package/src/store/modules/permission.js +31 -33
- package/src/store/modules/settings.js +2 -0
- package/src/store/modules/tagsView.js +2 -1
- package/src/store/modules/user.js +11 -17
- package/src/utils/pddLog.js +4 -18
- package/src/views/user/login/indexMixin.js +71 -163
- package/src/bootstrap/business.js +0 -31
- package/src/bootstrap/businessFeatures.js +0 -108
- package/src/utils/externalAssets.js +0 -62
- package/src/utils/loginVab.js +0 -68
- package/src/utils/prefixGlobals.js +0 -11
package/src/permission.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
/**version-1.0*/
|
|
2
|
-
import router from "@base/router";
|
|
3
|
-
import store from "./store";
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
/**version-1.0*/
|
|
2
|
+
import router from "@base/router";
|
|
3
|
+
import store from "./store";
|
|
4
|
+
import {
|
|
5
|
+
Message
|
|
6
|
+
} from "element-ui";
|
|
7
|
+
import NProgress from "nprogress"; // progress bar
|
|
8
|
+
import "nprogress/nprogress.css"; // progress bar style
|
|
9
|
+
import {
|
|
10
|
+
getToken
|
|
11
|
+
} from "./utils/auth"; // get token from cookie
|
|
10
12
|
import settingConfig from "@/settings";
|
|
13
|
+
|
|
11
14
|
import {
|
|
12
|
-
|
|
13
|
-
preloadBusinessFeatures,
|
|
14
|
-
} from "@base/bootstrap/business";
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
saveAccessMenuLog
|
|
15
|
+
saveAccessMenuLog
|
|
18
16
|
} from "./api/user";
|
|
19
17
|
import indexUtil from "./utils/index.js"
|
|
20
18
|
|
|
@@ -26,30 +24,10 @@ const whiteList = [
|
|
|
26
24
|
"/login",
|
|
27
25
|
"/auth-redirect",
|
|
28
26
|
"/report/vform/out_render",
|
|
29
|
-
"/report/xform/out_render",
|
|
27
|
+
"/report/xform/out_render",
|
|
30
28
|
]; // no redirect whitelist
|
|
31
29
|
|
|
32
|
-
//
|
|
33
|
-
const lightweightRoutes = new Set([
|
|
34
|
-
"/login",
|
|
35
|
-
"/auth-redirect",
|
|
36
|
-
"/404",
|
|
37
|
-
]);
|
|
38
|
-
const parallelBusinessRoutes = new Set(["/", "/home"]);
|
|
39
|
-
|
|
40
|
-
function needsBusinessFeatures(to) {
|
|
41
|
-
return !lightweightRoutes.has(to.path)
|
|
42
|
-
&& (getToken() || to.meta.checkToken === false);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function handleBusinessFeatureError(error, next) {
|
|
46
|
-
console.error("[bootstrap] 业务模块加载失败", error);
|
|
47
|
-
Message.error("业务模块加载失败,请刷新后重试");
|
|
48
|
-
NProgress.done();
|
|
49
|
-
next(false);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// qiankun 保活:子应用容器被隐藏期间暂停一切路由响应(配合包入口 update 生命周期)
|
|
30
|
+
// qiankun 保活:子应用容器被隐藏期间暂停一切路由响应(配合包入口 update 生命周期)
|
|
53
31
|
router.beforeEach((to, from, next) => {
|
|
54
32
|
if (store.state.micro && store.state.micro.routerPaused) {
|
|
55
33
|
next(false);
|
|
@@ -59,28 +37,8 @@ router.beforeEach((to, from, next) => {
|
|
|
59
37
|
});
|
|
60
38
|
|
|
61
39
|
router.beforeEach((to, from, next) => {
|
|
62
|
-
|
|
63
|
-
next();
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
40
|
+
// start progress bar
|
|
66
41
|
NProgress.start();
|
|
67
|
-
|
|
68
|
-
// 首页首跳先启动下载,再让鉴权守卫并行拉用户信息和菜单;最终在
|
|
69
|
-
// beforeResolve 中等待安装完成,确保组件渲染前全局能力已经就绪。
|
|
70
|
-
if (parallelBusinessRoutes.has(to.path)) {
|
|
71
|
-
preloadBusinessFeatures();
|
|
72
|
-
next();
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
ensureBusinessFeatures()
|
|
77
|
-
.then(() => next())
|
|
78
|
-
.catch((error) => handleBusinessFeatureError(error, next));
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
router.beforeEach((to, from, next) => {
|
|
82
|
-
// start progress bar
|
|
83
|
-
NProgress.start();
|
|
84
42
|
|
|
85
43
|
store.dispatch("user/initLoginConfig").then(() => {
|
|
86
44
|
const hasToken = getToken();
|
|
@@ -157,26 +115,12 @@ router.beforeEach((to, from, next) => {
|
|
|
157
115
|
}
|
|
158
116
|
})
|
|
159
117
|
|
|
160
|
-
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
router.beforeResolve((to, from, next) => {
|
|
164
|
-
if (
|
|
165
|
-
!needsBusinessFeatures(to)
|
|
166
|
-
|| !parallelBusinessRoutes.has(to.path)
|
|
167
|
-
) {
|
|
168
|
-
next();
|
|
169
|
-
return;
|
|
170
|
-
}
|
|
171
118
|
|
|
172
|
-
ensureBusinessFeatures()
|
|
173
|
-
.then(() => next())
|
|
174
|
-
.catch((error) => handleBusinessFeatureError(error, next));
|
|
175
119
|
});
|
|
176
120
|
|
|
177
121
|
router.onError((error) => {
|
|
178
|
-
// finish progress bar
|
|
179
|
-
console.error(error);
|
|
122
|
+
// finish progress bar
|
|
123
|
+
console.error(error);
|
|
180
124
|
NProgress.done();
|
|
181
125
|
});
|
|
182
126
|
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { constantRoutes } from "@base/router";
|
|
2
2
|
import { asyncRoutes, sidebarRoutes } from "@base/router/modules/system";
|
|
3
|
+
import Layout from "@/layout";
|
|
3
4
|
import { getRouters } from "../../api/menu";
|
|
4
5
|
import router from "@base/router";
|
|
5
6
|
import storeConfig from "../config/index";
|
|
6
7
|
import settings from "@/settings";
|
|
7
8
|
import {
|
|
8
9
|
resolveComponentPath,
|
|
9
|
-
resolveOwner,
|
|
10
|
-
dispatchMenus,
|
|
11
|
-
} from "@base/utils/menuAdapter";
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
resolveOwner,
|
|
11
|
+
dispatchMenus,
|
|
12
|
+
} from "@base/utils/menuAdapter";
|
|
13
|
+
import {
|
|
14
|
+
getAppRegistry,
|
|
15
|
+
registerSubApps,
|
|
16
|
+
buildSubAppRoutes,
|
|
17
|
+
} from "@base/microRouter";
|
|
18
|
+
import MenuFallback from "@base/views/user/menuFallback/index.vue";
|
|
18
19
|
|
|
19
20
|
// qiankun 宿主态(仅 settings.microMainEnabled 的主应用登录后填充)
|
|
20
21
|
let hostRegistryApps = [];
|
|
@@ -235,30 +236,27 @@ const actions = {
|
|
|
235
236
|
if (!isHost) {
|
|
236
237
|
return dispatch("setSidebarRoute", rows);
|
|
237
238
|
}
|
|
238
|
-
return
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return dispatch("setSidebarRoute", rows);
|
|
260
|
-
})
|
|
261
|
-
);
|
|
239
|
+
return getAppRegistry().then((apps) => {
|
|
240
|
+
// 自排除:自身也在注册表时(子应用开宿主形态互访别家应用)不装载自己,
|
|
241
|
+
// 否则会自嵌套且自身菜单被误判为"派发给子应用"而跳过本地路由
|
|
242
|
+
let ownAppCode = settings.appCode || "";
|
|
243
|
+
hostRegistryApps = (apps || []).filter(
|
|
244
|
+
(app) => app.appCode !== ownAppCode
|
|
245
|
+
);
|
|
246
|
+
commit(
|
|
247
|
+
"SET_REGISTRY_APP_CODES",
|
|
248
|
+
hostRegistryApps.map((app) => app.appCode)
|
|
249
|
+
);
|
|
250
|
+
let subAppMenus = dispatchMenus(rows, hostRegistryApps);
|
|
251
|
+
hostMicroRoutes = buildSubAppRoutes(hostRegistryApps, subAppMenus);
|
|
252
|
+
if (hostRegistryApps.length) {
|
|
253
|
+
registerSubApps(hostRegistryApps, {
|
|
254
|
+
subAppMenus,
|
|
255
|
+
userInfo: buildUserInfoSnapshot(rootState.user),
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return dispatch("setSidebarRoute", rows);
|
|
259
|
+
});
|
|
262
260
|
},
|
|
263
261
|
// qiankun 子应用模式:主应用经 props 下发菜单,替代 getRouters 自拉
|
|
264
262
|
generateRoutesFromProps({ dispatch, rootState }, menus = []) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import store from "../index.js";
|
|
2
|
+
import _ from "lodash";
|
|
2
3
|
import { isRepeatable, viewKey } from "@base/utils/repeatOpen";
|
|
3
4
|
|
|
4
5
|
let state, mutations, actions;
|
|
@@ -200,7 +201,7 @@ actions = {
|
|
|
200
201
|
let newView0 = { ...(view || window.$vueRoot.$route) };
|
|
201
202
|
delete newView0.matched;
|
|
202
203
|
newView0.meta.title = title;
|
|
203
|
-
let newView =
|
|
204
|
+
let newView = _.cloneDeep(newView0);
|
|
204
205
|
|
|
205
206
|
commit("UPDATE_VISITED_VIEW", newView);
|
|
206
207
|
},
|
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
getLoginConfig,
|
|
9
9
|
getLogicParamValue,
|
|
10
10
|
} from "../../api/user";
|
|
11
|
-
import { getToken, setToken, clearToken } from "../../utils/auth";
|
|
12
|
-
import router, { resetRouter } from "@base/router";
|
|
13
|
-
import {
|
|
11
|
+
import { getToken, setToken, clearToken } from "../../utils/auth";
|
|
12
|
+
import router, { resetRouter } from "@base/router";
|
|
13
|
+
import { unmountAllMicroApps } from "@base/microRouter";
|
|
14
|
+
import { getDispermissions } from "../../api/menu";
|
|
14
15
|
import settingConfig from "@/settings";
|
|
15
16
|
import storeConfig from "../config/index";
|
|
16
17
|
|
|
@@ -329,21 +330,14 @@ actions = {
|
|
|
329
330
|
configUtil.clearToken();
|
|
330
331
|
// qiankun 宿主:登出必须真正卸载保活中的子应用,
|
|
331
332
|
// 否则换账号登录后切回子应用会复活上一个用户的实例(旧角色/旧路由/旧页面数据)
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
// 微前端 chunk 加载失败不能阻断本地登录态清理
|
|
336
|
-
console.error("[user] 微应用卸载模块加载失败", error);
|
|
337
|
-
})
|
|
338
|
-
.then(() => {
|
|
339
|
-
configUtil.resetRouter();
|
|
340
|
-
sessionStorage.removeItem("easyweb");
|
|
333
|
+
unmountAllMicroApps();
|
|
334
|
+
configUtil.resetRouter();
|
|
335
|
+
sessionStorage.removeItem("easyweb");
|
|
341
336
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
});
|
|
337
|
+
dispatch("tagsView/delAllViews", null, {
|
|
338
|
+
root: true,
|
|
339
|
+
});
|
|
340
|
+
resolve();
|
|
347
341
|
});
|
|
348
342
|
},
|
|
349
343
|
|
package/src/utils/pddLog.js
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
import settingConfig from "@/settings";
|
|
2
|
-
import { loadScript } from "@base/utils/externalAssets";
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export async function initPddLog() {
|
|
8
|
-
if (!settingConfig.pddLogEnabled) return;
|
|
9
|
-
if (!window.PDD_OPEN_init) {
|
|
10
|
-
try {
|
|
11
|
-
await loadScript(PDD_LOG_SDK_URL);
|
|
12
|
-
} catch (error) {
|
|
13
|
-
console.warn("[pddLog] SDK 加载失败", error);
|
|
14
|
-
return;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
if (typeof window.PDD_OPEN_init === "function") {
|
|
18
|
-
pddIntfHandle();
|
|
19
|
-
}
|
|
3
|
+
export function initPddLog() {
|
|
4
|
+
if (!settingConfig.pddLogEnabled || !window.PDD_OPEN_init) return
|
|
5
|
+
pddIntfHandle();
|
|
20
6
|
}
|
|
21
7
|
|
|
22
8
|
function getPageCode(callback) {
|
|
@@ -90,7 +76,7 @@ function handleOrderLog(pati) {
|
|
|
90
76
|
async function pddIntfHandle() {
|
|
91
77
|
getPageCode(async (pageCode) => {
|
|
92
78
|
if (!pageCode) return
|
|
93
|
-
|
|
79
|
+
PDD_OPEN_init({
|
|
94
80
|
code: pageCode
|
|
95
81
|
// 对于获取 code 接口或未登录态,可不传 code:PDD_OPEN_init({}, function () { ... })
|
|
96
82
|
}, function () {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { encode } from "js-base64";
|
|
2
2
|
import settingConfig from "@/settings";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
function getUrlParams(url) {
|
|
6
|
-
let result = {};
|
|
3
|
+
import QRcode from "qrcode";
|
|
4
|
+
|
|
5
|
+
function getUrlParams(url) {
|
|
6
|
+
let result = {};
|
|
7
7
|
if (url) {
|
|
8
8
|
let urlStr = url.split("?")[1];
|
|
9
9
|
const urlSearchParams = new URLSearchParams(urlStr);
|
|
@@ -89,14 +89,12 @@ export default {
|
|
|
89
89
|
immediate: true,
|
|
90
90
|
},
|
|
91
91
|
},
|
|
92
|
-
beforeDestroy() {
|
|
93
|
-
this.clearQrLoginTimer();
|
|
94
|
-
this.clearSmsTimer();
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
created() {
|
|
99
|
-
this.init();
|
|
92
|
+
beforeDestroy() {
|
|
93
|
+
this.clearQrLoginTimer();
|
|
94
|
+
this.clearSmsTimer();
|
|
95
|
+
},
|
|
96
|
+
created() {
|
|
97
|
+
this.init();
|
|
100
98
|
},
|
|
101
99
|
mounted() {
|
|
102
100
|
// if (this.loginForm.username === '') {
|
|
@@ -242,25 +240,23 @@ export default {
|
|
|
242
240
|
}
|
|
243
241
|
}
|
|
244
242
|
|
|
245
|
-
// 登录接口、部署前缀、用户信息和菜单请求期间并行下载业务模块,
|
|
246
|
-
// 路由守卫会复用同一个 Promise,不增加登录结果等待链路。
|
|
247
|
-
preloadBusinessFeatures();
|
|
248
|
-
|
|
249
243
|
this.$store
|
|
250
|
-
.dispatch("user/login2", reqData)
|
|
251
|
-
.then((res) => {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
this.
|
|
262
|
-
|
|
263
|
-
|
|
244
|
+
.dispatch("user/login2", reqData)
|
|
245
|
+
.then((res) => {
|
|
246
|
+
setTimeout(function () {
|
|
247
|
+
loadingObj.close();
|
|
248
|
+
}, 200);
|
|
249
|
+
if (res.type == "success") {
|
|
250
|
+
localStorage.removeItem("currentMenuId");
|
|
251
|
+
this.rememberPassword();
|
|
252
|
+
/*this.$router.push({
|
|
253
|
+
path: '/'
|
|
254
|
+
});*/
|
|
255
|
+
this.loading = false;
|
|
256
|
+
window.removeEventListener("keydown", this.keyDown, false);
|
|
257
|
+
this.handleRedirectUrl();
|
|
258
|
+
} else {
|
|
259
|
+
setTimeout(function () {
|
|
264
260
|
loadingObj.close();
|
|
265
261
|
}, 200);
|
|
266
262
|
}
|
|
@@ -453,41 +449,33 @@ export default {
|
|
|
453
449
|
clearInterval(this.smsTimer);
|
|
454
450
|
this.smsTimer = null;
|
|
455
451
|
}
|
|
456
|
-
},
|
|
457
|
-
mobileLogin() {},
|
|
452
|
+
},
|
|
453
|
+
mobileLogin() {},
|
|
458
454
|
handleRedirectUrl(redirect) {
|
|
459
|
-
// SSO、扫码等非账号密码入口也在跳转前启动预加载。
|
|
460
|
-
preloadBusinessFeatures();
|
|
461
455
|
redirect = redirect || this.$route.query.redirect;
|
|
462
|
-
let path = null;
|
|
463
|
-
if (redirect && redirect.startsWith("/outLinkView")) {
|
|
456
|
+
let path = null;
|
|
457
|
+
if (redirect && redirect.startsWith("/outLinkView")) {
|
|
464
458
|
path = this.addParamToUrl(redirect, "hasToken", "true");
|
|
465
459
|
} else {
|
|
466
460
|
path = "/";
|
|
467
461
|
}
|
|
468
462
|
this.getWebPrefix((webPrefix) => {
|
|
469
463
|
let prefix = webPrefix ? "/" + webPrefix : "";
|
|
470
|
-
let ssotoken = this.searchParam.gatewayToken;
|
|
471
|
-
let xtoken = this.searchParam.xtoken;
|
|
472
|
-
if (prefix && prefix !== window.WEB_PREFIX) {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}, () => {
|
|
486
|
-
// getWebPrefix 请求失败:恢复登录页可操作,避免 loading 永久卡死
|
|
487
|
-
this.closeRedirectLoading(true);
|
|
488
|
-
});
|
|
489
|
-
/*if (redirect && redirect.startsWith("/outLinkView")) {
|
|
490
|
-
let path = this.addParamToUrl(redirect, "hasToken", "true");
|
|
464
|
+
let ssotoken = this.searchParam.gatewayToken;
|
|
465
|
+
let xtoken = this.searchParam.xtoken;
|
|
466
|
+
if (prefix && prefix !== window.WEB_PREFIX) {
|
|
467
|
+
location.href = prefix + "/index.html" + path;
|
|
468
|
+
} else if (!!ssotoken || !!xtoken) {
|
|
469
|
+
prefix = prefix || window.WEB_PREFIX;
|
|
470
|
+
location.href = prefix + "/index.html" + path;
|
|
471
|
+
} else {
|
|
472
|
+
this.$router.push({
|
|
473
|
+
path: path,
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
/*if (redirect && redirect.startsWith("/outLinkView")) {
|
|
478
|
+
let path = this.addParamToUrl(redirect, "hasToken", "true");
|
|
491
479
|
this.$router.push({
|
|
492
480
|
path: path
|
|
493
481
|
});
|
|
@@ -504,104 +492,23 @@ export default {
|
|
|
504
492
|
} else {
|
|
505
493
|
url +=
|
|
506
494
|
(url.indexOf("?") === -1 ? "?" : "&") + paramKey + "=" + paramValue;
|
|
507
|
-
}
|
|
508
|
-
return url;
|
|
509
|
-
},
|
|
510
|
-
getWebPrefix(callback
|
|
511
|
-
this.$http({
|
|
512
|
-
url: USER_PREFIX + "/auth/getWebPrefix",
|
|
513
|
-
method: `post`,
|
|
495
|
+
}
|
|
496
|
+
return url;
|
|
497
|
+
},
|
|
498
|
+
getWebPrefix(callback) {
|
|
499
|
+
this.$http({
|
|
500
|
+
url: USER_PREFIX + "/auth/getWebPrefix",
|
|
501
|
+
method: `post`,
|
|
514
502
|
data: {},
|
|
515
503
|
isLoading: true,
|
|
516
504
|
success: (res) => {
|
|
517
|
-
let webPrefix = res.objx;
|
|
518
|
-
callback && callback(webPrefix);
|
|
519
|
-
},
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
errorCallback && errorCallback();
|
|
525
|
-
},
|
|
526
|
-
});
|
|
527
|
-
},
|
|
528
|
-
/**
|
|
529
|
-
* 打开登录跳转期的全屏遮罩。
|
|
530
|
-
* 不能用 fullscreen:true —— element 的全屏 loading 是全局单例(fullscreenLoading),
|
|
531
|
-
* request.js 里 isLoading 的请求(getWebPrefix 就是)用的正是这个单例,请求结束会把
|
|
532
|
-
* 它一起 close 掉。这里传 target:body + fullscreen:false 拿独立实例,遮罩挂在 body 上
|
|
533
|
-
* 不随登录组件销毁而消失,全屏样式手动补。
|
|
534
|
-
*/
|
|
535
|
-
openRedirectLoading() {
|
|
536
|
-
this.closeRedirectLoading();
|
|
537
|
-
let loading = this.$baseLoading({
|
|
538
|
-
target: document.body,
|
|
539
|
-
fullscreen: false,
|
|
540
|
-
lock: true,
|
|
541
|
-
});
|
|
542
|
-
let el = loading && loading.$el;
|
|
543
|
-
if (el) {
|
|
544
|
-
el.style.position = "fixed";
|
|
545
|
-
el.style.top = "0";
|
|
546
|
-
el.style.left = "0";
|
|
547
|
-
el.style.width = "100%";
|
|
548
|
-
el.style.height = "100%";
|
|
549
|
-
el.style.zIndex = 9999;
|
|
550
|
-
}
|
|
551
|
-
this.redirectLoadingObj = loading;
|
|
552
|
-
// 收口挂在 afterEach 上:路由守卫里的重定向会让原始 push 走 onAbort,但新导航
|
|
553
|
-
// 其实还在继续(实测 onAbort 在 +211ms 触发,首页 +577ms 才绘制完成),所以不能
|
|
554
|
-
// 用 push 的回调收口。afterEach 只在导航真正确认后触发一次,且带最终目标路由
|
|
555
|
-
this.redirectAfterEachOff = this.$router.afterEach((to) => {
|
|
556
|
-
if (String((to && to.path) || "").indexOf("/login") >= 0) {
|
|
557
|
-
// 兜了一圈又回到登录页(如守卫拉用户信息失败),恢复登录页可操作
|
|
558
|
-
this.closeRedirectLoading(true);
|
|
559
|
-
} else {
|
|
560
|
-
this.closeRedirectLoadingAfterPaint();
|
|
561
|
-
}
|
|
562
|
-
});
|
|
563
|
-
// 兜底:跳转链路既不 complete 也不 abort 时不至于永久锁死
|
|
564
|
-
this.redirectLoadingTimer = setTimeout(() => {
|
|
565
|
-
this.closeRedirectLoading(true);
|
|
566
|
-
}, 20000);
|
|
567
|
-
},
|
|
568
|
-
/**
|
|
569
|
-
* 等目标页真正绘制上屏后再撤遮罩:$nextTick 等 Vue 完成 patch,
|
|
570
|
-
* 双 rAF 等浏览器完成这一帧的绘制
|
|
571
|
-
*/
|
|
572
|
-
closeRedirectLoadingAfterPaint() {
|
|
573
|
-
this.$nextTick(() => {
|
|
574
|
-
requestAnimationFrame(() => {
|
|
575
|
-
requestAnimationFrame(() => {
|
|
576
|
-
this.closeRedirectLoading();
|
|
577
|
-
});
|
|
578
|
-
});
|
|
579
|
-
});
|
|
580
|
-
},
|
|
581
|
-
/**
|
|
582
|
-
* 登录跳转期 loading 统一收口:上屏完成、跳转中止、getWebPrefix 失败、超时兜底时调用。
|
|
583
|
-
* reenable=true 时恢复登录页可操作(跳转失败仍停留在登录页的场景)
|
|
584
|
-
*/
|
|
585
|
-
closeRedirectLoading(reenable) {
|
|
586
|
-
if (this.redirectAfterEachOff) {
|
|
587
|
-
this.redirectAfterEachOff();
|
|
588
|
-
this.redirectAfterEachOff = null;
|
|
589
|
-
}
|
|
590
|
-
if (this.redirectLoadingTimer) {
|
|
591
|
-
clearTimeout(this.redirectLoadingTimer);
|
|
592
|
-
this.redirectLoadingTimer = null;
|
|
593
|
-
}
|
|
594
|
-
if (this.redirectLoadingObj) {
|
|
595
|
-
this.redirectLoadingObj.close();
|
|
596
|
-
this.redirectLoadingObj = null;
|
|
597
|
-
}
|
|
598
|
-
if (reenable) {
|
|
599
|
-
this.loading = false;
|
|
600
|
-
window.addEventListener("keydown", this.keyDown, false);
|
|
601
|
-
}
|
|
602
|
-
},
|
|
603
|
-
handleGatewayTokenLogin() {
|
|
604
|
-
let ssotoken = this.searchParam.gatewayToken;
|
|
505
|
+
let webPrefix = res.objx;
|
|
506
|
+
callback && callback(webPrefix);
|
|
507
|
+
},
|
|
508
|
+
});
|
|
509
|
+
},
|
|
510
|
+
handleGatewayTokenLogin() {
|
|
511
|
+
let ssotoken = this.searchParam.gatewayToken;
|
|
605
512
|
let companycode = this.searchParam.entCode;
|
|
606
513
|
this.$store
|
|
607
514
|
.dispatch("user/login2", { ssotoken, companycode })
|
|
@@ -643,17 +550,18 @@ export default {
|
|
|
643
550
|
this.qrExpired = false;
|
|
644
551
|
this.qrBase64 = url;
|
|
645
552
|
this.createQrLoginTimer();
|
|
646
|
-
});
|
|
647
|
-
},
|
|
648
|
-
// 生成二维码
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
553
|
+
});
|
|
554
|
+
},
|
|
555
|
+
// 生成二维码
|
|
556
|
+
createQR(content, options) {
|
|
557
|
+
return new Promise((resolve, reject) => {
|
|
558
|
+
QRcode.toDataURL(content, options).then((url) => {
|
|
559
|
+
resolve(url);
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
},
|
|
563
|
+
changeTab() {
|
|
564
|
+
// this.initQR();
|
|
657
565
|
// return
|
|
658
566
|
if (this.activeName == "third") {
|
|
659
567
|
this.initQR();
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
let installPromise = null;
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* 登录页只安装认证所需的最小能力。表格、Excel、上传和业务弹框等全局能力
|
|
5
|
-
* 在第一次进入业务路由前按需安装,避免进入 /login 时下载整套后台模块。
|
|
6
|
-
*/
|
|
7
|
-
export function ensureBusinessFeatures() {
|
|
8
|
-
if (!installPromise) {
|
|
9
|
-
installPromise = import(
|
|
10
|
-
/* webpackChunkName: "business-core" */ "./businessFeatures"
|
|
11
|
-
).catch((error) => {
|
|
12
|
-
// 网络抖动或发布切换导致 chunk 失败时,允许下一次导航重新尝试
|
|
13
|
-
installPromise = null;
|
|
14
|
-
throw error;
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return installPromise;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 提前触发业务模块下载和安装,但不阻塞当前交互。
|
|
22
|
-
* 登录提交后会与认证、用户信息和菜单请求并行;真正进入业务路由时
|
|
23
|
-
* ensureBusinessFeatures 会复用同一个 Promise,失败时仍由路由守卫统一提示。
|
|
24
|
-
*/
|
|
25
|
-
export function preloadBusinessFeatures() {
|
|
26
|
-
const promise = ensureBusinessFeatures();
|
|
27
|
-
promise.catch((error) => {
|
|
28
|
-
console.warn("[bootstrap] 业务模块预加载失败,将在导航时重试", error);
|
|
29
|
-
});
|
|
30
|
-
return promise;
|
|
31
|
-
}
|