cloud-web-corejs 1.0.54-dev.746 → 1.0.54-dev.749
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 +3 -1
- package/src/index.js +5 -2
- package/src/microRouter/index.js +389 -0
- package/src/public-path.js +8 -0
- package/src/store/config/index.js +24 -24
- package/src/store/modules/permission.js +115 -108
- package/src/views/user/menuFallback/index.vue +15 -15
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.
|
|
4
|
+
"version": "1.0.54-dev.749",
|
|
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 "
|
|
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(
|
|
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
|
+
}
|
|
@@ -458,7 +458,7 @@ modules = {
|
|
|
458
458
|
type: 0,
|
|
459
459
|
children: [],
|
|
460
460
|
},
|
|
461
|
-
|
|
461
|
+
{
|
|
462
462
|
id: 6657,
|
|
463
463
|
createDate: "2024-05-28 16:20:15",
|
|
464
464
|
modifyDate: "2025-01-02 10:20:52",
|
|
@@ -480,7 +480,7 @@ modules = {
|
|
|
480
480
|
grade: 2,
|
|
481
481
|
type: 0,
|
|
482
482
|
children: [],
|
|
483
|
-
},
|
|
483
|
+
},
|
|
484
484
|
{
|
|
485
485
|
id: 6949,
|
|
486
486
|
createDate: "2024-06-13 14:29:01",
|
|
@@ -617,28 +617,28 @@ modules = {
|
|
|
617
617
|
grade: 2,
|
|
618
618
|
type: 0,
|
|
619
619
|
},
|
|
620
|
-
{
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
},
|
|
620
|
+
// {
|
|
621
|
+
// id: 10002,
|
|
622
|
+
// createDate: "2022-05-31 09:39:47",
|
|
623
|
+
// modifyDate: "2024-08-19 10:50:08",
|
|
624
|
+
// createBy: "admin",
|
|
625
|
+
// modifyBy: "admin",
|
|
626
|
+
// orders: 1,
|
|
627
|
+
// parent: 60,
|
|
628
|
+
// menuName: "数据源",
|
|
629
|
+
// menuEnName: null,
|
|
630
|
+
// menuCode: "extend_datasource:list",
|
|
631
|
+
// sn: null,
|
|
632
|
+
// menuImg: null,
|
|
633
|
+
// url: "@base/views/user/extend_datasource/list",
|
|
634
|
+
// route: "/user/extend_datasource/list",
|
|
635
|
+
// enabled: true,
|
|
636
|
+
// treePath: ",12,60,",
|
|
637
|
+
// treePathName: ",",
|
|
638
|
+
// hasChild: true,
|
|
639
|
+
// grade: 2,
|
|
640
|
+
// type: 0,
|
|
641
|
+
// },
|
|
642
642
|
{
|
|
643
643
|
id: 10003,
|
|
644
644
|
createDate: "2022-05-31 09:39:47",
|
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
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 "
|
|
15
|
-
import {
|
|
16
|
-
|
|
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([
|
|
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([
|
|
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(
|
|
160
|
+
if (roles.includes("admin")) {
|
|
161
161
|
accessedRoutes = configUtl.asyncRoutes || [];
|
|
162
162
|
} else {
|
|
163
163
|
accessedRoutes = filterAsyncRoutes(configUtl.asyncRoutes, roles);
|
|
164
164
|
}
|
|
165
|
-
commit(
|
|
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(
|
|
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(
|
|
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 =
|
|
195
|
+
setupHostAndRoutes({ dispatch, commit, rootState }, rows = []) {
|
|
196
|
+
let isHost =
|
|
197
|
+
settings.microMainEnabled === true && !window.__POWERED_BY_QIANKUN__;
|
|
197
198
|
if (!isHost) {
|
|
198
|
-
return dispatch(
|
|
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(
|
|
205
|
-
|
|
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(
|
|
220
|
+
return dispatch("setSidebarRoute", rows);
|
|
215
221
|
});
|
|
216
222
|
},
|
|
217
223
|
// qiankun 子应用模式:主应用经 props 下发菜单,替代 getRouters 自拉
|
|
218
|
-
generateRoutesFromProps({dispatch}, menus = []) {
|
|
219
|
-
return dispatch(
|
|
224
|
+
generateRoutesFromProps({ dispatch }, menus = []) {
|
|
225
|
+
return dispatch("setSidebarRoute", menus);
|
|
220
226
|
},
|
|
221
|
-
setSidebarRoute({commit, dispatch}, rows = []) {
|
|
222
|
-
return new Promise(resolve => {
|
|
223
|
-
let accessedRoutes =
|
|
224
|
-
rows))) || [];
|
|
225
|
-
let nsidebarRoutes =
|
|
226
|
-
rows))) || [];
|
|
227
|
-
commit(
|
|
228
|
-
commit(
|
|
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(
|
|
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:
|
|
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 ||
|
|
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
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
route1.children
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
route2.children
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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
|
-
|
|
442
|
-
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
}
|
|
450
|
+
});
|
|
451
|
+
}
|
|
446
452
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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 "
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
this.$t1("该菜单归属子应用") +
|
|
55
|
+
"「" +
|
|
56
|
+
this.ownerSegment +
|
|
57
|
+
"」" +
|
|
58
|
+
this.$t1(",加载失败,请检查应用注册表与子应用部署")
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
return (
|
|
62
|
-
this.$t1("该菜单归属应用")
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
this.$t1("该菜单归属应用") +
|
|
63
|
+
"「" +
|
|
64
|
+
this.ownerSegment +
|
|
65
|
+
"」" +
|
|
66
|
+
this.$t1(",当前应用未部署对应页面,请在主平台中访问")
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
return this.$t1("页面组件加载失败,请检查菜单配置或应用注册表");
|