cloud-web-corejs 1.0.54-dev.770 → 1.0.54-dev.772
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 +365 -204
- package/src/layout/components/TagsView/index.vue +1 -1
- package/src/microRouter/index.js +31 -5
- package/src/permission.js +18 -74
- package/src/public-path.js +30 -0
- 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
|
@@ -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
|
-
}
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import Vue from "vue";
|
|
2
|
-
import Cookies from "js-cookie";
|
|
3
|
-
import Element from "element-ui";
|
|
4
|
-
|
|
5
|
-
import BaseKeepAlive from "@base/utils/keepAlive.js";
|
|
6
|
-
import VXETable from "vxe-table";
|
|
7
|
-
import "vxe-table/lib/style.css";
|
|
8
|
-
import "@base/components/table/plugins/extend-cell-area/vxe-table-extend-cell-area.es6.min.js";
|
|
9
|
-
import "@base/components/table/plugins/extend-cell-area/vxe-table-extend-cell-area.min.css";
|
|
10
|
-
import "@base/components/table/index.js";
|
|
11
|
-
import Vab from "@base/utils/vab";
|
|
12
|
-
import drag from "@base/directive/el-drag-dialog/index.js";
|
|
13
|
-
import elDialogCenter from "@base/directive/el-dialog-center/index.js";
|
|
14
|
-
import ErroreBox from "@base/components/errorMsg/index.js";
|
|
15
|
-
import ExcelExport from "@base/components/excelExport/index.js";
|
|
16
|
-
import ExcelImport from "@base/components/excelImport/index.js";
|
|
17
|
-
import ConfirmDialog from "@base/components/confirmDialog/index.js";
|
|
18
|
-
import baseAlert from "@base/components/baseAlert/index.js";
|
|
19
|
-
import FormDialog from "@base/components/formDialog/index.js";
|
|
20
|
-
import permission from "@base/directive/permission";
|
|
21
|
-
import VabUpload from "@base/components/VabUpload/index.js";
|
|
22
|
-
import baseAttachment from "@base/components/baseAttachment/install";
|
|
23
|
-
import vxeFilter from "@base/components/table/vxeFilter/index.js";
|
|
24
|
-
import baseTableExport from "@base/components/excelExport/button.vue";
|
|
25
|
-
import LimitNumber from "@base/directive/LimitNumber/index.js";
|
|
26
|
-
import baseInputNumber from "@base/components/baseInputNumber/index.vue";
|
|
27
|
-
import elReadonly from "@base/directive/el-readonly/index.js";
|
|
28
|
-
import oplogTable from "@base/components/oplogTable/index.vue";
|
|
29
|
-
import baseInputBatch from "@base/components/baseInputBatch/index.vue";
|
|
30
|
-
import baseArea from "@base/components/baseArea/index.vue";
|
|
31
|
-
import baseTabs from "@base/components/baseTabs/index.vue";
|
|
32
|
-
import baseTabPane from "@base/components/baseTabs/baseTabPane.vue";
|
|
33
|
-
import vbTabs from "@base/components/vb-tabs/index.vue";
|
|
34
|
-
import vbTabPane from "@base/components/vb-tabs/tab-pane.vue";
|
|
35
|
-
import xTabs from "@base/components/vb-tabs/x-tabs.vue";
|
|
36
|
-
import baseTextarea from "@base/components/base-textarea/index.vue";
|
|
37
|
-
import jsonImport from "@base/components/jsonImport/index.js";
|
|
38
|
-
import langImport from "@base/components/langImport/index.js";
|
|
39
|
-
import * as filters from "@base/filters";
|
|
40
|
-
import {
|
|
41
|
-
getPublicAssetUrl,
|
|
42
|
-
loadStyle,
|
|
43
|
-
} from "@base/utils/externalAssets";
|
|
44
|
-
|
|
45
|
-
Vue.component("BaseKeepAlive", BaseKeepAlive);
|
|
46
|
-
Vue.use(Element, { size: Cookies.get("size") || "medium" });
|
|
47
|
-
Vue.use(Vab);
|
|
48
|
-
Vue.use(VXETable);
|
|
49
|
-
Vue.use(drag.install);
|
|
50
|
-
Vue.use(elDialogCenter.install);
|
|
51
|
-
Vue.use(ErroreBox);
|
|
52
|
-
Vue.use(ExcelExport);
|
|
53
|
-
Vue.use(ExcelImport);
|
|
54
|
-
Vue.use(ConfirmDialog);
|
|
55
|
-
Vue.use(baseAlert);
|
|
56
|
-
Vue.use(FormDialog);
|
|
57
|
-
Vue.use(permission);
|
|
58
|
-
Vue.use(VabUpload);
|
|
59
|
-
Vue.use(baseAttachment);
|
|
60
|
-
Vue.use(vxeFilter);
|
|
61
|
-
Vue.use(LimitNumber);
|
|
62
|
-
Vue.use(elReadonly);
|
|
63
|
-
Vue.use(jsonImport);
|
|
64
|
-
Vue.use(langImport);
|
|
65
|
-
|
|
66
|
-
Vue.component("baseUpload", () =>
|
|
67
|
-
import("@base/components/VabUpload/view.vue")
|
|
68
|
-
);
|
|
69
|
-
Vue.component("attachmentShowList", () =>
|
|
70
|
-
import("@base/components/baseAttachment/showList")
|
|
71
|
-
);
|
|
72
|
-
Vue.component(baseTableExport.name, baseTableExport);
|
|
73
|
-
Vue.component(baseInputNumber.name, baseInputNumber);
|
|
74
|
-
Vue.component(oplogTable.name, oplogTable);
|
|
75
|
-
Vue.component(baseInputBatch.name, baseInputBatch);
|
|
76
|
-
Vue.component(baseArea.name, baseArea);
|
|
77
|
-
Vue.component("baseInputExport", () =>
|
|
78
|
-
import("@base/components/baseInputExport/index.vue")
|
|
79
|
-
);
|
|
80
|
-
Vue.component("advancedSearchDialog", () =>
|
|
81
|
-
import("@base/components/advancedSearchDialog/index.vue")
|
|
82
|
-
);
|
|
83
|
-
Vue.component(baseTabs.name, baseTabs);
|
|
84
|
-
Vue.component(baseTabPane.name, baseTabPane);
|
|
85
|
-
Vue.component(vbTabs.name, vbTabs);
|
|
86
|
-
Vue.component(vbTabPane.name, vbTabPane);
|
|
87
|
-
Vue.component(xTabs.name, xTabs);
|
|
88
|
-
Vue.component("status-tag", () =>
|
|
89
|
-
import("@base/components/statusTag/index.vue")
|
|
90
|
-
);
|
|
91
|
-
Vue.component("CodeEditor", () =>
|
|
92
|
-
import("@base/components/code-editor/index.vue")
|
|
93
|
-
);
|
|
94
|
-
Vue.component("scriptDescriptionButton", () =>
|
|
95
|
-
import("@base/components/scriptDescription/button")
|
|
96
|
-
);
|
|
97
|
-
Vue.component("scriptTestButton", () =>
|
|
98
|
-
import("@base/components/scriptTest/button")
|
|
99
|
-
);
|
|
100
|
-
Vue.component(baseTextarea.name, baseTextarea);
|
|
101
|
-
|
|
102
|
-
Object.keys(filters).forEach((key) => {
|
|
103
|
-
Vue.filter(key, filters[key]);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
loadStyle(getPublicAssetUrl("css/print-lock.css"), { media: "print" }).catch(
|
|
107
|
-
(error) => console.warn("[bootstrap] 打印样式加载失败", error)
|
|
108
|
-
);
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
const assetPromises = Object.create(null);
|
|
2
|
-
|
|
3
|
-
export function getPublicAssetUrl(path) {
|
|
4
|
-
const baseUrl = (process.env.BASE_URL || "/").replace(/\/?$/, "/");
|
|
5
|
-
return baseUrl + String(path || "").replace(/^\//, "");
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function findAsset(tagName, attribute, url) {
|
|
9
|
-
return Array.from(document.getElementsByTagName(tagName)).find(
|
|
10
|
-
(element) => element.getAttribute(attribute) === url
|
|
11
|
-
);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function loadStyle(href, attributes = {}) {
|
|
15
|
-
const key = "style:" + href;
|
|
16
|
-
if (assetPromises[key]) return assetPromises[key];
|
|
17
|
-
const existing = findAsset("link", "href", href);
|
|
18
|
-
if (existing) return Promise.resolve(existing);
|
|
19
|
-
|
|
20
|
-
assetPromises[key] = new Promise((resolve, reject) => {
|
|
21
|
-
const link = document.createElement("link");
|
|
22
|
-
link.rel = "stylesheet";
|
|
23
|
-
link.href = href;
|
|
24
|
-
Object.keys(attributes).forEach((name) => {
|
|
25
|
-
link.setAttribute(name, attributes[name]);
|
|
26
|
-
});
|
|
27
|
-
link.onload = () => resolve(link);
|
|
28
|
-
link.onerror = () => {
|
|
29
|
-
delete assetPromises[key];
|
|
30
|
-
link.remove();
|
|
31
|
-
reject(new Error("样式加载失败:" + href));
|
|
32
|
-
};
|
|
33
|
-
document.head.appendChild(link);
|
|
34
|
-
});
|
|
35
|
-
return assetPromises[key];
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export function loadStyles(hrefs) {
|
|
39
|
-
return Promise.all(hrefs.map((href) => loadStyle(href)));
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function loadScript(src) {
|
|
43
|
-
const key = "script:" + src;
|
|
44
|
-
if (assetPromises[key]) return assetPromises[key];
|
|
45
|
-
const existing = findAsset("script", "src", src);
|
|
46
|
-
if (existing) return Promise.resolve(existing);
|
|
47
|
-
|
|
48
|
-
assetPromises[key] = new Promise((resolve, reject) => {
|
|
49
|
-
const script = document.createElement("script");
|
|
50
|
-
script.src = src;
|
|
51
|
-
script.async = true;
|
|
52
|
-
script.onload = () => resolve(script);
|
|
53
|
-
script.onerror = () => {
|
|
54
|
-
delete assetPromises[key];
|
|
55
|
-
script.remove();
|
|
56
|
-
reject(new Error("脚本加载失败:" + src));
|
|
57
|
-
};
|
|
58
|
-
document.head.appendChild(script);
|
|
59
|
-
});
|
|
60
|
-
return assetPromises[key];
|
|
61
|
-
}
|
|
62
|
-
|
package/src/utils/loginVab.js
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
// API 模块沿用 USER_PREFIX 等全局常量;完整 Vab 延迟加载后,登录阶段需先恢复
|
|
2
|
-
// 这项原本由 vab.js 模块初始化完成的副作用。
|
|
3
|
-
import "@base/utils/prefixGlobals";
|
|
4
|
-
import Loading from "element-ui/lib/loading";
|
|
5
|
-
import MessageBox from "element-ui/lib/message-box";
|
|
6
|
-
import request from "@base/utils/request";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* 登录阶段需要的最小 Vab 能力。完整 Vab 会连带 lodash、moment、XEUtils、
|
|
10
|
-
* 图片预览等后台依赖,改为进入业务路由后再覆盖安装。
|
|
11
|
-
*/
|
|
12
|
-
export default function installLoginVab(Vue) {
|
|
13
|
-
Vue.prototype.$baseEventBus = new Vue();
|
|
14
|
-
const $http = async function (option = {}) {
|
|
15
|
-
if (!option.loadingTarget && this.$el) {
|
|
16
|
-
option.loadingTarget = this.$el;
|
|
17
|
-
}
|
|
18
|
-
if (!option.vueTarget) {
|
|
19
|
-
option.vueTarget = this;
|
|
20
|
-
}
|
|
21
|
-
return option.sync === false ? await request(option) : request(option);
|
|
22
|
-
};
|
|
23
|
-
Object.assign($http, request);
|
|
24
|
-
$http.prototype = request.prototype;
|
|
25
|
-
Vue.prototype.$http = $http;
|
|
26
|
-
|
|
27
|
-
Vue.prototype.$baseLoading = function (option = {}) {
|
|
28
|
-
const opts = {
|
|
29
|
-
lock: true,
|
|
30
|
-
background: "hsla(0,0%,100%,.8)",
|
|
31
|
-
target: this.$el,
|
|
32
|
-
...option,
|
|
33
|
-
};
|
|
34
|
-
if (option.index) {
|
|
35
|
-
opts.spinner = "vab-loading-type" + option.index;
|
|
36
|
-
}
|
|
37
|
-
return Loading.service(opts);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
Vue.prototype.$baseAlert = function (content, title, callback) {
|
|
41
|
-
return MessageBox.alert(content, title || "提示", {
|
|
42
|
-
confirmButtonText: "确定",
|
|
43
|
-
dangerouslyUseHTMLString: true,
|
|
44
|
-
target: this.$el,
|
|
45
|
-
confirmButtonClass: "icondui",
|
|
46
|
-
customClass: "dialog-style",
|
|
47
|
-
callback,
|
|
48
|
-
});
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
Vue.prototype.$t1 = function (path, values) {
|
|
52
|
-
const root = this.$root || window.$vueRoot;
|
|
53
|
-
if (!root || !root._i18n) return path;
|
|
54
|
-
const i18n = root.$i18n;
|
|
55
|
-
if (i18n.locale === "zh" || !i18n.te(path)) {
|
|
56
|
-
return i18n._t(path, i18n.locale, { zh: { [path]: path } }, null, values);
|
|
57
|
-
}
|
|
58
|
-
return i18n.t(path, values) || path;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
Vue.prototype.$t2 = function (defaultValue, path, values) {
|
|
62
|
-
const root = this.$root || window.$vueRoot;
|
|
63
|
-
if (!root || !root._i18n) return defaultValue;
|
|
64
|
-
const i18n = root.$i18n;
|
|
65
|
-
const key = path || defaultValue;
|
|
66
|
-
return i18n.te(key) ? i18n.t(key, values) : defaultValue;
|
|
67
|
-
};
|
|
68
|
-
}
|