cloud-web-corejs 1.0.54-dev.746 → 1.0.54-dev.747

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cloud-web-corejs",
3
3
  "private": false,
4
- "version": "1.0.54-dev.746",
4
+ "version": "1.0.54-dev.747",
5
5
  "scripts": {
6
6
  "dev": "vue-cli-service serve",
7
7
  "lint": "eslint --ext .js,.vue src",
@@ -183,6 +183,8 @@
183
183
  "src/router",
184
184
  "src/permission.js",
185
185
  "src/index.js",
186
+ "src/public-path.js",
187
+ "src/microRouter",
186
188
  "src/App.vue"
187
189
  ],
188
190
  "publishConfig": {
package/src/index.js CHANGED
@@ -10,7 +10,7 @@ import "@/styles/index.scss"; // global css
10
10
  import App from "@base/App";
11
11
  import store from "@base/store";
12
12
  import router, { resetRouter } from "@base/router";
13
- import settings from "@base/settings";
13
+ import settings from "@/settings";
14
14
  import { setToken as setAuthToken } from "@base/utils/auth";
15
15
 
16
16
  import "@/icons"; // icon
@@ -273,7 +273,10 @@ export async function mount(props = {}) {
273
273
  flag: store.state.user.userFlag,
274
274
  });
275
275
  } else {
276
- await store.dispatch("permission/generateRoutesFromProps", props.menus || []);
276
+ await store.dispatch(
277
+ "permission/generateRoutesFromProps",
278
+ props.menus || []
279
+ );
277
280
  }
278
281
  }
279
282
  render(props);
