@pubinfo/core 2.0.0-beta.26 → 2.0.0-beta.28

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 (63) hide show
  1. package/dist/{AppSetting-DodCOb_z.js → AppSetting-DMJZXmzA.js} +21 -20
  2. package/dist/{HCheckList.vue_vue_type_script_setup_true_lang-CMOw56Mk.js → HCheckList.vue_vue_type_script_setup_true_lang-B3wESRn7.js} +2 -2
  3. package/dist/{PreferencesContent-Dic24ifo.js → PreferencesContent-BniiAnvk.js} +117 -113
  4. package/dist/{SettingBreadcrumb-DWpbGcSy.js → SettingBreadcrumb-C4f3EHvJ.js} +2 -2
  5. package/dist/{SettingCopyright-CIY0pFMT.js → SettingCopyright-BfIv7JmX.js} +1 -1
  6. package/dist/{SettingEnableTransition-f0xuLIrZ.js → SettingEnableTransition-ltxmSAel.js} +1 -1
  7. package/dist/{SettingHome-BFtJsJsN.js → SettingHome-D3YO-Jml.js} +1 -1
  8. package/dist/{SettingMenu-DuPD3iSG.js → SettingMenu-BFPc8wk1.js} +2 -2
  9. package/dist/{SettingMode-nZ65qSWK.js → SettingMode-FWqs1ki-.js} +1 -1
  10. package/dist/{SettingNavSearch-CrarPE7d.js → SettingNavSearch-CNH2GsIA.js} +1 -1
  11. package/dist/{SettingOther-BddvExCF.js → SettingOther-DeKEcGIY.js} +1 -1
  12. package/dist/{SettingPage-C6Na8HEN.js → SettingPage-CvRmxfR7.js} +1 -1
  13. package/dist/{SettingTabbar-nuwfRRaE.js → SettingTabbar-C7I7s-0s.js} +2 -2
  14. package/dist/SettingThemes-DzQ2YBRN.js +145 -0
  15. package/dist/{SettingToolbar-BdizZaGF.js → SettingToolbar-BPj0XLJ3.js} +1 -1
  16. package/dist/{SettingTopbar-D5BX5vS_.js → SettingTopbar-DVlc3dq-.js} +2 -2
  17. package/dist/{SettingWidthMode-CHrLW3gs.js → SettingWidthMode-BzNU65dj.js} +1 -1
  18. package/dist/{TopThinMode-CttqTmaT.js → TopThinMode-DSO5USf6.js} +1 -1
  19. package/dist/{_...all_--d4S-8dL.js → _...all_-6l5FWUkL.js} +1 -1
  20. package/dist/{colors-BOKDjZQI.js → colors-DiWJrScm.js} +1 -1
  21. package/dist/components/PubinfoIcon/register.d.ts +9 -0
  22. package/dist/{index-Cygbc-66.js → index-Be7jJtXg.js} +33 -31
  23. package/dist/{index-CC3GE307.js → index-BmMbAV1Y.js} +34 -30
  24. package/dist/{index-D0CMv5FJ.js → index-CXsL0aQN.js} +5618 -5248
  25. package/dist/{index-B0i20hau.js → index-CfasTv4x.js} +6 -6
  26. package/dist/{index-Bz9lh14R.js → index-Ckgil96Y.js} +30 -30
  27. package/dist/{index-DltN2SCZ.js → index-De_ME_Ws.js} +2 -2
  28. package/dist/{index-dPREgrj8.js → index-Md7zV10q.js} +12 -12
  29. package/dist/{index-DORROKh7.js → index-XnF26Tbt.js} +3 -3
  30. package/dist/{index-Cf8yM5Cv.js → index-bsi-FZDt.js} +11 -9
  31. package/dist/index.js +33 -32
  32. package/dist/{index.vue_vue_type_style_index_0_scoped_fa1c6ee4_lang-Bmtn9Oo4.js → index.vue_vue_type_style_index_0_scoped_fa1c6ee4_lang-B3Eieo0k.js} +315 -297
  33. package/dist/interface.d.ts +2 -0
  34. package/dist/layout/Layout.vue.d.ts +2 -2
  35. package/dist/{menu-Ddxel9ck.js → menu-CC5544p-.js} +3202 -3184
  36. package/dist/{pick-DEgsMKda.js → pick-CJo2YiT-.js} +1 -1
  37. package/dist/request.js +399 -390
  38. package/dist/route/routes.d.ts +6 -4
  39. package/dist/style.css +2 -2
  40. package/dist/utils/index.d.ts +6 -0
  41. package/package.json +26 -26
  42. package/src/api/modules/configData/xitongpeizhifuwu.ts +3 -3
  43. package/src/components/PubinfoApp/index.vue +1 -1
  44. package/src/components/PubinfoIcon/index.vue +3 -1
  45. package/src/components/PubinfoIcon/register.ts +19 -0
  46. package/src/components/PubinfoProvider/index.ts +1 -2
  47. package/src/create.ts +7 -0
  48. package/src/interface.ts +2 -0
  49. package/src/layout/Layout.vue +50 -59
  50. package/src/layout/components/Content/index.vue +34 -13
  51. package/src/layout/components/SettingBar/components/SettingThemes.vue +7 -5
  52. package/src/layout/components/Sidebar/MainSidebar.vue +4 -7
  53. package/src/layout/components/Tools/Preferences/PreferencesContent.vue +2 -1
  54. package/src/layout/components/Tools/index.vue +1 -8
  55. package/src/layout/provider.ts +7 -1
  56. package/src/pages/system/not-permission/index.vue +2 -2
  57. package/src/route/routes.ts +26 -8
  58. package/src/stores/modules/route.ts +10 -2
  59. package/src/utils/index.ts +14 -0
  60. package/types/vue-router.d.ts +3 -1
  61. package/dist/SettingThemes-DBq6j0zt.js +0 -144
  62. package/src/layout/components/Tools/I18nSelector.vue +0 -52
  63. package/src/pages/system/change-password/page.vue +0 -58
