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.
@@ -5,6 +5,7 @@
5
5
  * 由 permission store 在登录后菜单生成流程中调用(settings.microMainEnabled 门控)。
6
6
  */
7
7
  import { loadMicroApp } from "qiankun";
8
+ import { Loading } from "element-ui";
8
9
  import { getLogicParamValue } from "@base/api/user";
9
10
  import {
10
11
  getAccessPath,
@@ -248,6 +249,19 @@ function activateMicroApp(key) {
248
249
  + "/ 即回到正式环境)"
249
250
  );
250
251
  }
252
+ // 子应用是另一套系统,首次装载要下载其全量资源、耗时明显,期间容器空白。
253
+ // loading 只盖内容区,不遮页签,也不挂子应用容器 el(el 会被 qiankun 写 innerHTML
254
+ // 清掉,且空 #Appmicro 高度为 0):挂到有尺寸、qiankun 不碰的 .app-main,
255
+ // 再把遮罩顶边下移到 #Appmicro 的位置(offsetTop = 固定表头里页签的占位高度,
256
+ // 动态读取不写死),从而避开顶部的页签栏。挂载成功 / 失败都关闭。
257
+ const appMain = wrapper.closest(".app-main");
258
+ const loadingInstance = Loading.service({
259
+ target: appMain || wrapper,
260
+ text: "加载中…",
261
+ });
262
+ if (appMain && loadingInstance.$el && loadingInstance.$el.style) {
263
+ loadingInstance.$el.style.top = wrapper.offsetTop + "px";
264
+ }
251
265
  let instance;