@@ -0,0 +1,389 @@
1
+ /**
2
+ * qiankun 主应用侧:应用注册表驱动的子应用注册。
3
+ * 注册表载体为逻辑参数 micro_app_registry(JSON 数组),
4
+ * 协议见 docs/qiankun微前端改造-实现方案.md 3.2 / 3.4。
5
+ * 由 permission store 在登录后菜单生成流程中调用(settings.microMainEnabled 门控)。
6
+ */
7
+ import { loadMicroApp } from "qiankun";
8
+ import { getLogicParamValue } from "@base/api/user";
9
+ import {
10
+ getAccessPath,
11
+ validateRegistry,
12
+ resolveEntry,
13
+ } from "@base/utils/menuAdapter";
14
+ import { getToken } from "@base/utils/auth";
15
+ import router from "@base/router";
16
+ import settings from "@/settings";
17
+
18
+ export const REGISTRY_PARAM_CODE = "micro_app_registry";
19
+ export const DEBUG_STORAGE_KEY = "micro_app_debug";
20
+
21
+ const REGISTRY_TIMEOUT = 8000;
22
+ const CONTAINER_WRAPPER_ID = "Appmicro";
23
+ const DEBUG_APP_CODE_REG = /^[A-Za-z][A-Za-z0-9_-]*$/;
24
+
25
+ // 保活管理:appCode → { instance, el };离开子应用路由只隐藏容器不卸载,
26
+ // 切回直接显示并经 update 生命周期同步路由,页面状态(页签/表格/表单)得以保留
27
+ let microAppConfigs = {};
28
+ let aliveApps = {};
29
+ let routeHookInstalled = false;
30
+
31
+ /**
32
+ * 读应用注册表(第一阶段载体:逻辑参数)。
33
+ * 非法条目由 validateRegistry 跳过并在控制台显式报错;
34
+ * 参数缺失 / 请求失败 / 超时一律回落空数组,不阻塞登录流程。
35
+ */
36
+ export function getAppRegistry() {
37
+ const fetchPromise = new Promise((resolve) => {
38
+ getLogicParamValue({
39
+ data: { paramCode: REGISTRY_PARAM_CODE },
40
+ failMsg: false,
41
+ errorMsg: false,
42
+ modal: false,
43
+ success: (res) => {
44
+ const raw = res && res.objx;
45
+ if (!raw) {
46
+ resolve([]);
47
+ return;
48
+ }
49
+ const { apps, errors } = validateRegistry(raw);
50
+ if (errors.length) {
51
+ console.error(
52
+ "[microRouter] 应用注册表存在非法条目(已跳过):",
53
+ errors
54
+ );
55
+ }
56
+ resolve(apps);
57
+ },
58
+ }).catch(() => resolve([]));
59
+ });
60
+ const timeoutPromise = new Promise((resolve) => {
61
+ setTimeout(() => {
62
+ resolve([]);
63
+ }, REGISTRY_TIMEOUT);
64
+ });
65
+ return Promise.race([fetchPromise, timeoutPromise]).then((apps) =>
66
+ applyDebugOverrides(apps)
67
+ );
68
+ }
69
+
70
+ /**
71
+ * 本机调试覆盖:localStorage.micro_app_debug 仅在当前浏览器生效,
72
+ * 用于"发布环境主应用 + 本机子应用"的联调,不影响其他用户。四档写法:
73
+ * "1" → settings.microDebugAppCode + microDebugEntry
74
+ * "appB" → appB + 默认调试入口
75
+ * "appB=http://localhost:9530/" → 指定入口;多个用逗号分隔,可混写
76
+ * '[{"appCode":"..","entry":".."}]' → 完整条目数组
77
+ * 与注册表按 appCode 合并:已存在的条目覆盖 entry 并强制 enabled,不存在的追加。
78
+ */
79
+ function getDebugOverrides() {
80
+ let raw = null;
81
+ try {
82
+ raw = window.localStorage.getItem(DEBUG_STORAGE_KEY);
83
+ } catch (e) {
84
+ return [];
85
+ }
86
+ if (!raw || !(raw = raw.trim())) return [];
87
+ const defaults = {
88
+ appCode: settings.microDebugAppCode || "",
89
+ entry: settings.microDebugEntry || "",
90
+ };
91
+ let items = [];
92
+ if (raw.charAt(0) === "[") {
93
+ try {
94
+ const list = JSON.parse(raw);
95
+ items = (Array.isArray(list) ? list : []).map((item) => ({
96
+ appCode: (item && item.appCode) || "",
97
+ entry: (item && item.entry) || defaults.entry,
98
+ }));
99
+ } catch (e) {
100
+ console.error(
101
+ "[microRouter] micro_app_debug JSON 解析失败,已忽略:",
102
+ e.message
103
+ );
104
+ return [];
105
+ }
106
+ } else if (raw === "1" || raw === "true") {
107
+ items = [defaults];
108
+ } else {
109
+ items = raw.split(",").map((part) => {
110
+ const idx = part.indexOf("=");
111
+ const code = (idx > -1 ? part.slice(0, idx) : part).trim();
112
+ const entry = idx > -1 ? part.slice(idx + 1).trim() : defaults.entry;
113
+ return { appCode: code, entry };
114
+ });
115
+ }
116
+ return items.filter((item) => {
117
+ if (!DEBUG_APP_CODE_REG.test(item.appCode || "") || !item.entry) {
118
+ console.error(
119
+ "[microRouter] micro_app_debug 非法条目已跳过:",
120
+ JSON.stringify(item)
121
+ );
122
+ return false;
123
+ }
124
+ return true;
125
+ });
126
+ }
127
+
128
+ function applyDebugOverrides(apps) {
129
+ const overrides = getDebugOverrides();
130
+ if (!overrides.length) return apps || [];
131
+ const result = (apps || []).slice();
132
+ overrides.forEach((override) => {
133
+ const existing = result.find((app) => app.appCode === override.appCode);
134
+ if (existing) {
135
+ existing.entry = override.entry;
136
+ existing.enabled = true;
137
+ } else {
138
+ result.push({
139
+ appCode: override.appCode,
140
+ appName: override.appCode + "(本地调试)",
141
+ entry: override.entry,
142
+ hasCorejs: true,
143
+ enabled: true,
144
+ });
145
+ }
146
+ console.warn(
147
+ "[microRouter] ⚠ 本地调试覆盖生效:" +
148
+ override.appCode +
149
+ " → " +
150
+ override.entry +
151
+ "(删除 localStorage." +
152
+ DEBUG_STORAGE_KEY +
153
+ " 后刷新恢复)"
154
+ );
155
+ });
156
+ return result;
157
+ }
158
+
159
+ /**
160
+ * activeRule 由 appCode 推导:hash 首段即归属首段,与菜单访问路径天然一致。
161
+ */
162
+ export function buildActiveRule(appCode) {
163
+ const prefix = "#/" + appCode;
164
+ return (location) => {
165
+ const hash = location.hash || "";
166
+ return (
167
+ hash === prefix ||
168
+ hash.indexOf(prefix + "/") === 0 ||
169
+ hash.indexOf(prefix + "?") === 0
170
+ );
171
+ };
172
+ }
173
+
174
+ /**
175
+ * 登记子应用(保活模式):不再走 registerMicroApps/start 的 activeRule 自动装卸,
176
+ * 改为路由钩子驱动的 loadMicroApp 手动装载——首次进入装载,离开只隐藏,切回显示并同步路由。
177
+ * options.subAppMenus 为 menuAdapter.dispatchMenus 的切分结果。
178
+ */
179
+ export function registerSubApps(apps, options = {}) {
180
+ const env = process.env.NODE_ENV || "development";
181
+ const subAppMenus = options.subAppMenus || {};
182
+ const mainAdapter = options.mainAdapter || createDefaultMainAdapter();
183
+ const userInfo = options.userInfo || null;
184
+ microAppConfigs = {};
185
+ (apps || []).forEach((app) => {
186
+ const entry = resolveEntry(app.entry, env);
187
+ if (!entry) {
188
+ console.error(
189
+ "[microRouter] 子应用缺少当前环境 entry,已跳过:" + app.appCode
190
+ );
191
+ return;
192
+ }
193
+ microAppConfigs[app.appCode] = {
194
+ name: app.appCode,
195
+ entry,
196
+ props: {
197
+ appCode: app.appCode,
198
+ menus: subAppMenus[app.appCode] || [],
199
+ token: getToken(),
200
+ lang: localStorage.getItem("i18n-lang") || "",
201
+ userInfo,
202
+ mainAdapter,
203
+ },
204
+ };
205
+ });
206
+ installRouteHook();
207
+ return Object.keys(microAppConfigs);
208
+ }
209
+
210
+ // 当前应处于激活态的子应用(等待容器期间用户可能又切走,异步续体据此丢弃过期操作)
211
+ let currentActiveAppCode = null;
212
+
213
+ function installRouteHook() {
214
+ if (routeHookInstalled) return;
215
+ routeHookInstalled = true;
216
+ router.afterEach((to) => {
217
+ const appCode =
218
+ to.meta && to.meta.isMicroApp && microAppConfigs[to.meta.appCode]
219
+ ? to.meta.appCode
220
+ : null;
221
+ currentActiveAppCode = appCode;
222
+ Object.keys(aliveApps).forEach((code) => {
223
+ if (code !== appCode) {
224
+ deactivateMicroApp(code);
225
+ }
226
+ });
227
+ if (appCode) {
228
+ activateMicroApp(appCode);
229
+ }
230
+ });
231
+ }
232
+
233
+ // 刷新直接落在子应用路由时,afterEach 早于布局渲染(AppMain 懒加载 + showAppMain 延迟),
234
+ // 容器尚未进 DOM——轮询等待,超时显式报错
235
+ const WRAPPER_WAIT_INTERVAL = 100;
236
+ const WRAPPER_WAIT_MAX_TRIES = 100;
237
+
238
+ function waitForWrapper(tryCount = 0) {
239
+ const wrapper = document.getElementById(CONTAINER_WRAPPER_ID);
240
+ if (wrapper) return Promise.resolve(wrapper);
241
+ if (tryCount >= WRAPPER_WAIT_MAX_TRIES) {
242
+ console.error(
243
+ "[microRouter] 等待子应用容器 #" + CONTAINER_WRAPPER_ID + " 超时"
244
+ );
245
+ return Promise.resolve(null);
246
+ }
247
+ return new Promise((resolve) => {
248
+ setTimeout(() => {
249
+ resolve(waitForWrapper(tryCount + 1));
250
+ }, WRAPPER_WAIT_INTERVAL);
251
+ });
252
+ }
253
+
254
+ function getContainerEl(wrapper, appCode) {
255
+ const id = CONTAINER_WRAPPER_ID + "-" + appCode;
256
+ let el = document.getElementById(id);
257
+ if (!el) {
258
+ el = document.createElement("div");
259
+ el.id = id;
260
+ el.style.height = "100%";
261
+ wrapper.appendChild(el);
262
+ }
263
+ return el;
264
+ }
265
+
266
+ function activateMicroApp(appCode) {
267
+ const config = microAppConfigs[appCode];
268
+ if (!config) return;
269
+ waitForWrapper().then((wrapper) => {
270
+ if (!wrapper) return;
271
+ if (currentActiveAppCode !== appCode) return; // 等待期间已切走
272
+ const el = getContainerEl(wrapper, appCode);
273
+ el.style.display = "";
274
+ const alive = aliveApps[appCode];
275
+ if (!alive) {
276
+ aliveApps[appCode] = {
277
+ el,
278
+ instance: loadMicroApp({
279
+ name: config.name,
280
+ entry: config.entry,
281
+ container: el,
282
+ props: config.props,
283
+ }),
284
+ };
285
+ return;
286
+ }
287
+ // 已保活:显示容器并通知子应用恢复路由监听、同步当前 hash(含"切到本应用另一菜单"的深导航)
288
+ notifyMicroApp(alive.instance, { microActive: true });
289
+ });
290
+ }
291
+
292
+ function deactivateMicroApp(appCode) {
293
+ const alive = aliveApps[appCode];
294
+ if (!alive) return;
295
+ alive.el.style.display = "none";
296
+ // 暂停子应用路由监听,防止隐藏期间对主应用的 URL 变化做出反应(回写 URL 互相打架)
297
+ notifyMicroApp(alive.instance, { microActive: false });
298
+ }
299
+
300
+ function notifyMicroApp(instance, props) {
301
+ if (!instance || typeof instance.update !== "function") return;
302
+ const mountPromise = instance.mountPromise || Promise.resolve();
303
+ mountPromise
304
+ .then(() => instance.update(props))
305
+ .catch((e) => {
306
+ console.error("[microRouter] 子应用 update 通知失败:", e);
307
+ });
308
+ }
309
+
310
+ /** 真正卸载全部子应用(登出等场景按需调用;常规页签切换不卸载) */
311
+ export function unmountAllMicroApps() {
312
+ Object.keys(aliveApps).forEach((code) => {
313
+ const alive = aliveApps[code];
314
+ if (alive && alive.instance) {
315
+ alive.instance.unmount().catch(() => {});
316
+ }
317
+ if (alive && alive.el && alive.el.parentNode) {
318
+ alive.el.parentNode.removeChild(alive.el);
319
+ }
320
+ });
321
+ aliveApps = {};
322
+ }
323
+
324
+ /**
325
+ * 每个子应用先按菜单生成精确路由以携带菜单标题等元数据,再追加通配兜底。
326
+ * 路由均不挂组件,内容由 qiankun 挂进 AppMain 的 #Appmicro 容器。
327
+ */
328
+ export function buildSubAppRoutes(apps, subAppMenus = {}) {
329
+ const routes = [];
330
+ (apps || []).forEach((app) => {
331
+ const seenPaths = {};
332
+ (subAppMenus[app.appCode] || []).forEach((menu, index) => {
333
+ let path = getAccessPath(menu).split("?")[0];
334
+ if (!path) return;
335
+ if (!path.startsWith("/")) {
336
+ path = "/" + path;
337
+ }
338
+ if (seenPaths[path]) return;
339
+ seenPaths[path] = true;
340
+ routes.push({
341
+ path,
342
+ name: `micro-${app.appCode}-menu-${menu.id || menu.menuCode || index}`,
343
+ meta: {
344
+ title: menu.menuName || app.appName,
345
+ enTitle: menu.menuEnName || null,
346
+ treePathName: menu.treePathName,
347
+ repeatOpen: menu.repeatOpen,
348
+ isMicroApp: true,
349
+ appCode: app.appCode,
350
+ },
351
+ });
352
+ });
353
+ routes.push({
354
+ path: "/" + app.appCode + "/*",
355
+ name: "micro-" + app.appCode,
356
+ meta: {
357
+ title: app.appName,
358
+ isMicroApp: true,
359
+ appCode: app.appCode,
360
+ },
361
+ });
362
+ });
363
+ return routes;
364
+ }
365
+
366
+ // 子应用表单脚本跳主应用路由必须走该回调,不得直接摸主应用 router
367
+ function createDefaultMainAdapter() {
368
+ return {
369
+ navigate(path) {
370
+ const vueRoot = window.$vueRoot;
371
+ if (vueRoot && vueRoot.$router) {
372
+ vueRoot.$router.push(path).catch(() => {});
373
+ }
374
+ },
375
+ openTab(path) {
376
+ this.navigate(path);
377
+ },
378
+ closeTab(view) {
379
+ const vueRoot = window.$vueRoot;
380
+ if (vueRoot && vueRoot.$store) {
381
+ return vueRoot.$store.dispatch(
382
+ "tagsView/delView",
383
+ view || vueRoot.$route
384
+ );
385
+ }
386
+ return Promise.resolve();
387
+ },
388
+ };
389
+ }
@@ -0,0 +1,8 @@
1
+ /* eslint-disable camelcase, no-undef */
2
+ /**
3
+ * qiankun 子应用模式下修正 webpack 运行时 publicPath,
4
+ * 必须在入口文件的第一行 import,早于其余任何模块。
5
+ */
6
+ if (window.__POWERED_BY_QIANKUN__) {
7
+ __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
8
+ }
@@ -1,19 +1,20 @@
1
- import {
2
- constantRoutes,
3
- } from '@base/router';
4
- import {
5
- asyncRoutes,
6
- sidebarRoutes
7
- } from '@base/router/modules/system';
8
- import Layout from '@/layout';
9
- import {
10
- getRouters
11
- } from '../../api/menu'
1
+ import { constantRoutes } from "@base/router";
2
+ import { asyncRoutes, sidebarRoutes } from "@base/router/modules/system";
3
+ import Layout from "@/layout";
4
+ import { getRouters } from "../../api/menu";
12
5
  import router from "@base/router";
