@epxing/core 5.3.0-beta.2 → 5.3.0-beta.3

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.
Files changed (101) hide show
  1. package/API.md +26 -25
  2. package/README.md +3 -1
  3. package/dist/.cache/route-chart-release/frontend/frame/public/js/ecStat.min.js +4 -0
  4. package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts-wordcloud.min.js +4 -0
  5. package/dist/.cache/route-chart-release/frontend/frame/public/js/echarts.min.js +4 -0
  6. package/dist/_virtual/_plugin-vue_export-helper.js +10 -0
  7. package/dist/_virtual/jsencrypt.min.js +1 -1
  8. package/dist/assets/ecStat.min-BrTYPOXX.js +1 -0
  9. package/dist/assets/echarts-wordcloud.min-nWR4Hzny.js +3 -0
  10. package/dist/assets/echarts.min-DROS9E5X.js +45 -0
  11. package/dist/assets/role_select-DTqRlFNz.webp +0 -0
  12. package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/jsencrypt@3.5.4/_vendor/jsencrypt/bin/jsencrypt.min.js +1 -1
  13. package/dist/src/RootApp.js +54 -0
  14. package/dist/src/api/createHttp.js +6 -0
  15. package/dist/src/app-ui-settings.js +49 -0
  16. package/dist/src/axios.js +10 -15
  17. package/dist/src/chart-runtime-assets.js +9 -0
  18. package/dist/src/create-app.js +3 -6
  19. package/dist/src/index.js +2 -0
  20. package/dist/src/loadComponent.js +2 -2
  21. package/dist/src/menu-route.js +11 -0
  22. package/dist/src/mixins/component.js +3 -0
  23. package/dist/src/navigation-context.js +47 -0
  24. package/dist/src/navigation.js +43 -12
  25. package/dist/src/package-install.js +3 -2
  26. package/dist/src/plugins/element-plus.js +8 -8
  27. package/dist/src/public-api.js +4 -2
  28. package/dist/src/route-components.js +9 -0
  29. package/dist/src/router/config.js +7 -8
  30. package/dist/src/runtime-services.js +1 -1
  31. package/dist/src/runtime-utils/meta.js +3 -0
  32. package/dist/src/runtime-utils/pdf.viewer.js +31 -15
  33. package/dist/src/runtime-utils/util.js +29 -5
  34. package/dist/src/shared-packages.js +1 -3
  35. package/dist/src/store/modules/list.js +25 -3
  36. package/dist/src/store/modules/meta.js +49 -7
  37. package/dist/src/style-presets.js +4 -4
  38. package/dist/src/ui-settings.js +90 -18
  39. package/dist/src/views/App.js +48 -0
  40. package/dist/src/views/AppRoleSelect.js +233 -0
  41. package/dist/src/views/Error.js +210 -0
  42. package/dist/src/views/Module.js +173 -0
  43. package/dist/style.css +251 -0
  44. package/package.json +4 -4
  45. package/src/RootApp.vue +75 -0
  46. package/src/api/createHttp.js +7 -0
  47. package/src/api/index.js +47 -47
  48. package/src/app-ui-settings.js +31 -0
  49. package/src/axios.js +311 -318
  50. package/src/chart-runtime-assets.js +7 -0
  51. package/src/create-app.js +3 -7
  52. package/src/index.js +28 -28
  53. package/src/install.js +157 -157
  54. package/src/loadComponent.js +187 -187
  55. package/src/loadLibrary.js +99 -99
  56. package/src/menu-route.js +12 -1
  57. package/src/mixins/component.js +1464 -1461
  58. package/src/navigation-context.js +49 -0
  59. package/src/navigation.js +208 -176
  60. package/src/package-install.js +2 -1
  61. package/src/plugins/element-plus.js +302 -302
  62. package/src/plugins/frame.js +178 -178
  63. package/src/public-api.js +1 -0
  64. package/src/route-components.js +7 -0
  65. package/src/router/config.js +861 -864
  66. package/src/router/public.js +1 -1
  67. package/src/runtime-services.js +1 -1
  68. package/src/runtime-utils/fieldFactory.js +179 -179
  69. package/src/runtime-utils/meta.js +399 -378
  70. package/src/runtime-utils/pdf.viewer.js +672 -644
  71. package/src/runtime-utils/util.js +1357 -1330
  72. package/src/shared-packages.js +1 -3
  73. package/src/store/modules/config.js +351 -351
  74. package/src/store/modules/list.js +30 -3
  75. package/src/store/modules/locale.js +236 -236
  76. package/src/store/modules/meta.js +314 -265
  77. package/src/style-presets.js +4 -4
  78. package/src/ui-settings.js +84 -23
  79. package/src/views/App.vue +53 -0
  80. package/src/views/AppRoleSelect.vue +334 -0
  81. package/src/views/Error.vue +63 -0
  82. package/src/views/Module.vue +210 -0
  83. package/src/xss.js +26 -26
  84. package/types/app.d.ts +10 -10
  85. package/types/axios.d.ts +1 -1
  86. package/types/component-mixin.d.ts +1 -1
  87. package/types/field-factory.d.ts +1 -1
  88. package/types/global-mixin.d.ts +1 -1
  89. package/types/http.d.ts +1 -1
  90. package/types/index.d.ts +3 -0
  91. package/types/meta.d.ts +1 -1
  92. package/types/navigation.d.ts +21 -21
  93. package/types/pdf-viewer.d.ts +1 -1
  94. package/types/runtime.d.ts +13 -13
  95. package/types/store.d.ts +1 -1
  96. package/types/util.d.ts +2 -2
  97. /package/dist/{build → .cache/route-chart-release/frontend/frame/build}/stubs/empty-components.js +0 -0
  98. /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-icons.names.js +0 -0
  99. /package/dist/{src → .cache/route-chart-release/frontend/frame/src}/element-plus.lazy.js +0 -0
  100. /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/en.js +0 -0
  101. /package/dist/{_vendor → frontend/frame/_vendor}/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/zh-cn.js +0 -0
