mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-27 05:36:43 +08:00
fix(types): 修正了route的meta类型,新增pageType类型,方便过滤菜单和标签
This commit is contained in:
parent
784fa1ef8e
commit
99745ad9fa
2
.env
2
.env
@ -17,7 +17,7 @@ VITE_ICON_LOCAL_PREFIX=icon-local
|
|||||||
VITE_AUTH_ROUTE_MODE=static
|
VITE_AUTH_ROUTE_MODE=static
|
||||||
|
|
||||||
# static auth route home
|
# static auth route home
|
||||||
VITE_ROUTE_HOME=home
|
VITE_ROUTE_HOME=pan
|
||||||
|
|
||||||
# default menu icon
|
# default menu icon
|
||||||
VITE_MENU_ICON=mdi:menu
|
VITE_MENU_ICON=mdi:menu
|
||||||
|
@ -24,6 +24,10 @@ const inverted = computed(() => !themeStore.darkMode && themeStore.sider.inverte
|
|||||||
|
|
||||||
const expandedKeys = ref<string[]>([]);
|
const expandedKeys = ref<string[]>([]);
|
||||||
|
|
||||||
|
const menuOptions = computed(() => {
|
||||||
|
return routeStore.menus.filter(menu => menu.pageType === routeStore.currentPageType);
|
||||||
|
});
|
||||||
|
|
||||||
function updateExpandedKeys() {
|
function updateExpandedKeys() {
|
||||||
if (appStore.siderCollapse || !selectedKey.value) {
|
if (appStore.siderCollapse || !selectedKey.value) {
|
||||||
expandedKeys.value = [];
|
expandedKeys.value = [];
|
||||||
@ -51,7 +55,7 @@ watch(
|
|||||||
:collapsed="appStore.siderCollapse"
|
:collapsed="appStore.siderCollapse"
|
||||||
:collapsed-width="themeStore.sider.collapsedWidth"
|
:collapsed-width="themeStore.sider.collapsedWidth"
|
||||||
:collapsed-icon-size="22"
|
:collapsed-icon-size="22"
|
||||||
:options="routeStore.menus"
|
:options="menuOptions"
|
||||||
:inverted="inverted"
|
:inverted="inverted"
|
||||||
:indent="18"
|
:indent="18"
|
||||||
@update:value="routerPushByKeyWithMetaQuery"
|
@update:value="routerPushByKeyWithMetaQuery"
|
||||||
|
@ -162,7 +162,8 @@ const local: App.I18n.Schema = {
|
|||||||
404: 'Page Not Found',
|
404: 'Page Not Found',
|
||||||
500: 'Server Error',
|
500: 'Server Error',
|
||||||
'iframe-page': 'Iframe',
|
'iframe-page': 'Iframe',
|
||||||
home: 'Home'
|
home: 'Home',
|
||||||
|
pan: 'My Files'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
@ -162,7 +162,8 @@ const local: App.I18n.Schema = {
|
|||||||
404: '页面不存在',
|
404: '页面不存在',
|
||||||
500: '服务器错误',
|
500: '服务器错误',
|
||||||
'iframe-page': '外链页面',
|
'iframe-page': '外链页面',
|
||||||
home: '首页'
|
home: '首页',
|
||||||
|
pan: '我的文件'
|
||||||
},
|
},
|
||||||
page: {
|
page: {
|
||||||
login: {
|
login: {
|
||||||
|
@ -21,4 +21,5 @@ export const views: Record<LastLevelRouteKey, RouteComponent | (() => Promise<Ro
|
|||||||
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
|
"iframe-page": () => import("@/views/_builtin/iframe-page/[url].vue"),
|
||||||
login: () => import("@/views/_builtin/login/index.vue"),
|
login: () => import("@/views/_builtin/login/index.vue"),
|
||||||
home: () => import("@/views/home/index.vue"),
|
home: () => import("@/views/home/index.vue"),
|
||||||
|
pan: () => import("@/views/pan/index.vue"),
|
||||||
};
|
};
|
||||||
|
@ -47,7 +47,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||||||
title: 'home',
|
title: 'home',
|
||||||
i18nKey: 'route.home',
|
i18nKey: 'route.home',
|
||||||
icon: 'mdi:monitor-dashboard',
|
icon: 'mdi:monitor-dashboard',
|
||||||
order: 1
|
order: 1,
|
||||||
|
pageType: 'admin'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -74,5 +75,15 @@ export const generatedRoutes: GeneratedRoute[] = [
|
|||||||
constant: true,
|
constant: true,
|
||||||
hideInMenu: true
|
hideInMenu: true
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pan',
|
||||||
|
path: '/pan',
|
||||||
|
component: 'layout.base$view.pan',
|
||||||
|
meta: {
|
||||||
|
title: 'pan',
|
||||||
|
i18nKey: 'route.pan',
|
||||||
|
pageType: 'pan'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
@ -168,7 +168,8 @@ const routeMap: RouteMap = {
|
|||||||
"500": "/500",
|
"500": "/500",
|
||||||
"home": "/home",
|
"home": "/home",
|
||||||
"iframe-page": "/iframe-page/:url",
|
"iframe-page": "/iframe-page/:url",
|
||||||
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?"
|
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?",
|
||||||
|
"pan": "/pan"
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,6 +18,9 @@ import { localStg } from '@/utils/storage';
|
|||||||
*/
|
*/
|
||||||
export function createRouteGuard(router: Router) {
|
export function createRouteGuard(router: Router) {
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
const routeStore = useRouteStore();
|
||||||
|
// 每次路由变化时更新页面类型
|
||||||
|
routeStore.setPageType(to);
|
||||||
const location = await initRoute(to);
|
const location = await initRoute(to);
|
||||||
|
|
||||||
if (location) {
|
if (location) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { computed, nextTick, ref, shallowRef } from 'vue';
|
import { computed, nextTick, ref, shallowRef } from 'vue';
|
||||||
import type { RouteRecordRaw } from 'vue-router';
|
import type { RouteLocationNormalized, RouteRecordRaw } from 'vue-router';
|
||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { useBoolean } from '@sa/hooks';
|
import { useBoolean } from '@sa/hooks';
|
||||||
import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
|
import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
|
||||||
@ -41,6 +41,21 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
|||||||
/** Home route key */
|
/** Home route key */
|
||||||
const routeHome = ref(import.meta.env.VITE_ROUTE_HOME);
|
const routeHome = ref(import.meta.env.VITE_ROUTE_HOME);
|
||||||
|
|
||||||
|
/** 当前页面的类型 */
|
||||||
|
const currentPageType = ref<UnionKey.SystemPageType>('pan');
|
||||||
|
|
||||||
|
/** 设置当前页面类型方法 */
|
||||||
|
const setPageType = (route: RouteLocationNormalized) => {
|
||||||
|
const matched = route.matched;
|
||||||
|
for (let i = matched.length - 1; i >= 0; i -= 1) {
|
||||||
|
const type = matched[i].meta?.pageType;
|
||||||
|
if (type) {
|
||||||
|
currentPageType.value = type;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
currentPageType.value = 'pan';
|
||||||
|
};
|
||||||
/**
|
/**
|
||||||
* Set route home
|
* Set route home
|
||||||
*
|
*
|
||||||
@ -343,6 +358,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
|||||||
getIsAuthRouteExist,
|
getIsAuthRouteExist,
|
||||||
getSelectedMenuKeyPath,
|
getSelectedMenuKeyPath,
|
||||||
onRouteSwitchWhenLoggedIn,
|
onRouteSwitchWhenLoggedIn,
|
||||||
onRouteSwitchWhenNotLoggedIn
|
onRouteSwitchWhenNotLoggedIn,
|
||||||
|
currentPageType,
|
||||||
|
setPageType
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
@ -127,19 +127,33 @@ export function updateLocaleOfGlobalMenus(menus: App.Global.Menu[]) {
|
|||||||
function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | ElegantConstRoute) {
|
function getGlobalMenuByBaseRoute(route: RouteLocationNormalizedLoaded | ElegantConstRoute) {
|
||||||
const { SvgIconVNode } = useSvgIcon();
|
const { SvgIconVNode } = useSvgIcon();
|
||||||
|
|
||||||
const { name, path } = route;
|
const { name, path, meta } = route;
|
||||||
const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon, iconFontSize } = route.meta ?? {};
|
const { title, i18nKey, icon = import.meta.env.VITE_MENU_ICON, localIcon, iconFontSize } = route.meta ?? {};
|
||||||
|
|
||||||
const label = i18nKey ? $t(i18nKey) : title!;
|
const label = i18nKey ? $t(i18nKey) : title!;
|
||||||
|
|
||||||
const menu: App.Global.Menu = {
|
let menu: App.Global.Menu;
|
||||||
key: name as string,
|
|
||||||
label,
|
if (meta?.pageType) {
|
||||||
i18nKey,
|
menu = {
|
||||||
routeKey: name as RouteKey,
|
key: name as string,
|
||||||
routePath: path as RouteMap[RouteKey],
|
label,
|
||||||
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 })
|
i18nKey,
|
||||||
};
|
routeKey: name as RouteKey,
|
||||||
|
routePath: path as RouteMap[RouteKey],
|
||||||
|
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 }),
|
||||||
|
pageType: meta?.pageType
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
menu = {
|
||||||
|
key: name as string,
|
||||||
|
label,
|
||||||
|
i18nKey,
|
||||||
|
routeKey: name as RouteKey,
|
||||||
|
routePath: path as RouteMap[RouteKey],
|
||||||
|
icon: SvgIconVNode({ icon, localIcon, fontSize: iconFontSize || 20 })
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
1
src/typings/app.d.ts
vendored
1
src/typings/app.d.ts
vendored
@ -204,6 +204,7 @@ declare namespace App {
|
|||||||
/** The menu icon */
|
/** The menu icon */
|
||||||
icon?: () => VNode;
|
icon?: () => VNode;
|
||||||
/** The menu children */
|
/** The menu children */
|
||||||
|
pageType?: UnionKey.SystemPageType;
|
||||||
children?: Menu[];
|
children?: Menu[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
3
src/typings/elegant-router.d.ts
vendored
3
src/typings/elegant-router.d.ts
vendored
@ -23,6 +23,7 @@ declare module "@elegant-router/types" {
|
|||||||
"home": "/home";
|
"home": "/home";
|
||||||
"iframe-page": "/iframe-page/:url";
|
"iframe-page": "/iframe-page/:url";
|
||||||
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
|
"login": "/login/:module(pwd-login|code-login|register|reset-pwd|bind-wechat)?";
|
||||||
|
"pan": "/pan";
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +61,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "home"
|
| "home"
|
||||||
| "iframe-page"
|
| "iframe-page"
|
||||||
| "login"
|
| "login"
|
||||||
|
| "pan"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,6 +84,7 @@ declare module "@elegant-router/types" {
|
|||||||
| "iframe-page"
|
| "iframe-page"
|
||||||
| "login"
|
| "login"
|
||||||
| "home"
|
| "home"
|
||||||
|
| "pan"
|
||||||
>;
|
>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
2
src/typings/router.d.ts
vendored
2
src/typings/router.d.ts
vendored
@ -66,6 +66,8 @@ declare module 'vue-router' {
|
|||||||
multiTab?: boolean | null;
|
multiTab?: boolean | null;
|
||||||
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
|
/** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */
|
||||||
fixedIndexInTab?: number | null;
|
fixedIndexInTab?: number | null;
|
||||||
|
/** 页面类型 */
|
||||||
|
pageType?: UnionKey.SystemPageType;
|
||||||
/** if set query parameters, it will be automatically carried when entering the route */
|
/** if set query parameters, it will be automatically carried when entering the route */
|
||||||
query?: { key: string; value: string }[] | null;
|
query?: { key: string; value: string }[] | null;
|
||||||
}
|
}
|
||||||
|
2
src/typings/union-key.d.ts
vendored
2
src/typings/union-key.d.ts
vendored
@ -51,6 +51,8 @@ declare namespace UnionKey {
|
|||||||
*/
|
*/
|
||||||
type ThemeTabMode = import('@sa/materials').PageTabMode;
|
type ThemeTabMode = import('@sa/materials').PageTabMode;
|
||||||
|
|
||||||
|
type SystemPageType = 'pan' | 'admin' | null;
|
||||||
|
|
||||||
/** Unocss animate key */
|
/** Unocss animate key */
|
||||||
type UnoCssAnimateKey =
|
type UnoCssAnimateKey =
|
||||||
| 'pulse'
|
| 'pulse'
|
||||||
|
7
src/views/pan/index.vue
Normal file
7
src/views/pan/index.vue
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>网盘页面</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
Loading…
Reference in New Issue
Block a user