-
-
-
-
-
+
+
+
-
<%= appTitle %>
+
<%= appTitle %>
+
+
diff --git a/public/resource/loading.css b/public/resource/loading.css
new file mode 100644
index 00000000..4f2a1bdb
--- /dev/null
+++ b/public/resource/loading.css
@@ -0,0 +1,91 @@
+.loading-container {
+ position: fixed;
+ left: 0;
+ top: 0;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+}
+
+.loading-svg {
+ width: 128px;
+ height: 128px;
+ color: var(--primary-color);
+}
+
+.loading-spin__container {
+ width: 56px;
+ height: 56px;
+ margin: 36px 0;
+}
+
+.loading-spin {
+ position: relative;
+ height: 100%;
+ animation: loadingSpin 1s linear infinite;
+}
+
+.left-0 {
+ left: 0;
+}
+.right-0 {
+ right: 0;
+}
+.top-0 {
+ top: 0;
+}
+.bottom-0 {
+ bottom: 0;
+}
+
+.loading-spin-item {
+ position: absolute;
+ height: 16px;
+ width: 16px;
+ background-color: var(--primary-color);
+ border-radius: 8px;
+ -webkit-animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+ animation: loadingPulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
+}
+
+@keyframes loadingSpin {
+ from {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+ to {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+
+@keyframes loadingPulse {
+ 0%, 100% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: .5;
+ }
+}
+
+.loading-delay-500 {
+ -webkit-animation-delay: 500ms;
+ animation-delay: 500ms;
+}
+.loading-delay-1000 {
+ -webkit-animation-delay: 1000ms;
+ animation-delay: 1000ms;
+}
+.loading-delay-1500 {
+ -webkit-animation-delay: 1500ms;
+ animation-delay: 1500ms;
+}
+
+.loading-title {
+ font-size: 28px;
+ font-weight: 500;
+ color: #646464;
+}
diff --git a/public/resource/loading.js b/public/resource/loading.js
new file mode 100644
index 00000000..6530ba41
--- /dev/null
+++ b/public/resource/loading.js
@@ -0,0 +1,44 @@
+/**
+ * 初始化加载效果的svg格式logo
+ * @param { string }id - 元素id
+ */
+function initSvgLogo(id) {
+ const svgStr = `
+`;
+ const appEl = document.querySelector(id);
+ const div = document.createElement('div');
+ div.innerHTML = svgStr;
+ if (appEl) {
+ appEl.appendChild(div);
+ }
+}
+
+function addThemeColorCssVars() {
+ const key = '__THEME_COLOR__';
+ const themeColor = '#1890ff';
+ const cssVars = window.localStorage.getItem(key) || `--primary-color: ${themeColor}`;
+ document.documentElement.style.cssText = cssVars;
+}
+
+initSvgLogo('#loadingLogo');
+
+addThemeColorCssVars();
diff --git a/src/App.vue b/src/App.vue
index 3675bcbd..609060c3 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,19 +1,24 @@
-
-
-
+
+
+
+
+
diff --git a/src/AppProvider.vue b/src/AppProvider.vue
deleted file mode 100644
index 8acec2bc..00000000
--- a/src/AppProvider.vue
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
-
-
-
-
-
diff --git a/src/composables/common/index.ts b/src/composables/common/index.ts
index ad404928..2d2a11c3 100644
--- a/src/composables/common/index.ts
+++ b/src/composables/common/index.ts
@@ -1,4 +1,3 @@
export * from './system';
export * from './router';
-export * from './theme';
export * from './layout';
diff --git a/src/composables/common/theme.ts b/src/composables/common/theme.ts
deleted file mode 100644
index ef23e646..00000000
--- a/src/composables/common/theme.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import { watch, onUnmounted } from 'vue';
-import { useOsTheme } from 'naive-ui';
-import { useElementSize } from '@vueuse/core';
-import { useThemeStore } from '@/store';
-
-export function useTheme() {
- const osTheme = useOsTheme();
- const theme = useThemeStore();
- const { width } = useElementSize(document.documentElement);
-
- /** 监听操作系统主题模式 */
- const stopHandle = watch(
- osTheme,
- newValue => {
- const isDark = newValue === 'dark';
- theme.setDarkMode(isDark);
- },
- { immediate: true }
- );
-
- /**
- * 禁用横向滚动
- * @description 页面切换时,过渡动画会产生水平方向的滚动条, 小于最小宽度时,不禁止
- */
- const anotherStopHandle = watch(width, newValue => {
- if (newValue < theme.layout.minWidth) {
- document.documentElement.style.overflowX = 'auto';
- } else {
- document.documentElement.style.overflowX = 'hidden';
- }
- });
-
- onUnmounted(() => {
- stopHandle();
- anotherStopHandle();
- });
-}
diff --git a/src/enum/common/storage.ts b/src/enum/common/storage.ts
index 05c1be83..8e5bfb28 100644
--- a/src/enum/common/storage.ts
+++ b/src/enum/common/storage.ts
@@ -1,4 +1,6 @@
export enum EnumStorageKey {
+ /** 主题颜色 */
+ 'theme-color' = '__THEME_COLOR__',
/** 用户token */
'token' = '__TOKEN__',
/** 用户刷新token */
diff --git a/src/interface/expose.ts b/src/interface/expose.ts
new file mode 100644
index 00000000..0dcabf0e
--- /dev/null
+++ b/src/interface/expose.ts
@@ -0,0 +1,3 @@
+export interface ExposeLayoutMixMenu {
+ resetFirstDegreeMenus(): void;
+}
diff --git a/src/interface/index.ts b/src/interface/index.ts
index f947ba8a..c1c16a68 100644
--- a/src/interface/index.ts
+++ b/src/interface/index.ts
@@ -1,4 +1,5 @@
export * from './enum';
export * from './theme';
export * from './system';
+export * from './expose';
export * from './layout';
diff --git a/src/layouts/common/GlobalHeader/components/GlobalBreadcrumb.vue b/src/layouts/common/GlobalHeader/components/GlobalBreadcrumb.vue
index 7d45fe04..7fca88e8 100644
--- a/src/layouts/common/GlobalHeader/components/GlobalBreadcrumb.vue
+++ b/src/layouts/common/GlobalHeader/components/GlobalBreadcrumb.vue
@@ -4,7 +4,11 @@
-
+
{{ breadcrumb.label }}
diff --git a/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuCollapse.vue b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuCollapse.vue
new file mode 100644
index 00000000..808a9352
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuCollapse.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDetail.vue b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDetail.vue
new file mode 100644
index 00000000..07961bd7
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDetail.vue
@@ -0,0 +1,45 @@
+
+
+
+
+
+
diff --git a/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDrawer.vue b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDrawer.vue
new file mode 100644
index 00000000..665554e2
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/MixMenuDrawer.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/common/GlobalSider/components/VerticalMixSider/components/index.ts b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/index.ts
new file mode 100644
index 00000000..75ae054e
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalMixSider/components/index.ts
@@ -0,0 +1,5 @@
+import MixMenuDetail from './MixMenuDetail.vue';
+import MixMenuDrawer from './MixMenuDrawer.vue';
+import MixMenuCollapse from './MixMenuCollapse.vue';
+
+export { MixMenuDetail, MixMenuDrawer, MixMenuCollapse };
diff --git a/src/layouts/common/GlobalSider/components/VerticalMixSider/index.vue b/src/layouts/common/GlobalSider/components/VerticalMixSider/index.vue
new file mode 100644
index 00000000..f74b93a4
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalMixSider/index.vue
@@ -0,0 +1,107 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/common/GlobalSider/components/SiderMenu.vue b/src/layouts/common/GlobalSider/components/VerticalSider/components/VerticalMenu.vue
similarity index 68%
rename from src/layouts/common/GlobalSider/components/SiderMenu.vue
rename to src/layouts/common/GlobalSider/components/VerticalSider/components/VerticalMenu.vue
index 0f203de7..5b49943e 100644
--- a/src/layouts/common/GlobalSider/components/SiderMenu.vue
+++ b/src/layouts/common/GlobalSider/components/VerticalSider/components/VerticalMenu.vue
@@ -1,11 +1,11 @@
-
+
routeStore.menus as GlobalMenuOption[]);
const activeKey = computed(() => route.name as string);
const expandedKeys = ref([]);
-function getExpendedKeys() {
- const keys = menus.value.map(menu => getActiveKeysInMenus(menu)).flat();
- return keys;
-}
-
-function getActiveKeysInMenus(menu: GlobalMenuOption) {
- const keys: string[] = [];
- if (activeKey.value.includes(menu.routeName)) {
- keys.push(menu.routeName);
- }
- if (menu.children) {
- keys.push(...menu.children.map(item => getActiveKeysInMenus(item as GlobalMenuOption)).flat(1));
- }
- return keys;
-}
-
function handleUpdateMenu(_key: string, item: MenuOption) {
const menuItem = item as GlobalMenuOption;
routerPush(menuItem.routePath);
@@ -61,7 +45,7 @@ function handleUpdateExpandedKeys(keys: string[]) {
watch(
() => route.name,
() => {
- expandedKeys.value = getExpendedKeys();
+ expandedKeys.value = getActiveKeyPathsOfMenus(activeKey.value, routeStore.menus);
},
{ immediate: true }
);
diff --git a/src/layouts/common/GlobalSider/components/VerticalSider/components/index.ts b/src/layouts/common/GlobalSider/components/VerticalSider/components/index.ts
new file mode 100644
index 00000000..e01ff94e
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalSider/components/index.ts
@@ -0,0 +1,3 @@
+import VerticalMenu from './VerticalMenu.vue';
+
+export { VerticalMenu };
diff --git a/src/layouts/common/GlobalSider/components/VerticalSider/index.vue b/src/layouts/common/GlobalSider/components/VerticalSider/index.vue
new file mode 100644
index 00000000..72701a7a
--- /dev/null
+++ b/src/layouts/common/GlobalSider/components/VerticalSider/index.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/layouts/common/GlobalSider/components/index.ts b/src/layouts/common/GlobalSider/components/index.ts
index aee0b996..364d0396 100644
--- a/src/layouts/common/GlobalSider/components/index.ts
+++ b/src/layouts/common/GlobalSider/components/index.ts
@@ -1,3 +1,4 @@
-import SiderMenu from './SiderMenu.vue';
+import VerticalSider from './VerticalSider/index.vue';
+import VerticalMixSider from './VerticalMixSider/index.vue';
-export { SiderMenu };
+export { VerticalSider, VerticalMixSider };
diff --git a/src/layouts/common/GlobalSider/index.vue b/src/layouts/common/GlobalSider/index.vue
index 8bbc7308..b279cb5c 100644
--- a/src/layouts/common/GlobalSider/index.vue
+++ b/src/layouts/common/GlobalSider/index.vue
@@ -1,18 +1,16 @@
-
-
-
-
+
+