@@ -1,4 +1,4 @@
1
- import { __module as jsencrypt_min$1 } from "../../../../../../_virtual/jsencrypt.min2.js";
1
+ import { __module as jsencrypt_min$1 } from "../../../../../../../../_virtual/jsencrypt.min2.js";
2
2
  var jsencrypt_min = jsencrypt_min$1.exports;
3
3
  var hasRequiredJsencrypt_min;
4
4
  function requireJsencrypt_min() {
@@ -0,0 +1,54 @@
1
+ import '../style.css';
2
+ import { migrateLegacyTheme, initTheme } from "./ui-settings.js";
3
+ import storage from "@epxing/utils/src/storage";
4
+ import { resolveComponent, openBlock, createElementBlock, createBlock } from "vue";
5
+ /* empty css */
6
+ import _export_sfc from "../_virtual/_plugin-vue_export-helper.js";
7
+ const _sfc_main = {
8
+ name: "epx-root-app",
9
+ computed: {
10
+ routeViewKey() {
11
+ const route = this.$route;
12
+ if (route.name === "system") {
13
+ return JSON.stringify([route.name, route.params.client, route.params.system]);
14
+ }
15
+ if (route.name === "wikiSite" || route.name === "wikiView") {
16
+ return JSON.stringify([route.name, route.params.client, route.params.system, route.params.wiki || route.query.w]);
17
+ }
18
+ return route.meta && route.meta.refresh !== false ? route.path : this.routeKeyName;
19
+ },
20
+ // b17a2b119 把根 key 从 $route.name 改成了本计算属性,但**没把它加上**——
21
+ // 于是 refresh:false 的路由 key 恒为 undefined,每次渲染刷一条
22
+ // [Vue warn]: Property "routeKeyName" was accessed during render but is not defined。
23
+ // 实际效果是「所有 refresh:false 路由共用一个空 key」,比设计更粗:
24
+ // help / client / defaultApp 也跟着不重挂了。这里补回该提交的原意——
25
+ // 只在菜单族内归一,其余仍用 $route.name(即改动前的行为)。
26
+ routeKeyName() {
27
+ const name = this.$route.name;
28
+ if (name === "app1" || name === "appMenu") return "app";
29
+ if (name === "hall" || name === "hallMenu") return "hall";
30
+ return name;
31
+ }
32
+ },
33
+ created() {
34
+ migrateLegacyTheme(storage.get("epx_frame_theme"));
35
+ initTheme();
36
+ },
37
+ mounted() {
38
+ const that = this;
39
+ window.addEventListener("resize", that.$_.debounce(() => {
40
+ that.$store.commit("GET_VIEWPORT");
41
+ }, 200));
42
+ }
43
+ };
44
+ const _hoisted_1 = { class: "epx-app-root" };
45
+ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
46
+ const _component_router_view = resolveComponent("router-view");
47
+ return openBlock(), createElementBlock("div", _hoisted_1, [
48
+ (openBlock(), createBlock(_component_router_view, { key: $options.routeViewKey }))
49
+ ]);
50
+ }
51
+ const Root = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__scopeId", "data-v-80523e3c"]]);
52
+ export {
53
+ Root as default
54
+ };
@@ -164,6 +164,12 @@ const createHttp = (config) => {
164
164
  if (meta.serverCode && !options.domainContext) {
165
165
  projectName = meta.serverCode;
166
166
  }
167
+ if (router.currentRoute.value.name === "hall") {
168
+ const { clientCode: clientCode2, systemCode } = meta;
169
+ if (clientCode2) clientId = clientCode2;
170
+ if (systemCode) sysId = systemCode;
171
+ if (entityId.includes("@system@")) entityId = `${entityId.split("@")[0]}@${sysId}@${clientId}`;
172
+ }
167
173
  } else if (router.currentRoute.value.name === "hall") {
168
174
  const isSystemEntity = entityId.includes("@system@") || entityId.length === 32;
169
175
  if (action !== "getMeta" && action !== "getSystemInfo" && isSystemEntity) {
@@ -0,0 +1,49 @@
1
+ import '../style.css';
2
+ import { DEFAULTS, LEGACY_RADIUS_AXIS, LEGACY_DENSITY_AXIS } from "./ui-settings.js";
3
+ const APP_UI_KEYS = [
4
+ "themeMode",
5
+ "themeColor",
6
+ "customTheme",
7
+ "menuAccordion",
8
+ "showLogo",
9
+ "breadcrumb",
10
+ "sidebarDark",
11
+ "styleRadius",
12
+ "styleFont",
13
+ "styleDensity",
14
+ "styleElevation",
15
+ "componentSize",
16
+ "tabsPosition",
17
+ "tabsStyle",
18
+ "tabsKeepAlive",
19
+ "pageAnim",
20
+ "progressBar",
21
+ "pageLoading"
22
+ ];
23
+ function resolveAppUiDefaults(config = {}, pageConfig = {}) {
24
+ var _a;
25
+ const legacy = { ...pageConfig, ...config };
26
+ const result = {};
27
+ for (const key of APP_UI_KEYS) {
28
+ if (legacy[key] !== void 0 && legacy[key] !== null) result[key] = legacy[key];
29
+ }
30
+ if (result.styleRadius === void 0 && legacy.borderRadius !== void 0) {
31
+ result.styleRadius = LEGACY_RADIUS_AXIS[legacy.borderRadius] || "";
32
+ }
33
+ if (result.styleDensity === void 0 && legacy.componentMargin !== void 0) {
34
+ result.styleDensity = LEGACY_DENSITY_AXIS[legacy.componentMargin] || "";
35
+ }
36
+ for (const key of APP_UI_KEYS) {
37
+ if (((_a = config.uiDefaults) == null ? void 0 : _a[key]) !== void 0 && config.uiDefaults[key] !== null) result[key] = config.uiDefaults[key];
38
+ }
39
+ return result;
40
+ }
41
+ function createAppUiDraft(config = {}) {
42
+ const defaults = resolveAppUiDefaults(config);
43
+ return Object.fromEntries(APP_UI_KEYS.map((key) => [key, defaults[key] ?? DEFAULTS[key]]));
44
+ }
45
+ export {
46
+ APP_UI_KEYS,
47
+ createAppUiDraft,
48
+ resolveAppUiDefaults
49
+ };
package/dist/src/axios.js CHANGED
@@ -5,7 +5,7 @@ import util from "./runtime-utils/util.js";
5
5
  import { getXsrfToken, setXsrfToken } from "@epxing/utils/src/storage";
6
6
  import { consumeUrlToken, setStoredToken, removeStoredToken, getStoredToken } from "@epxing/utils/src/token-storage";
7
7
  import { ElMessage } from "element-plus/es/components/message/index.mjs";
8
- import { MENU_ROUTE_ALIAS, roleStorage } from "./menu-route.js";
8
+ import { resolveRouteRole } from "./menu-route.js";
9
9
  let message = null;
10
10
  let timer = null;
11
11
  const normalizeBearerToken = (authorization) => {
@@ -52,10 +52,11 @@ let encryptedAesKey = null;
52
52
  const ensureCrypto = () => {
53
53
  if (cryptoReadyPromise) return cryptoReadyPromise;
54
54
  cryptoReadyPromise = (async () => {
55
- const [CryptoJS, jsEncryptModule] = await Promise.all([
55
+ const [cryptoModule, jsEncryptModule] = await Promise.all([
56
56
  __epxPackagePreload(() => import("crypto-js"), true ? [] : void 0, import.meta.url),
57
57
  __epxPackagePreload(() => import("../_virtual/jsencrypt.min.js").then((n) => n.j), true ? [] : void 0, import.meta.url)
58
58
  ]);
59
+ const CryptoJS = "default" in cryptoModule ? cryptoModule.default : cryptoModule;
59
60
  const JSEncrypt = jsEncryptModule.default;
60
61
  let rsaKey = window.store.state.config.decryptKey.rsaKey;
61
62
  if (!rsaKey) {
@@ -79,7 +80,7 @@ const init = () => {
79
80
  instance.defaults.xsrfCookieName = null;
80
81
  axios$1.defaults.xsrfCookieName = null;
81
82
  instance.interceptors.request.use(async (config) => {
82
- var _a;
83
+ var _a, _b, _c, _d, _e;
83
84
  const legacyCancelToken = config.cancelToken;
84
85
  if ((typeof __EPX_VUE2_COMPAT__ === "undefined" || __EPX_VUE2_COMPAT__) && window.__EPX_VUE2_COMPAT__ !== false && legacyCancelToken && typeof legacyCancelToken.subscribe !== "function" && typeof ((_a = legacyCancelToken.promise) == null ? void 0 : _a.then) === "function") {
85
86
  const { adaptLegacyCancelToken } = await __epxPackagePreload(async () => {
@@ -91,28 +92,21 @@ const init = () => {
91
92
  if (window.IP) {
92
93
  config.baseURL = window.IP;
93
94
  }
94
- let name = null;
95
- let params = {};
96
- if (window.router) {
97
- params = window.router.currentRoute.value.params;
98
- name = window.router.currentRoute.value.name;
99
- }
100
95
  const locationUrl = window.location.hash.split("?")[0];
96
+ const currentRoute = (_c = (_b = window.router) == null ? void 0 : _b.currentRoute) == null ? void 0 : _c.value;
97
+ const route = (currentRoute == null ? void 0 : currentRoute.name) ? currentRoute : ((_e = (_d = window.router) == null ? void 0 : _d.resolve) == null ? void 0 : _e.call(_d, locationUrl.slice(1))) || currentRoute;
98
+ const { name = null, params = {} } = route || {};
101
99
  var reg = /(app\/role\/select|hall\/role\/select|app|hall\/login|hall|login|system|client|service\/setting|recruit\/register)\/(\w+)\/?([\w-]+)?\/(\w+)\/?([\w-_]+)?/;
102
100
  var regResult = reg.exec(locationUrl);
103
101
  const regClientCode = regResult ? RegExp.$2 === "login" ? RegExp.$3 : RegExp.$2 : null;
104
102
  const regSystemCode = regResult ? RegExp.$3 : null;
105
103
  const regAppCode = regResult ? RegExp.$1 === "hall" ? "FM_SERVICE_HALL" : RegExp.$4 : null;
106
- const regRoleCode = regResult ? RegExp.$1 === "hall" ? RegExp.$3 : RegExp.$1 === "system" ? RegExp.$4 : RegExp.$5 : null;
107
104
  const { clientConfig = {}, appConfig = {}, temporaryRole } = window.store.state.config;
108
105
  const { CODE: CLIENT_CODE = "" } = clientConfig;
109
106
  const { CODE: APP_CODE = "", EXTEND_OF_COMPETENCE } = appConfig;
110
107
  const clientCode = params.client || regClientCode || CLIENT_CODE;
111
108
  const appCode = params.app || APP_CODE || regAppCode;
112
- let roleCode = params.role || regRoleCode || "";
113
- if (MENU_ROUTE_ALIAS[name]) {
114
- roleCode = params.role || roleStorage.get(regClientCode, regSystemCode) || "";
115
- }
109
+ let roleCode = resolveRouteRole({ params: { ...params, client: clientCode, system: params.client ? params.system : regSystemCode } });
116
110
  if (name === "Config") roleCode = "SYSTEM";
117
111
  const token = consumeUrlToken(clientCode ? clientCode + "-token" : "");
118
112
  if (window.IP && token) {
@@ -182,7 +176,8 @@ const init = () => {
182
176
  if (data.responseEncrypt) {
183
177
  const key = response.config.encryptAesKey;
184
178
  const iv = response.config.encryptIv;
185
- return __epxPackagePreload(() => import("crypto-js"), true ? [] : void 0, import.meta.url).then((CryptoJS) => {
179
+ return __epxPackagePreload(() => import("crypto-js"), true ? [] : void 0, import.meta.url).then((cryptoModule) => {
180
+ const CryptoJS = "default" in cryptoModule ? cryptoModule.default : cryptoModule;
186
181
  const decrypted = CryptoJS.AES.decrypt(data.data, key, {
187
182
  iv,
188
183
  mode: CryptoJS.mode.CBC,
@@ -0,0 +1,9 @@
1
+ import '../style.css';
2
+ import echartsUrl from "../.cache/route-chart-release/frontend/frame/public/js/echarts.min.js";
3
+ import ecStatUrl from "../.cache/route-chart-release/frontend/frame/public/js/ecStat.min.js";
4
+ import { default as default2 } from "../.cache/route-chart-release/frontend/frame/public/js/echarts-wordcloud.min.js";
5
+ const chartRuntimeAssets = [echartsUrl, ecStatUrl];
6
+ export {
7
+ chartRuntimeAssets as default,
8
+ default2 as wordcloudUrl
9
+ };
@@ -1,11 +1,8 @@
1
1
  import '../style.css';
2
- import { createApp, h } from "vue";
3
- import { createRouter, createWebHashHistory, RouterView } from "vue-router";
2
+ import { createApp } from "vue";
3
+ import { createRouter, createWebHashHistory } from "vue-router";
4
4
  import { createFrameStore } from "./store/create-store.js";
5
- const Root = {
6
- name: "EpxCoreApp",
7
- render: () => h("div", { class: "epx-app-root" }, [h(RouterView)])
8
- };
5
+ import Root from "./RootApp.js";
9
6
  function createCoreApp(options, corePlugin) {
10
7
  const {
11
8
  rootComponent = Root,
package/dist/src/index.js CHANGED
@@ -21,6 +21,7 @@ import { createFrameStore, createStoreModules, storeModules } from "./store/crea
21
21
  import { getApp, registerComponent, resolveComponent, setApp } from "./app.js";
22
22
  import { default as default11 } from "./mixins/index.js";
23
23
  import { default as default12 } from "./navigation.js";
24
+ import { default as default13 } from "./route-components.js";
24
25
  function publishCoreRuntime() {
25
26
  publishSharedPackage("@epxing/core", { ...src_publicApi, installCore, createCore, createApp, publishCoreRuntime, default: EpxCore });
26
27
  publishSharedPackage("@epxing/utils", utils);
@@ -69,6 +70,7 @@ export {
69
70
  registerComponent,
70
71
  registerRouteComponents,
71
72
  resolveComponent,
73
+ default13 as routeComponents,
72
74
  default10 as routerConfig,
73
75
  runExpByScope,
74
76
  setApp,
@@ -15,8 +15,8 @@ function injectRemoteCss(href) {
15
15
  const strictPacks = () => typeof window !== "undefined" && window.EPX_DISABLE_LAZY_PACKS;
16
16
  const optionalGroupCache = {};
17
17
  const OPTIONAL_GROUPS = {
18
- dashboard: () => __epxPackagePreload(() => import("../build/stubs/empty-components.js"), true ? [] : void 0, import.meta.url),
19
- designer: () => __epxPackagePreload(() => import("../build/stubs/empty-components.js"), true ? [] : void 0, import.meta.url)
18
+ dashboard: () => __epxPackagePreload(() => import("../.cache/route-chart-release/frontend/frame/build/stubs/empty-components.js"), true ? [] : void 0, import.meta.url),
19
+ designer: () => __epxPackagePreload(() => import("../.cache/route-chart-release/frontend/frame/build/stubs/empty-components.js"), true ? [] : void 0, import.meta.url)
20
20
  };
21
21
  function loadOptionalGroup(app, which) {
22
22
  if (strictPacks()) return Promise.resolve({});
@@ -66,9 +66,19 @@ const MENU_ROUTE_ALIAS = { appMenu: "app1", hallMenu: "hall" };
66
66
  function effectiveRouteName(name) {
67
67
  return MENU_ROUTE_ALIAS[name] || name;
68
68
  }
69
+ function getRouteMenuKey(route) {
70
+ var _a, _b;
71
+ const key = ((_a = route.params) == null ? void 0 : _a.menuKey) || (effectiveRouteName(route.name) === "system" ? (_b = route.query) == null ? void 0 : _b.menuKey : "");
72
+ return typeof key === "string" ? key : "";
73
+ }
69
74
  function menuLocation(route, key, query) {
70
75
  const q = query !== void 0 ? query : route.query;
71
76
  const { client, system, app } = route.params || {};
77
+ if (effectiveRouteName(route.name) === "system") {
78
+ const systemQuery = { ...q };
79
+ delete systemQuery.menuKey;
80
+ return { name: "system", params: { client, system, menuKey: key }, query: systemQuery };
81
+ }
72
82
  if (effectiveRouteName(route.name) === "hall") {
73
83
  return { name: "hallMenu", params: { client, menuKey: key }, query: q };
74
84
  }
@@ -80,6 +90,7 @@ export {
80
90
  findMenuByKey,
81
91
  findMenuPath,
82
92
  getMenuKey,
93
+ getRouteMenuKey,
83
94
  menuLocation,
84
95
  resolveRouteRole,
85
96
  roleStorage
@@ -1201,15 +1201,18 @@ const component = {
1201
1201
  if (component2 instanceof Promise) {
1202
1202
  await component2;
1203
1203
  }
1204
+ if (this._isBeingDestroyed || this._isDestroyed) return;
1204
1205
  if (this.$metaId && !this.$meta) {
1205
1206
  await this.$store.dispatch({
1206
1207
  type: "ADD_META",
1207
1208
  metaId: this.$metaId
1208
1209
  });
1209
1210
  }
1211
+ if (this._isBeingDestroyed || this._isDestroyed) return;
1210
1212
  this.$componentStatus = "init";
1211
1213
  this.initComponent(this.$component);
1212
1214
  this.$nextTick(() => {
1215
+ if (this._isBeingDestroyed || this._isDestroyed) return;
1213
1216
  if (this.$el) {
1214
1217
  const compId = this.isPage ? this.$pageId : this.compId;
1215
1218
  if (this.$el.classList) {
@@ -0,0 +1,47 @@
1
+ import '../style.css';
2
+ import { findMenuPath, effectiveRouteName, resolveRouteRole } from "./menu-route.js";
3
+ const fields = ["moduleId", "pageId", "component", "metaId", "flag", "showMenu"];
4
+ function storageKey(route, menuId, userId) {
5
+ const name = effectiveRouteName(route.name);
6
+ if (name !== "app1" && name !== "hall") return "";
7
+ const { client, system, app } = route.params || {};
8
+ return "epx_nav_context:" + JSON.stringify([name, client, system, app, resolveRouteRole(route), userId, menuId]);
9
+ }
10
+ function saveMenuContext(route, menu, context, userId = "") {
11
+ const key = storageKey(route, menu.ID, userId);
12
+ if (!key) return;
13
+ try {
14
+ if (!(context == null ? void 0 : context.moduleId)) {
15
+ window.sessionStorage.removeItem(key);
16
+ return;
17
+ }
18
+ const saved = {};
19
+ for (const field of fields) {
20
+ const value = context[field];
21
+ if (typeof value === "string" || typeof value === "boolean") saved[field] = value;
22
+ }
23
+ window.sessionStorage.setItem(key, JSON.stringify(saved));
24
+ } catch (error) {
25
+ }
26
+ }
27
+ function readMenuContext(route, menu, menus, userId = "") {
28
+ const key = storageKey(route, menu.ID, userId);
29
+ if (!key) return null;
30
+ try {
31
+ const saved = JSON.parse(window.sessionStorage.getItem(key) || "null");
32
+ if (!saved) return null;
33
+ const path = findMenuPath(menus, menu.ID);
34
+ const root = path.find((item) => item.ID === saved.moduleId);
35
+ if (!root || (root.MAIN_PAGE || "") !== (saved.pageId || "")) {
36
+ window.sessionStorage.removeItem(key);
37
+ return null;
38
+ }
39
+ return saved;
40
+ } catch (error) {
41
+ return null;
42
+ }
43
+ }
44
+ export {
45
+ readMenuContext,
46
+ saveMenuContext
47
+ };
@@ -1,8 +1,9 @@
1
1
  import '../style.css';
2
2
  import { nextTick } from "vue";
3
3
  import { runtimeRouter, runtimeStore } from "./runtime-services.js";
4
- import { roleStorage, findMenuByKey, getMenuKey, menuLocation, effectiveRouteName } from "./menu-route.js";
5
- import { MENU_ROUTE_ALIAS, findMenuPath, resolveRouteRole } from "./menu-route.js";
4
+ import { roleStorage, findMenuByKey, getMenuKey, getRouteMenuKey, menuLocation, effectiveRouteName, resolveRouteRole } from "./menu-route.js";
5
+ import { MENU_ROUTE_ALIAS, findMenuPath } from "./menu-route.js";
6
+ import { readMenuContext, saveMenuContext } from "./navigation-context.js";
6
7
  function findNavId(menus = [], menuId, parent) {
7
8
  for (let i = 0; i < menus.length; i++) {
8
9
  const menu = menus[i];
@@ -15,8 +16,19 @@ function findNavId(menus = [], menuId, parent) {
15
16
  }
16
17
  }
17
18
  let lastSyncedKey = null;
19
+ const navigationUserId = () => {
20
+ var _a, _b, _c, _d;
21
+ return ((_b = (_a = runtimeStore.state.user) == null ? void 0 : _a.user) == null ? void 0 : _b.id) || ((_d = (_c = runtimeStore.state.user) == null ? void 0 : _c.userInfo) == null ? void 0 : _d.ID) || "";
22
+ };
18
23
  function activateMenu(menuId, extraProps = {}, { syncUrl = true, replaceUrl = false, query } = {}) {
19
24
  const appMenus = runtimeStore.state.config.appMenus || [];
25
+ if (effectiveRouteName(runtimeRouter.currentRoute.value.name) === "system") {
26
+ const menu = findMenuByKey(appMenus, menuId);
27
+ if (!menu) return false;
28
+ nextTick(activateHome);
29
+ if (syncUrl) syncMenuUrl(menu, { replace: replaceUrl, query });
30
+ return true;
31
+ }
20
32
  const topLevel = appMenus.find((m) => m.ID === menuId);
21
33
  let menuNode = null;
22
34
  let params = null;
@@ -62,16 +74,17 @@ function activateMenu(menuId, extraProps = {}, { syncUrl = true, replaceUrl = fa
62
74
  }
63
75
  runtimeStore.commit("DESTORY_TAB", params.key);
64
76
  nextTick(() => runtimeStore.commit("CREATE_TAB", params));
65
- if (syncUrl) syncMenuUrl(menuNode, { replace: replaceUrl, query });
77
+ if (syncUrl) syncMenuUrl(menuNode, { replace: replaceUrl, query, context: params });
66
78
  return true;
67
79
  }
68
- function syncMenuUrl(menu, { replace = false, query } = {}) {
80
+ function syncMenuUrl(menu, { replace = false, query, context } = {}) {
69
81
  const key = menu && menu.ID;
70
82
  if (!key || !/^[0-9A-Fa-f]{32}$/.test(key)) return;
71
83
  const route = runtimeRouter.currentRoute.value;
72
84
  const name = effectiveRouteName(route.name);
73
- if (name !== "app1" && name !== "hall") return;
74
- if (route.params.menuKey === key && query === void 0) return;
85
+ if (name !== "app1" && name !== "hall" && name !== "system") return;
86
+ saveMenuContext(route, menu, context, navigationUserId());
87
+ if (getRouteMenuKey(route) === key && query === void 0) return;
75
88
  lastSyncedKey = key;
76
89
  const loc = menuLocation(route, key, query);
77
90
  (replace ? runtimeRouter.replace(loc) : runtimeRouter.push(loc)).catch(() => {
@@ -81,13 +94,16 @@ const ignoreNavFailure = () => {
81
94
  };
82
95
  function clearMenuUrl({ replace = false } = {}) {
83
96
  const route = runtimeRouter.currentRoute.value;
84
- if (!route.params || !route.params.menuKey) return;
97
+ if (!getRouteMenuKey(route)) return;
85
98
  const { client, system, app } = route.params;
86
- const loc = effectiveRouteName(route.name) === "hall" ? { name: "hall", params: { client }, query: route.query } : { name: "app1", params: { client, system, app }, query: route.query };
99
+ const name = effectiveRouteName(route.name);
100
+ const query = { ...route.query };
101
+ if (name === "system") delete query.menuKey;
102
+ const loc = name === "system" ? { name: "system", params: { client, system, role: resolveRouteRole(route) }, query } : name === "hall" ? { name: "hall", params: { client }, query: route.query } : { name: "app1", params: { client, system, app }, query: route.query };
87
103
  (replace ? runtimeRouter.replace(loc) : runtimeRouter.push(loc)).catch(ignoreNavFailure);
88
104
  }
89
105
  function activateFromRoute(route) {
90
- const key = route.params && route.params.menuKey;
106
+ const key = getRouteMenuKey(route);
91
107
  if (!key) return false;
92
108
  if (key === lastSyncedKey) {
93
109
  lastSyncedKey = null;
@@ -98,6 +114,20 @@ function activateFromRoute(route) {
98
114
  console.warn(`[nav] 菜单直达:找不到 menuKey=${key}(权限变化或编号已改),落应用首页`);
99
115
  return false;
100
116
  }
117
+ const context = readMenuContext(route, menu, runtimeStore.state.config.appMenus || [], navigationUserId());
118
+ if (context) {
119
+ const params = {
120
+ ...context,
121
+ key: "default-" + context.moduleId,
122
+ component: context.component || "module-index-page",
123
+ title: menu.NAME_ALIAS || menu.NAME || menu.text,
124
+ // 来源容器与目标相同时沿用独立入口,避免额外生成一层侧栏。
125
+ ...context.moduleId !== menu.ID ? { activeMenuId: menu.ID, activeMenuPageId: menu.MAIN_PAGE } : {}
126
+ };
127
+ runtimeStore.commit("DESTORY_TAB", params.key);
128
+ nextTick(() => runtimeStore.commit("CREATE_TAB", params));
129
+ return true;
130
+ }
101
131
  return activateMenu(menu.ID, {}, { syncUrl: false });
102
132
  }
103
133
  function activateHome() {
@@ -117,16 +147,16 @@ const nav = {
117
147
  }
118
148
  return activateMenu(menu.ID, {}, { syncUrl: true, replaceUrl: replace, query });
119
149
  },
120
- /** 生成某菜单的可分享 URL(含 /m/:key,不含 role——打开者用自己的角色) */
150
+ /** 生成包含菜单 ID 的分享地址;角色由打开者自己的登录上下文恢复。 */
121
151
  menuUrl(keyOrId, query) {
122
152
  const menu = findMenuByKey(runtimeStore.state.config.appMenus || [], String(keyOrId));
123
153
  if (!menu) return "";
124
- const loc = menuLocation(runtimeRouter.currentRoute.value, getMenuKey(menu), query);
154
+ const loc = menuLocation(runtimeRouter.currentRoute.value, menu.ID, query);
125
155
  return window.location.origin + window.location.pathname + runtimeRouter.resolve(loc).href;
126
156
  },
127
157
  /** 当前 URL 上的菜单键(无则 '') */
128
158
  currentMenuKey() {
129
- return (runtimeRouter.currentRoute.value.params || {}).menuKey || "";
159
+ return getRouteMenuKey(runtimeRouter.currentRoute.value);
130
160
  },
131
161
  getMenuKey,
132
162
  findMenuByKey,
@@ -144,6 +174,7 @@ export {
144
174
  findMenuByKey,
145
175
  findMenuPath,
146
176
  getMenuKey,
177
+ getRouteMenuKey,
147
178
  menuLocation,
148
179
  nav,
149
180
  resolveRouteRole,
@@ -14,18 +14,19 @@ import I18n from "./plugins/i18n.js";
14
14
  import installElementPlus from "./plugins/element-plus.js";
15
15
  import { setApp } from "./app.js";
16
16
  import { configureRuntime } from "./runtime-services.js";
17
+ import routeComponents from "./route-components.js";
17
18
  import { installGlobalMethods } from "./mixins/methods-to-prototype.js";
18
19
  import optimizedGlobalMixin from "./mixins/optimized-global.js";
19
20
  import loadComponentFactory from "./loadComponent.js";
20
21
  import nav from "./navigation.js";
21
- /* empty css */
22
+ /* empty css */
22
23
  import "element-plus/theme-chalk/dark/css-vars.css";
23
24
  const installed = /* @__PURE__ */ new WeakMap();
24
25
  function installCore(app, options = {}) {
25
26
  if (installed.has(app)) return installed.get(app);
26
27
  const { store, router, http = client, plugins = [], components = {} } = options;
27
28
  if (!store || !router) throw new TypeError("[epx/core] install 需要 store 和 router;可用 createFrameStore() 创建框架 store");
28
- configureRuntime({ ...options, http });
29
+ configureRuntime({ ...options, http, routeComponents: { ...routeComponents, ...options.routeComponents } });
29
30
  setApp(app);
30
31
  window.store = store;
31
32
  window.router = router;
@@ -7,8 +7,8 @@ import { ElMessageBox } from "element-plus/es/components/message-box/index.mjs";
7
7
  import { ElLoadingDirective, ElLoading } from "element-plus/es/components/loading/index.mjs";
8
8
  import { ElNotification } from "element-plus/es/components/notification/index.mjs";
9
9
  import { ElInfiniteScroll } from "element-plus/es/components/infinite-scroll/index.mjs";
10
- import zh_cn_default from "../../_vendor/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/zh-cn.js";
11
- import en_default from "../../_vendor/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/en.js";
10
+ import zh_cn_default from "../../frontend/frame/_vendor/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/zh-cn.js";
11
+ import en_default from "../../frontend/frame/_vendor/.pnpm/element-plus@2.14.3_vue@3.5.39_typescript@5.9.3_/_vendor/element-plus/dist/locale/en.js";
12
12
  import { ElAvatar } from "element-plus/es/components/avatar/index.mjs";
13
13
  import { ElButton } from "element-plus/es/components/button/index.mjs";
14
14
  import { ElCard } from "element-plus/es/components/card/index.mjs";
@@ -27,12 +27,12 @@ import { ElTabs, ElTabPane } from "element-plus/es/components/tabs/index.mjs";
27
27
  import { ElCheckbox } from "element-plus/es/components/checkbox/index.mjs";
28
28
  import { ElIcon } from "element-plus/es/components/icon/index.mjs";
29
29
  import "element-plus/dist/index.css";
30
- /* empty css */
31
- /* empty css */
32
- /* empty css */
33
- /* empty css */
34
- import epLazy from "../element-plus.lazy.js";
35
- import iconNames from "../element-icons.names.js";
30
+ /* empty css */
31
+ /* empty css */
32
+ /* empty css */
33
+ /* empty css */
34
+ import epLazy from "../../.cache/route-chart-release/frontend/frame/src/element-plus.lazy.js";
35
+ import iconNames from "../../.cache/route-chart-release/frontend/frame/src/element-icons.names.js";
36
36
  const EN_LOCALE_CODES = /* @__PURE__ */ new Set(["011", "en", "en-us"]);
37
37
  function elementPlusLocale(lang) {
38
38
  return EN_LOCALE_CODES.has(String(lang || "").toLowerCase()) ? en_default : zh_cn_default;
@@ -14,7 +14,8 @@ import { createFrameRouter, default as default11 } from "./router/public.js";
14
14
  import { createEventBus, getEventBus } from "./vue.bus.js";
15
15
  import { getApp, registerComponent, resolveComponent, setApp } from "./app.js";
16
16
  import { configureRuntime, registerRouteComponents } from "./runtime-services.js";
17
- import { default as default12 } from "./navigation.js";
17
+ import { default as default12 } from "./route-components.js";
18
+ import { default as default13 } from "./navigation.js";
18
19
  export {
19
20
  default2 as ComponentMixin,
20
21
  default8 as FieldFactory,
@@ -37,10 +38,11 @@ export {
37
38
  default6 as http,
38
39
  installCore,
39
40
  default4 as mixins,
40
- default12 as nav,
41
+ default13 as nav,
41
42
  registerComponent,
42
43
  registerRouteComponents,
43
44
  resolveComponent,
45
+ default12 as routeComponents,
44
46
  default11 as routerConfig,
45
47
  runExpByScope,
46
48
  setApp,
@@ -0,0 +1,9 @@
1
+ import '../style.css';
2
+ import App from "./views/App.js";
3
+ import Module from "./views/Module.js";
4
+ import AppRoleSelect from "./views/AppRoleSelect.js";
5
+ import Error from "./views/Error.js";
6
+ const routeComponents = { App, Module, AppRoleSelect, Error };
7
+ export {
8
+ routeComponents as default
9
+ };
@@ -1,4 +1,5 @@
1
1
  import '../../style.css';
2
+ import { restoreChatWikiRoute } from "@epxing/utils/src/wiki-path";
2
3
  import { runtimeRouteComponent, getRuntimeService, runtimeStore } from "../runtime-services.js";
3
4
  import { isEmpty } from "lodash-es";
4
5
  import util from "../runtime-utils/util.js";
@@ -10,7 +11,6 @@ import { setElementPlusLocale } from "../plugins/element-plus.js";
10
11
  import { MENU_ROUTE_ALIAS, roleStorage, effectiveRouteName } from "../menu-route.js";
11
12
  const Page = runtimeRouteComponent("Page");
12
13
  const Login = runtimeRouteComponent("Login");
13
- const QyWechat = runtimeRouteComponent("QyWechat");
14
14
  const App = runtimeRouteComponent("App");
15
15
  const WikiSitePage = runtimeRouteComponent("WikiSitePage");
16
16
  const Module = runtimeRouteComponent("Module");
@@ -239,9 +239,11 @@ const routes = [
239
239
  props: (route) => ({ query: route.query })
240
240
  },
241
241
  {
242
- path: "/system/:client/:system/:role?",
242
+ // 32 位菜单 ID 与旧角色编号消歧;旧的 /system/.../SYSTEM 地址仍可使用。
243
+ path: "/system/:client/:system/:menuKey([0-9A-Fa-f]{32})?/:role?",
243
244
  name: "system",
244
245
  component: App,
246
+ meta: { refresh: false },
245
247
  props: (route) => ({ query: route.query })
246
248
  },
247
249
  {
@@ -317,11 +319,6 @@ const routes = [
317
319
  component: App,
318
320
  props: (route) => ({ query: route.query })
319
321
  },
320
- {
321
- path: "/qywechat",
322
- name: "qywechat",
323
- component: QyWechat
324
- },
325
322
  {
326
323
  // 旧形态 /m/:menuKey 链接兼容:重定向到无 /m/ 的新形态
327
324
  path: "/app/:client/:system/:app/m/:menuKey",
@@ -344,6 +341,8 @@ const routes = [
344
341
  }
345
342
  ];
346
343
  const beforeEach = async (to, from, next) => {
344
+ const restoredWikiRoute = restoreChatWikiRoute(to);
345
+ if (restoredWikiRoute) return next(restoredWikiRoute);
347
346
  try {
348
347
  subscribeToLogout();
349
348
  return await runBeforeEach(to, from, next);
@@ -366,7 +365,7 @@ const runBeforeEach = async (to, from, rawNext) => {
366
365
  }
367
366
  return rawNext(location);
368
367
  };
369
- const isMenuRoute = !!MENU_ROUTE_ALIAS[to.name];
368
+ const isMenuRoute = !!MENU_ROUTE_ALIAS[to.name] || to.name === "system" && !!to.params.menuKey;
370
369
  if (isMenuRoute) {
371
370
  const storedRole = roleStorage.get(to.params.client, to.params.system);
372
371
  to = { ...to, name: effectiveRouteName(to.name), params: { ...to.params, role: to.params.role || storedRole || void 0 } };
@@ -34,7 +34,7 @@ function registerRouteComponents(components) {
34
34
  function runtimeRouteComponent(name) {
35
35
  return async () => {
36
36
  const component = routeComponents.get(name);
37
- if (!component) throw new Error(`[epx/core] 路由组件 ${name} 尚未注册,请安装 component/business 或传入 routeComponents`);
37
+ if (!component) throw new Error(`[epx/core] 路由组件 ${name} 尚未注册,请安装提供该页面的 components/business 包或传入 routeComponents`);
38
38
  return component;
39
39
  };
40
40
  }
@@ -1,5 +1,6 @@
1
1
  import '../../style.css';
2
2
  import util from "./util.js";
3
+ const appliedLanguage = /* @__PURE__ */ new WeakMap();
3
4
  class Meta {
4
5
  constructor(props = {}) {
5
6
  var me = this;
@@ -56,6 +57,8 @@ class Meta {
56
57
  }
57
58
  getAttributes() {
58
59
  const currentLanguage = util.getCurrentLanguage();
60
+ if (appliedLanguage.get(this) === currentLanguage) return this.attributes;
61
+ appliedLanguage.set(this, currentLanguage);
59
62
  for (const key in this.attributes) {
60
63
  const item = this.attributes[key];
61
64
  for (const key2 in item.languageMap) {