@@ -5,6 +5,12 @@ type ConditionalExceptType<T extends Record<PropertyKey, any>, Type> = {
5
5
  export declare function resolveRoutePath(basePath?: string, routePath?: string): string;
6
6
  export declare function normalizePrimitiveToFunction<T extends Record<PropertyKey, any>>(options: T): ConditionalExceptType<T, Primitive>;
7
7
  export declare function objectToPaths(obj: Record<string, any>, prefix?: string): string[];
8
+ /**
9
+ * 基于 `import.meta.glob` 读取 `iconMap`
10
+ */
11
+ export declare function loadIconsFromGlob(modules: Record<string, {
12
+ default: string;
13
+ }>): Record<string, string>;
8
14
  export * from './cleanup';
9
15
  export * from './crypto';
10
16
  export { default as eventBus } from './eventBus';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pubinfo/core",
3
3
  "type": "module",
4
- "version": "2.0.0-beta.26",
4
+ "version": "2.0.0-beta.28",
5
5
  "exports": {
6
6
  ".": {
7
7
  "types": "./dist/index.d.ts",
@@ -23,34 +23,34 @@
23
23
  "types"
24
24
  ],
25
25
  "peerDependencies": {
26
- "alova": "^3.2.10",
26
+ "alova": "^3.2.13",
27
27
  "pinia": "^2.3.1",
28
- "vue": "^3.5.13",
29
- "vue-i18n": "^10.0.5",
30
- "vue-router": "^4.5.0",
31
- "@pubinfo/config": "2.0.0-beta.26"
28
+ "vue": "^3.5.16",
29
+ "vue-i18n": "^10.0.7",
30
+ "vue-router": "^4.5.1",
31
+ "@pubinfo/config": "2.0.0-beta.28"
32
32
  },
33
33
  "dependencies": {
34
- "@alova/adapter-axios": "^2.0.13",
34
+ "@alova/adapter-axios": "^2.0.14",
35
35
  "@ant-design/icons-vue": "^7.0.1",
36
36
  "@headlessui/vue": "^1.7.23",
37
- "@imengyu/vue3-context-menu": "^1.4.4",
38
- "@pubinfo/pro-components": "^1.7.0",
37
+ "@imengyu/vue3-context-menu": "^1.5.0",
38
+ "@pubinfo/pro-components": "^1.7.1",
39
39
  "@unocss/reset": "^65.5.0",
40
- "@vueuse/core": "^13.0.0",
41
- "@vueuse/integrations": "^13.0.0",
40
+ "@vueuse/core": "^13.3.0",
41
+ "@vueuse/integrations": "^13.3.0",
42
42
  "ant-design-vue": "^4.2.6",
43
- "axios": "^1.8.1",
44
- "consola": "^3.4.0",
43
+ "axios": "^1.9.0",
44
+ "consola": "^3.4.2",
45
45
  "floating-vue": "5.2.2",
46
46
  "hookable": "^5.5.3",
47
- "hotkeys-js": "^3.13.9",
47
+ "hotkeys-js": "^3.13.10",
48
48
  "jsencrypt": "^3.3.2",
49
49
  "lodash-es": "^4.17.21",
50
50
  "md5": "^2.3.0",
51
51
  "mitt": "^3.0.1",
52
52
  "nprogress": "^0.2.0",
53
- "overlayscrollbars": "^2.11.1",
53
+ "overlayscrollbars": "^2.11.3",
54
54
  "overlayscrollbars-vue": "^0.5.9",
55
55
  "path-browserify": "^1.0.1",
56
56
  "path-to-regexp": "^6.3.0",
@@ -60,7 +60,7 @@
60
60
  "zxcvbn": "^4.4.2"
61
61
  },
62
62
  "devDependencies": {
63
- "@iconify/json": "^2.2.312",
63
+ "@iconify/json": "^2.2.343",
64
64
  "@iconify/vue": "^4.3.0",
65
65
  "@pubinfo/openapi": "^0.8.4",
66
66
  "@pubinfo/preset-openapi": "^0.8.4",
@@ -70,22 +70,22 @@
70
70
  "@types/path-browserify": "^1.0.3",
71
71
  "@types/sortablejs": "^1.15.8",
72
72
  "@types/zxcvbn": "^4.4.5",
73
- "@vitejs/plugin-vue": "^5.2.1",
74
- "@vitejs/plugin-vue-jsx": "^4.1.1",
75
- "alova": "^3.2.10",
73
+ "@vitejs/plugin-vue": "^5.2.4",
74
+ "@vitejs/plugin-vue-jsx": "^4.2.0",
75
+ "alova": "^3.2.13",
76
76
  "pinia": "^2.3.1",
77
77
  "sass": "1.83.0",
78
- "type-fest": "^4.36.0",
78
+ "type-fest": "^4.41.0",
79
79
  "unocss": "^65.5.0",
80
80
  "unplugin-auto-import": "^0.18.6",
81
81
  "unplugin-icons": "^0.22.0",
82
82
  "unplugin-vue-components": "^0.27.5",
83
- "vite": "^6.2.0",
84
- "vite-plugin-dts": "^4.5.3",
85
- "vue": "^3.5.13",
86
- "vue-i18n": "^10.0.5",
87
- "vue-router": "^4.5.0",
88
- "@pubinfo/config": "2.0.0-beta.26"
83
+ "vite": "^6.3.5",
84
+ "vite-plugin-dts": "^4.5.4",
85
+ "vue": "^3.5.16",
86
+ "vue-i18n": "^10.0.7",
87
+ "vue-router": "^4.5.1",
88
+ "@pubinfo/config": "2.0.0-beta.28"
89
89
  },
90
90
  "scripts": {
91
91
  "dev": "vite build -w -m watch",
@@ -63,7 +63,7 @@ export function postSysconfigAddOrUpdateBackgroundImage<
63
63
  if (item !== undefined && item !== null) {
64
64
  if (typeof item === 'object' && !(item instanceof File)) {
65
65
  if (Array.isArray(item)) {
66
- item.forEach((f) => formData.append(ele, f || ''));
66
+ item.forEach(f => formData.append(ele, f || ''));
67
67
  }
68
68
  else {
69
69
  formData.append(ele, JSON.stringify(item));
@@ -110,7 +110,7 @@ export function postSysconfigAddOrUpdateBackgroundSmallImage<
110
110
  if (item !== undefined && item !== null) {
111
111
  if (typeof item === 'object' && !(item instanceof File)) {
112
112
  if (Array.isArray(item)) {
113
- item.forEach((f) => formData.append(ele, f || ''));
113
+ item.forEach(f => formData.append(ele, f || ''));
114
114
  }
115
115
  else {
116
116
  formData.append(ele, JSON.stringify(item));
@@ -152,7 +152,7 @@ export function postSysconfigAddOrUpdateLogImage<
152
152
  if (item !== undefined && item !== null) {
153
153
  if (typeof item === 'object' && !(item instanceof File)) {
154
154
  if (Array.isArray(item)) {
155
- item.forEach((f) => formData.append(ele, f || ''));
155
+ item.forEach(f => formData.append(ele, f || ''));
156
156
  }
157
157
  else {
158
158
  formData.append(ele, JSON.stringify(item));
@@ -9,7 +9,7 @@ const route = useRoute();
9
9
  const { auth } = useAuth();
10
10
 
11
11
  const isAuth = computed(() => {
12
- return route.matched.every((item) => auth(item.meta.auth ?? ''));
12
+ return route.matched.every(item => auth(item.meta.auth ?? ''));
13
13
  });
14
14
  </script>
15
15
 
@@ -1,6 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import { Icon } from '@iconify/vue';
3
3
  import { useProvider } from '../PubinfoProvider';
4
+ import { iconRegistry } from './register';
4
5
 
5
6
  defineOptions({
6
7
  name: 'PubinfoIcon',
@@ -72,7 +73,8 @@ function _loadIcon() {
72
73
  if (!loadIcon && outputType.value === 'custom') {
73
74
  return new Error('Need pro `loadIcon`, according to [PubinfoProvider].');
74
75
  }
75
- return loadIcon?.(props.name);
76
+
77
+ return loadIcon?.(props.name) ?? iconRegistry.get(props.name);
76
78
  }
77
79
  </script>
78
80
 
@@ -0,0 +1,19 @@
1
+ type IconMap = Record<string, string>;
2
+
3
+ export class IconRegistry {
4
+ private iconMap: IconMap = {};
5
+
6
+ register(icons: IconMap) {
7
+ this.iconMap = { ...this.iconMap, ...icons };
8
+ }
9
+
10
+ get(name: string): string | undefined {
11
+ return this.iconMap[name];
12
+ }
13
+
14
+ getAll(): IconMap {
15
+ return this.iconMap;
16
+ }
17
+ }
18
+
19
+ export const iconRegistry = new IconRegistry();
@@ -19,7 +19,6 @@ export default defineComponent({
19
19
  props: {
20
20
  loadIcon: {
21
21
  type: Function as PubinfoProviderProps['loadIcon'],
22
- required: true,
23
22
  },
24
23
  },
25
24
  setup(props, { slots }) {
@@ -27,7 +26,7 @@ export default defineComponent({
27
26
 
28
27
  createPubinfoProvider({
29
28
  loadIcon(name) {
30
- return props.loadIcon(name) ?? provider?.loadIcon?.(name);
29
+ return props?.loadIcon?.(name) ?? provider?.loadIcon?.(name);
31
30
  },
32
31
  });
33
32
 
package/src/create.ts CHANGED
@@ -6,6 +6,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
6
6
 
7
7
  import { GetAPIValidateIp } from './api/system/app';
8
8
 
9
+ import { iconRegistry } from './components/PubinfoIcon/register';
9
10
  import { createPubinfoContext, hooks } from './context';
10
11
  import { setupDirectives } from './directives';
11
12
  import { setupLayout } from './layout';
@@ -13,6 +14,7 @@ import { setupI18n } from './locales';
13
14
  import { extractModules, resolveModules } from './modules';
14
15
  import { constantRoutes, setupRouterGuard } from './route';
15
16
  import { setupStore } from './stores';
17
+ import { loadIconsFromGlob } from './utils';
16
18
 
17
19
  export function createPubinfo(
18
20
  App: Component,
@@ -45,6 +47,7 @@ export function createPubinfo(
45
47
  app,
46
48
  store,
47
49
  router,
50
+ iconRegistry,
48
51
  };
49
52
 
50
53
  app.use(store);
@@ -80,6 +83,10 @@ export function createPubinfo(
80
83
  }
81
84
 
82
85
  function setupBasic(context: Context) {
86
+ // register icons
87
+ const iconMap = loadIconsFromGlob(import.meta.glob('./assets/icons/*.svg', { eager: true }));
88
+ context.iconRegistry.register(iconMap);
89
+
83
90
  setupStore(context);
84
91
  setupRouterGuard(context);
85
92
  setupDirectives(context);
package/src/interface.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Pinia } from 'pinia';
2
2
  import type { App } from 'vue';
3
3
  import type { Router, RouterOptions as VueRouterOptions } from 'vue-router';
4
+ import type { IconRegistry } from './components/PubinfoIcon/register';
4
5
 
5
6
  type PartialKeys<T, Keys extends keyof T> = Omit<T, Keys> & Partial<Pick<T, Keys>>;
6
7
 
@@ -10,6 +11,7 @@ export interface Context {
10
11
  app: App<Element>
11
12
  store: Pinia
12
13
  router: Router
14
+ iconRegistry: IconRegistry
13
15
  }
14
16
 
15
17
  export interface Options {
@@ -1,5 +1,4 @@
1
1
  <script setup lang="ts">
2
- import { PubinfoProvider } from '@/components';
3
2
  import RiLogoutBoxLine from '~icons/ri/logout-box-line';
4
3
  import BackTop from './components/BackTop/index.vue';
5
4
  import LayoutContent from './components/Content/index.vue';
@@ -49,78 +48,70 @@ watch(() => routeInfo.path, () => {
49
48
  });
50
49
  }
51
50
  });
52
-
53
- function loadIcon(name: string) {
54
- const modules = (import.meta as any).glob('../assets/icons/*', { eager: true });
55
- const path = `../assets/icons/${name}.svg`;
56
- return modules[path]?.default;
57
- }
58
51
  </script>
59
52
 
60
53
  <template>
61
- <PubinfoProvider :load-icon="loadIcon">
62
- <div
63
- class="layout"
64
- :style="{
65
- '--g-main-sidebar-actual-width': mainSidebarActualWidth,
66
- '--g-sub-sidebar-actual-width': subSidebarActualWidth,
67
- }"
68
- >
69
- <div id="app-main" :class="{ 'main-page-maximize': settingsStore.mainPageMaximizeStatus }">
70
- <slot name="header">
71
- <LayoutHeader />
72
- </slot>
73
-
74
- <div class="wrapper">
75
- <div
76
- class="sidebar-container"
77
- :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }"
78
- >
79
- <!-- TODO 这种写法会导致侧边栏模式的布局下,有样式问题 -->
80
- <!-- <slot name="sidebar">
54
+ <div
55
+ class="layout"
56
+ :style="{
57
+ '--g-main-sidebar-actual-width': mainSidebarActualWidth,
58
+ '--g-sub-sidebar-actual-width': subSidebarActualWidth,
59
+ }"
60
+ >
61
+ <div id="app-main" :class="{ 'main-page-maximize': settingsStore.mainPageMaximizeStatus }">
62
+ <slot name="header">
63
+ <LayoutHeader />
64
+ </slot>
65
+
66
+ <div class="wrapper">
67
+ <div
68
+ class="sidebar-container"
69
+ :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }"
70
+ >
71
+ <!-- TODO 这种写法会导致侧边栏模式的布局下,有样式问题 -->
72
+ <!-- <slot name="sidebar">
81
73
  <Sidebar />
82
74
  </slot> -->
83
75
 
84
- <MainSidebar />
85
- <SubSidebar />
86
- </div>
87
-
88
- <div
89
- class="sidebar-mask"
90
- :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }"
91
- @click="settingsStore.toggleSidebarCollapse()"
92
- />
93
-
94
- <div class="main-container" :style="{ 'padding-bottom': routeInfo.meta.paddingBottom }">
95
- <slot name="topbar">
96
- <Topbar />
97
- </slot>
76
+ <MainSidebar />
77
+ <SubSidebar />
78
+ </div>
98
79
 
99
- <div class="main">
100
- <div
101
- v-show="settingsStore.mainPageMaximizeStatus"
102
- class="exit-main-page-maximize"
103
- @click="settingsStore.setMainPageMaximize()"
104
- >
105
- <RiLogoutBoxLine />
106
- </div>
107
-
108
- <slot>
109
- <LayoutContent />
110
- </slot>
80
+ <div
81
+ class="sidebar-mask"
82
+ :class="{ show: settingsStore.mode === 'mobile' && !settingsStore.settings.menu.subMenuCollapse }"
83
+ @click="settingsStore.toggleSidebarCollapse()"
84
+ />
85
+
86
+ <div class="main-container" :style="{ 'padding-bottom': routeInfo.meta.paddingBottom }">
87
+ <slot name="topbar">
88
+ <Topbar />
89
+ </slot>
90
+
91
+ <div class="main">
92
+ <div
93
+ v-show="settingsStore.mainPageMaximizeStatus"
94
+ class="exit-main-page-maximize"
95
+ @click="settingsStore.setMainPageMaximize()"
96
+ >
97
+ <RiLogoutBoxLine />
111
98
  </div>
112
99
 
113
- <slot name="footer">
114
- <Copyright />
100
+ <slot>
101
+ <LayoutContent />
115
102
  </slot>
116
103
  </div>
104
+
105
+ <slot name="footer">
106
+ <Copyright />
107
+ </slot>
117
108
  </div>
118
109
  </div>
119
-
120
- <SettingBar />
121
- <BackTop />
122
110
  </div>
123
- </PubinfoProvider>
111
+
112
+ <SettingBar />
113
+ <BackTop />
114
+ </div>
124
115
  </template>
125
116
 
126
117
  <style lang="scss" scoped>
@@ -7,25 +7,46 @@ defineOptions({
7
7
  name: 'LayoutContent',
8
8
  });
9
9
 
10
- const routeInfo = useRoute();
10
+ const _route = useRoute();
11
11
  const { settingsStore, keepAliveStore } = useContext();
12
12
 
13
- const isIframe = computed(() => !!routeInfo.meta.iframe);
14
- const isLink = computed(() => !!routeInfo.meta.link);
13
+ const isIframe = computed(() => !!_route.meta.iframe);
14
+ const isLink = computed(() => !!_route.meta.link);
15
+
16
+ function EmptyWrapper(_: any, { slots }: { slots: any }) {
17
+ return slots?.default?.();
18
+ }
19
+
20
+ const Provider = computed(() => {
21
+ const metaProvider = _route.matched?.[0]?.meta?.provider;
22
+
23
+ if (!metaProvider) {
24
+ return EmptyWrapper;
25
+ };
26
+
27
+ // 是函数,认为是 () => import(...)
28
+ if (typeof metaProvider === 'function') {
29
+ return defineAsyncComponent(metaProvider);
30
+ }
31
+
32
+ return metaProvider;
33
+ });
15
34
  </script>
16
35
 
17
36
  <template>
18
37
  <RouterView v-slot="{ Component, route }">
19
- <Transition :name="settingsStore.settings.mainPage.enableTransition ? settingsStore.settings.mainPage.transitionMode : ''" mode="out-in" appear>
20
- <KeepAlive :include="keepAliveStore.list">
21
- <component
22
- :is="Component"
23
- v-show="!(isIframe || isLink)"
24
- :key="route.fullPath"
25
- class="page-container"
26
- />
27
- </KeepAlive>
28
- </Transition>
38
+ <component :is="Provider">
39
+ <Transition :name="settingsStore.settings.mainPage.enableTransition ? settingsStore.settings.mainPage.transitionMode : ''" mode="out-in" appear>
40
+ <KeepAlive :include="keepAliveStore.list">
41
+ <component
42
+ :is="Component"
43
+ v-show="!(isIframe || isLink)"
44
+ :key="route.fullPath"
45
+ class="page-container"
46
+ />
47
+ </KeepAlive>
48
+ </Transition>
49
+ </component>
29
50
  </RouterView>
30
51
 
31
52
  <IframeView v-show="isIframe && !isLink" />
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
2
  import type { colorScheme, cssVarKey } from '@pubinfo/config/themes';
3
3
  import { useTheme } from '@/composables';
4
- import { themes } from '@pubinfo/config/themes';
4
+ import { getThemes } from '@pubinfo/config/themes';
5
5
  import JamBookmarkF from '~icons/jam/bookmark-f';
6
6
  import PajamasCheckCircleFilled from '~icons/pajamas/check-circle-filled';
7
7
  import { useContext } from '../../../composables/useContext';
@@ -30,8 +30,10 @@ const benchmark: cssVarKey[] = [
30
30
  '--g-sub-sidebar-bg',
31
31
  ];
32
32
 
33
- const themeList = computed<ThemeListCard[]>(() =>
34
- Object.keys(themes).map((key) => {
33
+ const themeList = computed<ThemeListCard[]>(() => {
34
+ const themes = getThemes();
35
+
36
+ return Object.keys(themes).map((key) => {
35
37
  const value = themes[key];
36
38
  const colors = benchmark.map((cssVar) => {
37
39
  const cssValue = value[cssVar].startsWith('#')
@@ -48,8 +50,8 @@ const themeList = computed<ThemeListCard[]>(() =>
48
50
  };
49
51
  }).filter(cssVarScheme =>
50
52
  cssVarScheme.value['color-scheme'] === app.value.colorScheme,
51
- ),
52
- );
53
+ );
54
+ });
53
55
 
54
56
  function clickHandle(item: ThemeListCard) {
55
57
  const label = item.label;
@@ -15,14 +15,11 @@ const { settingsStore, menuStore, generateI18nTitle } = useContext();
15
15
  const { switchTo } = useMenu();
16
16
 
17
17
  function iconName(isActive: boolean, icon?: string, activeIcon?: string) {
18
- let name;
19
- if ((!isActive && icon) || (isActive && !activeIcon)) {
20
- name = icon;
18
+ if (isActive && activeIcon) {
19
+ return activeIcon;
21
20
  }
22
- else if (isActive && activeIcon) {
23
- name = activeIcon;
24
- }
25
- return name;
21
+
22
+ return icon;
26
23
  }
27
24
  </script>
28
25
 
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { themes } from '@pubinfo/config/themes';
2
+ import { getThemes } from '@pubinfo/config/themes';
3
3
  import { message } from 'ant-design-vue';
4
4
  import { cloneDeep, pick } from 'lodash-es';
5
5
  import EpBack from '~icons/ep/back';
@@ -92,6 +92,7 @@ const isDark = computed({
92
92
  });
93
93
 
94
94
  const themeList = computed(() => {
95
+ const themes = getThemes();
95
96
  return Object.keys(themes).map((key) => {
96
97
  return {
97
98
  label: key,
@@ -8,14 +8,12 @@ import FluentFullScreenMinimize16Filled from '~icons/fluent/full-screen-minimize
8
8
  import IconamoonSearch from '~icons/iconamoon/search';
9
9
  import MaterialSymbolsExpandMoreRounded from '~icons/material-symbols/expand-more-rounded';
10
10
  import PhLineVerticalThin from '~icons/ph/line-vertical-thin';
11
- // import RiTranslate from '~icons/ri/translate';
12
11
 
13
12
  import { useContext } from '../../composables/useContext';
14
13
  import useMainPage from '../../composables/useMainPage';
15
14
  import useViewTransition from '../../composables/useViewTransition';
16
15
  import DayNightSwitch from './DayNightSwitch.vue';
17
16
  import HotkeysIntro from './HotkeysIntro.vue';
18
- // import I18nSelector from './I18nSelector.vue';
19
17
  import Preferences from './Preferences/index.vue';
20
18
  import Search from './Search.vue';
21
19
 
@@ -71,9 +69,7 @@ const userMenu = computed(() => [
71
69
  {
72
70
  label: t('route.personal.profile'),
73
71
  icon: 'i-iconamoon-profile-duotone',
74
- handle: () => router.push({
75
- name: 'Profile',
76
- }),
72
+ handle: () => router.push({ name: 'Profile' }),
77
73
  },
78
74
  {
79
75
  label: t('app.changePassword'),
@@ -172,9 +168,6 @@ const searchComponentsClass = computed(() => {
172
168
  >
173
169
  <IconamoonSearch text="14px" />
174
170
  </span>
175
- <!-- <I18nSelector class="item">
176
- <RiTranslate text="15px" />
177
- </I18nSelector> -->
178
171
  <span
179
172
  v-if="settingsStore.mode === 'pc' && settingsStore.settings.toolbar.enableFullscreen"
180
173
  class="item"
@@ -1,3 +1,4 @@
1
+ import { PubinfoProvider } from '@/components';
1
2
  import {
2
3
  useFavoritesStore,
3
4
  useIframeStore,
@@ -8,6 +9,7 @@ import {
8
9
  useTabbarStore,
9
10
  useUserStore,
10
11
  } from '@/stores';
12
+ import { h } from 'vue';
11
13
  import { createContext } from './composables/useContext';
12
14
  import { useTitle } from './composables/useTitle';
13
15
 
@@ -53,6 +55,10 @@ export const Provider = defineComponent({
53
55
  generateI18nTitle,
54
56
  });
55
57
 
56
- return () => slots?.default?.();
58
+ return () => h(
59
+ PubinfoProvider,
60
+ {},
61
+ () => slots?.default?.(),
62
+ );
57
63
  },
58
64
  });
@@ -31,8 +31,8 @@ onMounted(() => {
31
31
  }, 1000);
32
32
  });
33
33
 
34
- async function goBack() {
35
- await userStore.logout();
34
+ function goBack() {
35
+ userStore.logout();
36
36
  router.push({
37
37
  name: 'login',
38
38
  });
@@ -4,13 +4,26 @@ import { readProject } from '@/context';
4
4
  import { useSettingsStore, useUserStore } from '@/stores';
5
5
  import { isUndefined } from 'lodash-es';
6
6
 
7
- let asyncRoutes: Route.recordMainRaw[] = [];
7
+ interface AsyncRoutesOptions {
8
+ /** 路由排序 */
9
+ sort?: number
10
+ }
11
+
12
+ interface RawAsyncRoute extends Required<AsyncRoutesOptions> {
13
+ routes: Route.recordMainRaw[]
14
+ }
15
+
16
+ // #region --- 动态路由
17
+ const rawAsyncRoutes: RawAsyncRoute[] = [];
8
18
 
9
19
  /**
10
20
  * 定义并注册动态路由
11
21
  */
12
- export function defineAsyncRoutes(routes: Route.recordMainRaw[]) {
13
- asyncRoutes = [...asyncRoutes, ...routes];
22
+ export function defineAsyncRoutes(routes: Route.recordMainRaw[], options?: AsyncRoutesOptions) {
23
+ rawAsyncRoutes.push({
24
+ routes,
25
+ sort: options?.sort ?? 0,
26
+ });
14
27
  return routes;
15
28
  }
16
29
 
@@ -18,9 +31,14 @@ export function defineAsyncRoutes(routes: Route.recordMainRaw[]) {
18
31
  * 读取注册的动态路由
19
32
  */
20
33
  export function getAsyncRoutes() {
21
- return asyncRoutes;
34
+ return rawAsyncRoutes
35
+ .sort((a, b) => a?.sort - b?.sort)
36
+ .map(e => e.routes)
37
+ .flat();
22
38
  }
39
+ // #endregion
23
40
 
41
+ // #region --- 系统路由
24
42
  const systemRoutes: RouteRecordRaw[] = [
25
43
  {
26
44
  path: '/',
@@ -57,7 +75,7 @@ const systemRoutes: RouteRecordRaw[] = [
57
75
  * 定义并注册系统路由(含Layout)
58
76
  */
59
77
  export function defineSystemRoutes(routes: RouteRecordRaw[]) {
60
- systemRoutes[0].children = [...(systemRoutes?.[0]?.children ?? []), ...routes];
78
+ systemRoutes[0].children?.push(...routes);
61
79
  }
62
80
 
63
81
  /**
@@ -66,10 +84,9 @@ export function defineSystemRoutes(routes: RouteRecordRaw[]) {
66
84
  export function getSystemRoutes() {
67
85
  return systemRoutes;
68
86
  }
87
+ // #endregion
69
88
 
70
- /**
71
- * 内置静态路由
72
- */
89
+ // #region --- 静态路由
73
90
  export const constantRoutes: RouteRecordRaw[] = [
74
91
  {
75
92
  path: '/change-password/:changePassWordToken',
@@ -122,3 +139,4 @@ export const constantRoutes: RouteRecordRaw[] = [
122
139
  },
123
140
  },
124
141
  ];
142
+ // #endregion