13
6
  import storeConfig from "../config/index";
14
- import settings from "@base/settings";
15
- import { resolveComponentPath, resolveOwner, dispatchMenus } from "@base/utils/menuAdapter";
16
- import { getAppRegistry, registerSubApps, buildSubAppRoutes } from "@base/microRouter";
7
+ import settings from "@/settings";
8
+ import {
9
+ resolveComponentPath,
10
+ resolveOwner,
11
+ dispatchMenus,
12
+ } from "@base/utils/menuAdapter";
13
+ import {
14
+ getAppRegistry,
15
+ registerSubApps,
16
+ buildSubAppRoutes,
17
+ } from "@base/microRouter";
17
18
  import MenuFallback from "@base/views/user/menuFallback/index.vue";
18
19
 
19
20
  // qiankun 宿主态(仅 settings.microMainEnabled 的主应用登录后填充)
@@ -62,25 +63,26 @@ let configUtl = {
62
63
  const fail = (e) => resolve(createFallbackComponent(view, e));
63
64
  try {
64
65
  if (view) {
65
- let t = "@base/views"
66
+ let t = "@base/views";
66
67
  // let t2 = "@/components"
67
68
  if (view.startsWith(t)) {
68
69
  let path = view.substr(t.length);
69
- return require(['../../views' + path], resolve, fail);
70
- }/* else if (view.startsWith(t2)) {
70
+ return require(["../../views" + path], resolve, fail);
71
+ } /* else if (view.startsWith(t2)) {
71
72
  let path = view.substr(t2.length);
72
73
  return require(['@/components' + path], resolve, fail);
73
74
  } */
74
75
  }
75
- return require(['@/views' + view], resolve, fail)
76
+ return require(["@/views" + view], resolve, fail);
76
77
  } catch (e) {
77
78
  fail(e);
78
79
  }
79
- }
80
- }
80
+ };
81
+ },
81
82
  };