252
266
  try {
253
267
  instance = loadMicroApp({
@@ -257,6 +271,7 @@ function activateMicroApp(key) {
257
271
  props: config.props,
258
272
  });
259
273
  } catch (error) {
274
+ loadingInstance.close();
260
275
  if (el.parentNode) {
261
276
  el.parentNode.removeChild(el);
262
277
  }
@@ -268,11 +283,17 @@ function activateMicroApp(key) {
268
283
  if (
269
284
  instance
270
285
  && instance.mountPromise
271
- && typeof instance.mountPromise.catch === "function"
286
+ && typeof instance.mountPromise.then === "function"
272
287
  ) {
273
- instance.mountPromise.catch((error) => {
274
- cleanupFailedMicroApp(key, createdAlive, error);
275
- });
288
+ instance.mountPromise
289
+ .then(() => loadingInstance.close())
290
+ .catch((error) => {
291
+ loadingInstance.close();
292
+ cleanupFailedMicroApp(key, createdAlive, error);
293
+ });
294
+ } else {
295
+ // 理论不会走到(loadMicroApp 恒返回带 mountPromise 的实例),兜底避免遮罩悬挂
296
+ loadingInstance.close();
276
297
  }
277
298
  return;
278
299
  }
@@ -398,7 +419,12 @@ function createDefaultMainAdapter() {
398
419
  navigate(path) {
399
420
  const vueRoot = window.$vueRoot;
400
421
  if (vueRoot && vueRoot.$router) {
401
- vueRoot.$router.push(path).catch(() => {});
422
+ // vue-router 3.0.2 的 push 返回 undefined(3.1.0 才返回 Promise),
423
+ // 直接 .catch 会抛 "reading 'catch'",仅在返回 Promise 时才吞异常
424
+ const nav = vueRoot.$router.push(path);
425
+ if (nav && typeof nav.catch === "function") {
426
+ nav.catch(() => {});
427
+ }
402
428
  }
403
429
  },
404
430
  openTab(path) {
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 Message from "element-ui/lib/message";
5
- import NProgress from "nprogress"; // progress bar
6
- import "nprogress/nprogress.css"; // progress bar style
7
- import {
8
- getToken
9
- } from "./utils/auth"; // get token from cookie
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
- ensureBusinessFeatures,
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
- if (!needsBusinessFeatures(to)) {
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
 
@@ -6,3 +6,33 @@
6
6
  if (window.__POWERED_BY_QIANKUN__) {
7
7
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
8
8
  }
9
+
10
+ /**
11
+ * API base 运行时解析:解决"被外部域名的主应用嵌入时,相对 baseURL 会误打主应用域名"。
12
+ * 消费应用的 vue.config.js 经 DefinePlugin 把每个 process.env.VUE_APP_BASE_API 编译成
13
+ * window.__resolveApiBase__("<原值>") 的调用,于是 request.js 及一切读该值的模块运行时按下述规则求值:
14
+ * 独立运行 → 原值(相对地址命中自身域名,行为不变)
15
+ * 子应用挂载:
16
+ * 原值是域名(绝对) → 原值(含协议相对 //host)
17
+ * 原值不是域名 → 子应用自身 origin + 原值("" → origin;"/gapi" → origin+"/gapi")
18
+ * 前提:API 与子应用静态资源同源部署(origin 即后端所在域名,路径前缀由原值补齐)。
19
+ * 该 helper 只接受调用点传入的原值作参数、绝不引用 process.env.VUE_APP_BASE_API,
20
+ * 以免被 DefinePlugin 递归改写成自我调用。
21
+ */
22
+ if (!window.__resolveApiBase__) {
23
+ window.__resolveApiBase__ = function (raw) {
24
+ raw = raw || "";
25
+ if (!window.__POWERED_BY_QIANKUN__) return raw;
26
+ // http:// https:// 以及协议相对 //host 都算"是域名",原样返回
27
+ if (/^(https?:)?\/\//.test(raw)) return raw;
28
+ try {
29
+ var origin = new URL(
30
+ window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,
31
+ window.location.href
32
+ ).origin;
33
+ return origin + raw;
34
+ } catch (e) {
35
+ return raw;
36
+ }
37
+ };
38
+ }
@@ -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
- const Layout = () => import(/* webpackChunkName: "layout" */ "@/layout");
14
- const MenuFallback = () =>
15
- import(
16
- /* webpackChunkName: "menu-fallback" */ "@base/views/user/menuFallback/index.vue"
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 import("@base/microRouter").then(
239
- ({ getAppRegistry, registerSubApps, buildSubAppRoutes }) =>
240
- getAppRegistry().then((apps) => {
241
- // 自排除:自身也在注册表时(子应用开宿主形态互访别家应用)不装载自己,
242
- // 否则会自嵌套且自身菜单被误判为"派发给子应用"而跳过本地路由
243
- let ownAppCode = settings.appCode || "";
244
- hostRegistryApps = (apps || []).filter(
245
- (app) => app.appCode !== ownAppCode
246
- );
247
- commit(
248
- "SET_REGISTRY_APP_CODES",
249
- hostRegistryApps.map((app) => app.appCode)
250
- );
251
- let subAppMenus = dispatchMenus(rows, hostRegistryApps);
252
- hostMicroRoutes = buildSubAppRoutes(hostRegistryApps, subAppMenus);
253
- if (hostRegistryApps.length) {
254
- registerSubApps(hostRegistryApps, {
255
- subAppMenus,
256
- userInfo: buildUserInfoSnapshot(rootState.user),
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,3 +1,5 @@
1
+ import variables from '@/styles/element-variables.scss'
2
+
1
3
  const state = {
2
4
  tagsView: true,
3
5
  }
@@ -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 = JSON.parse(JSON.stringify(newView0));
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 { getDispermissions } from "../../api/menu";
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
- import("@base/microRouter")
333
- .then(({ unmountAllMicroApps }) => unmountAllMicroApps())
334
- .catch((error) => {
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
- dispatch("tagsView/delAllViews", null, {
343
- root: true,
344
- });
345
- resolve();
346
- });
337
+ dispatch("tagsView/delAllViews", null, {
338
+ root: true,
339
+ });
340
+ resolve();
347
341
  });
348
342
  },
349
343
 
@@ -1,22 +1,8 @@
1
1
  import settingConfig from "@/settings";
2
- import { loadScript } from "@base/utils/externalAssets";
3
2
 
4
- const PDD_LOG_SDK_URL
5
- = "https://pfile.pddpic.com/galerie-go/open_sdk/pc.202102201613.js";
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
- window.PDD_OPEN_init({
79
+ PDD_OPEN_init({
94
80
  code: pageCode
95
81
  // 对于获取 code 接口或未登录态,可不传 code:PDD_OPEN_init({}, function () { ... })
96
82
  }, function () {