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.
@@ -1,9 +1,9 @@
1
1
  import { encode } from "js-base64";
2
2
  import settingConfig from "@/settings";
3
- import { preloadBusinessFeatures } from "@base/bootstrap/business";
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
- // 注意:这里不能关跳转期 loading。组件销毁发生在导航确认时,而首页真正渲染上屏
96
- // 还在其后,遮罩要撑过这段时间,由 closeRedirectLoading 收口
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
- if (res.type == "success") {
253
- localStorage.removeItem("currentMenuId");
254
- this.rememberPassword();
255
- window.removeEventListener("keydown", this.keyDown, false);
256
- // 登录成功后的跳转链路(getWebPrefix → 路由守卫拉用户信息/生成动态路由 →
257
- // 首页渲染上屏)耗时较长,换成挂在 body 上的全屏遮罩顶住这段时间,
258
- // 防止登录页被再次操作;由 closeRedirectLoading 统一收口
259
- loadingObj.close();
260
- this.openRedirectLoading();
261
- this.handleRedirectUrl();
262
- } else {
263
- setTimeout(function () {
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
- // 整页跳转,loading 随页面卸载消失
474
- location.href = prefix + "/index.html" + path;
475
- } else if (!!ssotoken || !!xtoken) {
476
- prefix = prefix || window.WEB_PREFIX;
477
- location.href = prefix + "/index.html" + path;
478
- } else {
479
- // 遮罩不在 push 的回调里收口:守卫内的重定向会让原始导航走 onAbort,
480
- // 而真正的导航仍在继续,统一交给 openRedirectLoading 里注册的 afterEach
481
- this.$router.push({
482
- path: path,
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, errorCallback) {
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
- fail: () => {
521
- errorCallback && errorCallback();
522
- },
523
- error: () => {
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
- async createQR(content, options) {
650
- const { default: QRCode } = await import(
651
- /* webpackChunkName: "login-qrcode" */ "qrcode"
652
- );
653
- return QRCode.toDataURL(content, options);
654
- },
655
- changeTab() {
656
- // this.initQR();
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
-
@@ -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
- }
@@ -1,11 +0,0 @@
1
- import prefixConfig from "@/prefixConfig.js";
2
-
3
- export function installPrefixGlobals(target) {
4
- if (target) {
5
- Object.assign(target, prefixConfig);
6
- }
7
- }
8
-
9
- if (typeof window !== "undefined") {
10
- installPrefixGlobals(window);
11
- }