82
83
 
83
- export const loadView = (view) => { // 路由懒加载
84
+ export const loadView = (view) => {
85
+ // 路由懒加载
84
86
  if (view) {
85
87
  let tIndex = view.lastIndexOf("?");
86
88
  let newView = view;
@@ -89,12 +91,10 @@ export const loadView = (view) => { // 路由懒加载
89
91
  }
90
92
  return configUtl.loadView(newView);
91
93
  } else {
92
- return () => {
93
- };
94
+ return () => {};
94
95
  }
95
96
  };
96
97
 
97
-
98
98
  /**
99
99
  * Use meta.role to determine if the current user has permission
100
100
  * @param roles
@@ -102,11 +102,11 @@ export const loadView = (view) => { // 路由懒加载
102
102
  */
103
103
  function hasPermission(roles, route) {
104
104
  if (route.meta && route.meta.roles) {
105
- return roles.some(role => route.meta.roles.includes(role));
105
+ return roles.some((role) => route.meta.roles.includes(role));
106
106
  } else {
107
107
  return true;
108
108
  }
109
- };
109
+ }
110
110
 
111
111
  /**
112
112
  * Filter asynchronous routing tables by recursion
@@ -116,9 +116,9 @@ function hasPermission(roles, route) {
116
116
  function filterAsyncRoutes(routes, roles) {
117
117
  const res = [];
118
118
 
119
- routes.forEach(route => {
119
+ routes.forEach((route) => {
120
120
  const tmp = {
121
- ...route
121
+ ...route,
122
122
  };
123
123
  if (hasPermission(roles, tmp)) {
124
124
  if (tmp.children) {
@@ -128,7 +128,7 @@ function filterAsyncRoutes(routes, roles) {
128
128
  }
129
129
  });
130
130
  return res;
131
- };
131
+ }
132
132
 
133
133
  const state = {
134
134
  routes: [],
@@ -136,7 +136,7 @@ const state = {
136
136
  sidebarRouters: [],
137
137
  // 注册表里的别家 appCode 列表(宿主/独立运行时填充),
138
138
  // menuFallback 据此判定"归属别家应用",避免把普通组件加载失败误判成别家菜单
139
- registryAppCodes: []
139
+ registryAppCodes: [],
140
140
  };
141
141
 
142
142
  const mutations = {
@@ -149,20 +149,20 @@ const mutations = {
149
149
  },
150
150
  SET_REGISTRY_APP_CODES: (state, appCodes) => {
151
151
  state.registryAppCodes = appCodes || [];
152
- }
152
+ },
153
153
  };
154
154
 
155
155
  const actions = {
156
156
  generateRoutes(opt, roles) {
157
157
  let commit = opt.commit;
158
- return new Promise(resolve => {
158
+ return new Promise((resolve) => {
159
159
  let accessedRoutes;
160
- if (roles.includes('admin')) {
160
+ if (roles.includes("admin")) {
161
161
  accessedRoutes = configUtl.asyncRoutes || [];
162
162
  } else {
163
163
  accessedRoutes = filterAsyncRoutes(configUtl.asyncRoutes, roles);
164
164
  }
165
- commit('SET_SIDEBAR_ROUTERS', configUtl.sidebarRoutes || []);
165
+ commit("SET_SIDEBAR_ROUTERS", configUtl.sidebarRoutes || []);
166
166
  resolve(accessedRoutes);
167
167
  });
168
168
  },
@@ -170,39 +170,45 @@ const actions = {
170
170
  let commit = opt.commit;
171
171
  let dispatch = opt.dispatch;
172
172
  let isBdAdmin = opt.rootGetters.isBdAdmin;
173
- return new Promise(resolve => {
173
+ return new Promise((resolve) => {
174
174
  if (!isBdAdmin) {
175
175
  configUtl.getRouters({
176
- success: res => {
176
+ success: (res) => {
177
177
  var rows = res.objx || [];
178
- dispatch('setupHostAndRoutes', rows).then((accessedRoutes) => {
178
+ dispatch("setupHostAndRoutes", rows).then((accessedRoutes) => {
179
179
  resolve(accessedRoutes);
180
- })
181
- }
180
+ });
181
+ },
182
182
  });
183
183
  } else {
184
184
  let flag = user?.flag ?? null;
185
185
  let userFlagMenuMap = storeConfig?.userFlagMenuMap || {};
186
- let rows = userFlagMenuMap[flag] || []
187
- dispatch('setupHostAndRoutes', rows).then((accessedRoutes) => {
186
+ let rows = userFlagMenuMap[flag] || [];
187
+ dispatch("setupHostAndRoutes", rows).then((accessedRoutes) => {
188
188
  resolve(accessedRoutes);
189
- })
189
+ });
190
190
  }
191
191
  });
192
192
  },
193
193
  // qiankun 宿主编排:拉注册表 → 按归属切分 → 注册子应用,再走常规路由生成。
194
194
  // 非宿主(未开 microMainEnabled / 自身被 qiankun 挂载)直接透传。
195
- setupHostAndRoutes({dispatch, commit, rootState}, rows = []) {
196
- let isHost = settings.microMainEnabled === true && !window.__POWERED_BY_QIANKUN__;
195
+ setupHostAndRoutes({ dispatch, commit, rootState }, rows = []) {
196
+ let isHost =
197
+ settings.microMainEnabled === true && !window.__POWERED_BY_QIANKUN__;
197
198
  if (!isHost) {
198
- return dispatch('setSidebarRoute', rows);
199
+ return dispatch("setSidebarRoute", rows);
199
200
  }
200
201
  return getAppRegistry().then((apps) => {
201
202
  // 自排除:自身也在注册表时(子应用开宿主形态互访别家应用)不装载自己,
202
203
  // 否则会自嵌套且自身菜单被误判为"派发给子应用"而跳过本地路由
203
204
  let ownAppCode = settings.appCode || "";
204
- hostRegistryApps = (apps || []).filter((app) => app.appCode !== ownAppCode);
205
- commit('SET_REGISTRY_APP_CODES', hostRegistryApps.map((app) => app.appCode));
205
+ hostRegistryApps = (apps || []).filter(
206
+ (app) => app.appCode !== ownAppCode
207
+ );
208
+ commit(
209
+ "SET_REGISTRY_APP_CODES",
210
+ hostRegistryApps.map((app) => app.appCode)
211
+ );
206
212
  let { subAppMenus } = dispatchMenus(rows, hostRegistryApps);
207
213
  hostMicroRoutes = buildSubAppRoutes(hostRegistryApps, subAppMenus);
208
214
  if (hostRegistryApps.length) {
@@ -211,30 +217,29 @@ const actions = {
211
217
  userInfo: buildUserInfoSnapshot(rootState.user),
212
218
  });
213
219
  }
214
- return dispatch('setSidebarRoute', rows);
220
+ return dispatch("setSidebarRoute", rows);
215
221
  });
216
222
  },
217
223
  // qiankun 子应用模式:主应用经 props 下发菜单,替代 getRouters 自拉
218
- generateRoutesFromProps({dispatch}, menus = []) {
219
- return dispatch('setSidebarRoute', menus);
224
+ generateRoutesFromProps({ dispatch }, menus = []) {
225
+ return dispatch("setSidebarRoute", menus);
220
226
  },
221
- setSidebarRoute({commit, dispatch}, rows = []) {
222
- return new Promise(resolve => {
223
- let accessedRoutes = handleMenuRoutes(JSON.parse(JSON.stringify(
224
- rows))) || [];
225
- let nsidebarRoutes = handleSidebarRoutes(JSON.parse(JSON.stringify(
226
- rows))) || [];
227
- commit('SET_SIDEBAR_ROUTERS', nsidebarRoutes);
228
- commit('SET_ROUTES', accessedRoutes);
227
+ setSidebarRoute({ commit, dispatch }, rows = []) {
228
+ return new Promise((resolve) => {
229
+ let accessedRoutes =
230
+ handleMenuRoutes(JSON.parse(JSON.stringify(rows))) || [];
231
+ let nsidebarRoutes =
232
+ handleSidebarRoutes(JSON.parse(JSON.stringify(rows))) || [];
233
+ commit("SET_SIDEBAR_ROUTERS", nsidebarRoutes);
234
+ commit("SET_ROUTES", accessedRoutes);
229
235
  router.addRoutes(accessedRoutes); // 动态添加可访问路由表
230
- resolve(accessedRoutes)
236
+ resolve(accessedRoutes);
231
237
  });
232
- }
238
+ },
233
239
  };
234
240
 
235
-
236
241
  function getUrlParams(url) {
237
- let urlStr = url.split('?')[1];
242
+ let urlStr = url.split("?")[1];
238
243
  const urlSearchParams = new URLSearchParams(urlStr);
239
244
  const result = Object.fromEntries(urlSearchParams.entries());
240
245
  return result;
@@ -248,7 +253,7 @@ function isDelegatedToSubApp(route) {
248
253
 
249
254
  function handleMenuRoutes(routes) {
250
255
  var sidebarRoutes = {
251
- path: '',
256
+ path: "",
252
257
  component: configUtl.Layout,
253
258
  };
254
259
  var children = [];
@@ -283,9 +288,9 @@ function handleMenuRoutes(routes) {
283
288
  sidebarRoutes.children = children;
284
289
  var result = [sidebarRoutes];
285
290
  result.push({
286
- path: '*',
287
- redirect: '/404',
288
- hidden: true
291
+ path: "*",
292
+ redirect: "/404",
293
+ hidden: true,
289
294
  });
290
295
  return result;
291
296
  }
@@ -307,7 +312,7 @@ function createRoute3(route3, flag) {
307
312
  componentPath = "/report/vform/render";
308
313
  menuCode = "vform_render";
309
314
  } else {
310
- let pIndex = path.indexOf('?');
315
+ let pIndex = path.indexOf("?");
311
316
  if (pIndex > 0) {
312
317
  param = getUrlParams(path);
313
318
  path = path.substring(0, pIndex);
@@ -317,13 +322,13 @@ function createRoute3(route3, flag) {
317
322
  menuCode = route3.menuCode;
318
323
  }
319
324
  } else {
320
- componentPath = '';
325
+ componentPath = "";
321
326
  menuCode = route3.menuCode;
322
327
  }
323
328
  if (path && path.startsWith("@")) {
324
329
  // path = "/" + path;
325
- path = null
326
- componentPath = ""
330
+ path = null;
331
+ componentPath = "";
327
332
  }
328
333
  item = {
329
334
  id: route3.id,
@@ -343,9 +348,9 @@ function createRoute3(route3, flag) {
343
348
  enTitle: route3.menuEnName || null,
344
349
  treePathName: route3.treePathName,
345
350
  param: param,
346
- repeatOpen: route3.repeatOpen
347
- }
348
- }
351
+ repeatOpen: route3.repeatOpen,
352
+ },
353
+ };
349
354
  if (flag !== 1) {
350
355
  item.component = loadView(componentPath);
351
356
  }
@@ -353,7 +358,7 @@ function createRoute3(route3, flag) {
353
358
  //外部菜单
354
359
  let menuCode = route3.menuCode;
355
360
  let componentPath = "@base/views/user/outLink/index";
356
- let path = route3.route || ("/user/outLink/index" + "/" + menuCode);
361
+ let path = route3.route || "/user/outLink/index" + "/" + menuCode;
357
362
  item = {
358
363
  id: route3.id,
359
364
  menuName: route3.menuName,
@@ -364,15 +369,15 @@ function createRoute3(route3, flag) {
364
369
  type: route3.type,
365
370
  url: path,
366
371
  path: path,
367
- outLink: route3.url || '',
372
+ outLink: route3.url || "",
368
373
  linkType: route3.type,
369
374
  route: route3.route,
370
375
  name: "outLink",
371
376
  meta: {
372
377
  title: route3.menuName,
373
378
  enTitle: route3.menuName || null,
374
- treePathName: route3.treePathName
375
- }
379
+ treePathName: route3.treePathName,
380
+ },
376
381
  };
377
382
  if (flag !== 1) {
378
383
  item.component = loadView(componentPath);
@@ -386,8 +391,8 @@ function createRoute3(route3, flag) {
386
391
  item.meta = {
387
392
  title: route3.menuName,
388
393
  enTitle: route3.menuEnName || null,
389
- treePathName: route3.treePathName
390
- }
394
+ treePathName: route3.treePathName,
395
+ };
391
396
  }
392
397
  } else if (route3.type == 5) {
393
398
  //动态表单
@@ -410,8 +415,8 @@ function createRoute3(route3, flag) {
410
415
  title: route3.menuName,
411
416
  enTitle: route3.menuEnName || null,
412
417
  treePathName: route3.treePathName,
413
- repeatOpen: route3.repeatOpen
414
- }
418
+ repeatOpen: route3.repeatOpen,
419
+ },
415
420
  };
416
421
  if (flag !== 1) {
417
422
  item.component = loadView(componentPath);
@@ -421,33 +426,35 @@ function createRoute3(route3, flag) {
421
426
  }
422
427
 
423
428
  function handleSidebarRoutes(routes) {
424
- return routes.map(route1 => {
425
- let item1 = createRoute3(route1, 1);
426
- if (item1) {
427
- let children1 = [];
428
- if (route1.children) {
429
- route1.children.forEach((route2, index2) => {
430
- let item2 = createRoute3(route2, 1);
431
- if (item2) {
432
- let children2 = [];
433
- if (route2.children) {
434
- route2.children.forEach((route3, index3) => {
435
- let item3 = createRoute3(route3, 1);
436
- if (item3) {
437
- children2.push(item3);
438
- }
439
- });
429
+ return routes
430
+ .map((route1) => {
431
+ let item1 = createRoute3(route1, 1);
432
+ if (item1) {
433
+ let children1 = [];
434
+ if (route1.children) {
435
+ route1.children.forEach((route2, index2) => {
436
+ let item2 = createRoute3(route2, 1);
437
+ if (item2) {
438
+ let children2 = [];
439
+ if (route2.children) {
440
+ route2.children.forEach((route3, index3) => {
441
+ let item3 = createRoute3(route3, 1);
442
+ if (item3) {
443
+ children2.push(item3);
444
+ }
445
+ });
446
+ }
447
+ item2.children = children2;
448
+ children1.push(item2);
440
449
  }
441
- item2.children = children2;
442
- children1.push(item2)
443
- }
444
- });
445
- }
450
+ });
451
+ }
446
452
 
447
- item1.children = children1;
448
- }
449
- return item1;
450
- }).filter(route => route != null);
453
+ item1.children = children1;
454
+ }
455
+ return item1;
456
+ })
457
+ .filter((route) => route != null);
451
458
  }
452
459
 
453
460
  modules = {
@@ -455,7 +462,7 @@ modules = {
455
462
  state,
456
463
  mutations,
457
464
  actions,
458
- filterAsyncRoutes
465
+ filterAsyncRoutes,
459
466
  };
460
467
 
461
- export default modules
468
+ export default modules;
@@ -13,7 +13,7 @@
13
13
  </template>
14
14
 
15
15
  <script>
16
- import settings from "@base/settings";
16
+ import settings from "@/settings";
17
17
  import { getFirstSegment, BASE_SEGMENT } from "@base/utils/menuAdapter";
18
18
 
19
19
  export default {
@@ -40,10 +40,10 @@ export default {
40
40
  let seg = this.ownerSegment;
41
41
  let own = settings.appCode || "";
42
42
  return (
43
- !!seg
44
- && seg !== BASE_SEGMENT
45
- && seg !== own
46
- && this.registryAppCodes.indexOf(seg) !== -1
43
+ !!seg &&
44
+ seg !== BASE_SEGMENT &&
45
+ seg !== own &&
46
+ this.registryAppCodes.indexOf(seg) !== -1
47
47
  );
48
48
  },
49
49
  message() {
@@ -51,19 +51,19 @@ export default {
51
51
  if (!(settings.appCode || "")) {
52
52
  // 主站视角:归属子应用的菜单本应委派 qiankun 渲染,走到本地加载即为注册/部署异常
53
53
  return (
54
- this.$t1("该菜单归属子应用")
55
- + "「"
56
- + this.ownerSegment
57
- + "」"
58
- + this.$t1(",加载失败,请检查应用注册表与子应用部署")
54
+ this.$t1("该菜单归属子应用") +
55
+ "「" +
56
+ this.ownerSegment +
57
+ "」" +
58
+ this.$t1(",加载失败,请检查应用注册表与子应用部署")
59
59
  );
60
60
  }
61
61
  return (
62
- this.$t1("该菜单归属应用")
63
- + "「"
64
- + this.ownerSegment
65
- + "」"
66
- + this.$t1(",当前应用未部署对应页面,请在主平台中访问")
62
+ this.$t1("该菜单归属应用") +
63
+ "「" +
64
+ this.ownerSegment +
65
+ "」" +
66
+ this.$t1(",当前应用未部署对应页面,请在主平台中访问")
67
67
  );
68
68
  }
69
69
  return this.$t1("页面组件加载失败,请检查菜单配置或应用注册表");