diff --git a/src/layouts/modules/global-menu/base-menu.vue b/src/layouts/modules/global-menu/base-menu.vue index 94351cb94..e3d17c405 100644 --- a/src/layouts/modules/global-menu/base-menu.vue +++ b/src/layouts/modules/global-menu/base-menu.vue @@ -57,7 +57,7 @@ function updateExpandedKeys() { } function handleClickMenu(key: RouteKey) { - const { query } = routeStore.getSelectedMenuMetaByKey(key) || {}; + const query = routeStore.getRouteQueryOfMetaByKey(key); routerPushByKey(key, { query }); } diff --git a/src/locales/langs/en-us.ts b/src/locales/langs/en-us.ts index 0dccccebe..400567900 100644 --- a/src/locales/langs/en-us.ts +++ b/src/locales/langs/en-us.ts @@ -362,7 +362,7 @@ const local: App.I18n.Schema = { menuName: 'Menu Name', routeName: 'Route Name', routePath: 'Route Path', - routeParams: 'Route Params', + pathParam: 'Path Param', layout: 'Layout Component', page: 'Page Component', i18nKey: 'I18n Key', @@ -377,7 +377,6 @@ const local: App.I18n.Schema = { activeMenu: 'Active Menu', multiTab: 'Multi Tab', fixedIndexInTab: 'Fixed Index In Tab', - roles: 'Roles', query: 'Query Params', button: 'Button', buttonCode: 'Button Code', @@ -389,6 +388,7 @@ const local: App.I18n.Schema = { menuName: 'Please enter menu name', routeName: 'Please enter route name', routePath: 'Please enter route path', + pathParam: 'Please enter path param', page: 'Please select page component', layout: 'Please select layout component', i18nKey: 'Please enter i18n key', @@ -402,7 +402,6 @@ const local: App.I18n.Schema = { multiTab: 'Please select whether to support multiple tabs', fixedInTab: 'Please select whether to fix in the tab', fixedIndexInTab: 'Please enter the index fixed in the tab', - roles: 'Please select roles', queryKey: 'Please enter route parameter Key', queryValue: 'Please enter route parameter Value', button: 'Please select whether it is a button', diff --git a/src/locales/langs/zh-cn.ts b/src/locales/langs/zh-cn.ts index 3908a485c..71f072144 100644 --- a/src/locales/langs/zh-cn.ts +++ b/src/locales/langs/zh-cn.ts @@ -362,7 +362,7 @@ const local: App.I18n.Schema = { menuName: '菜单名称', routeName: '路由名称', routePath: '路由路径', - routeParams: '路由参数', + pathParam: '路径参数', layout: '布局', page: '页面组件', i18nKey: '国际化key', @@ -377,7 +377,6 @@ const local: App.I18n.Schema = { activeMenu: '高亮的菜单', multiTab: '支持多页签', fixedIndexInTab: '固定在页签中的序号', - roles: '角色', query: '路由参数', button: '按钮', buttonCode: '按钮编码', @@ -389,6 +388,7 @@ const local: App.I18n.Schema = { menuName: '请输入菜单名称', routeName: '请输入路由名称', routePath: '请输入路由路径', + pathParam: '请输入路径参数', page: '请选择页面组件', layout: '请选择布局组件', i18nKey: '请输入国际化key', @@ -402,7 +402,6 @@ const local: App.I18n.Schema = { multiTab: '请选择是否支持多标签', fixedInTab: '请选择是否固定在页签中', fixedIndexInTab: '请输入固定在页签中的序号', - roles: '请选择角色', queryKey: '请输入路由参数Key', queryValue: '请输入路由参数Value', button: '请选择是否按钮', diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts index d34b7297a..a65e7ad51 100644 --- a/src/store/modules/route/index.ts +++ b/src/store/modules/route/index.ts @@ -332,15 +332,31 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { } /** - * Get selected menu meta by key + * Get route meta by key * - * @param selectedKey Selected menu key + * @param key Route key */ - function getSelectedMenuMetaByKey(selectedKey: string) { - // The routes in router.options.routes are static, you need to use router.getRoutes() to get all the routes. + function getRouteMetaByKey(key: string) { const allRoutes = router.getRoutes(); - return allRoutes.find(route => route.name === selectedKey)?.meta || null; + return allRoutes.find(route => route.name === key)?.meta || null; + } + + /** + * Get route query of meta by key + * + * @param key + */ + function getRouteQueryOfMetaByKey(key: string) { + const meta = getRouteMetaByKey(key); + + const query: Record = {}; + + meta?.query?.forEach(item => { + query[item.key] = item.value; + }); + + return query; } return { @@ -360,6 +376,6 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => { setIsInitAuthRoute, getIsAuthRouteExist, getSelectedMenuKeyPath, - getSelectedMenuMetaByKey + getRouteQueryOfMetaByKey }; }); diff --git a/src/typings/api.d.ts b/src/typings/api.d.ts index 7e85dd2e8..e581c4a30 100644 --- a/src/typings/api.d.ts +++ b/src/typings/api.d.ts @@ -171,6 +171,20 @@ declare namespace Api { */ type IconType = '1' | '2'; + type MenuPropsOfRoute = Pick< + import('vue-router').RouteMeta, + | 'i18nKey' + | 'keepAlive' + | 'constant' + | 'order' + | 'href' + | 'hideInMenu' + | 'activeMenu' + | 'multiTab' + | 'fixedIndexInTab' + | 'query' + >; + type Menu = Common.CommonRecord<{ /** parent menu id */ parentId: number; @@ -184,56 +198,16 @@ declare namespace Api { routePath: string; /** component */ component?: string; - /** - * i18n key - * - * it is for internationalization - */ - i18nKey?: App.I18n.I18nKey; /** iconify icon name or local icon name */ icon: string; /** icon type */ iconType: IconType; - /** menu order */ - order: number; - /** whether to cache the route */ - keepAlive?: boolean; - /** - * Is constant route - * - * Does not need to login, and the route is defined in the front-end - */ - constant?: boolean; - /** outer link */ - href?: string; - /** whether to hide the route in the menu */ - hideInMenu?: boolean; - /** - * The menu key will be activated when entering the route - * - * The route is not in the menu - * - * @example - * the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated - */ - activeMenu?: import('@elegant-router/types').LastLevelRouteKey; - /** By default, the same route path will use one tab, if set to true, it will use multiple tabs */ - multiTab?: boolean; - /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ - fixedIndexInTab?: number | null; - /** if set query parameters, it will be automatically carried when entering the route */ - query: Record; - /** menu buttons */ - buttons?: MenuButton[]; - /** - * Roles of the route - * - * Route can be accessed if the current user has at least one of the roles - */ - roles?: string[]; + /** buttons */ + buttons?: MenuButton[] | null; /** children menu */ - children?: Menu[]; - }>; + children?: Menu[] | null; + }> & + MenuPropsOfRoute; /** menu list */ type MenuList = Common.PaginatingQueryRecord; diff --git a/src/typings/app.d.ts b/src/typings/app.d.ts index f5bbae1f3..e0dbe7666 100644 --- a/src/typings/app.d.ts +++ b/src/typings/app.d.ts @@ -158,7 +158,7 @@ declare namespace App { /** The menu label */ label: string; /** The menu i18n key */ - i18nKey?: I18n.I18nKey; + i18nKey?: I18n.I18nKey | null; /** The route key */ routeKey: RouteKey; /** The route path */ @@ -216,7 +216,7 @@ declare namespace App { */ localIcon?: string; /** I18n key */ - i18nKey?: I18n.I18nKey; + i18nKey?: I18n.I18nKey | null; }; /** Form rule */ @@ -537,7 +537,7 @@ declare namespace App { menuName: string; routeName: string; routePath: string; - routeParams: string; + pathParam: string; layout: string; page: string; i18nKey: string; @@ -552,7 +552,6 @@ declare namespace App { activeMenu: string; multiTab: string; fixedIndexInTab: string; - roles: string; query: string; button: string; buttonCode: string; @@ -564,6 +563,7 @@ declare namespace App { menuName: string; routeName: string; routePath: string; + pathParam: string; layout: string; page: string; i18nKey: string; @@ -577,7 +577,6 @@ declare namespace App { multiTab: string; fixedInTab: string; fixedIndexInTab: string; - roles: string; queryKey: string; queryValue: string; button: string; diff --git a/src/typings/router.d.ts b/src/typings/router.d.ts index 13dc4f242..ab4030d66 100644 --- a/src/typings/router.d.ts +++ b/src/typings/router.d.ts @@ -13,21 +13,23 @@ declare module 'vue-router' { * * It's used in i18n, if it is set, the title will be ignored */ - i18nKey?: App.I18n.I18nKey; + i18nKey?: App.I18n.I18nKey | null; /** * Roles of the route * * Route can be accessed if the current user has at least one of the roles + * + * It only works when the route mode is "static", if the route mode is "dynamic", it will be ignored */ roles?: string[]; /** Whether to cache the route */ - keepAlive?: boolean; + keepAlive?: boolean | null; /** * Is constant route * * Does not need to login, and the route is defined in the front-end */ - constant?: boolean; + constant?: boolean | null; /** * Iconify icon * @@ -41,11 +43,11 @@ declare module 'vue-router' { */ localIcon?: string; /** Router order */ - order?: number; + order?: number | null; /** The outer link of the route */ - href?: string; + href?: string | null; /** Whether to hide the route in the menu */ - hideInMenu?: boolean; + hideInMenu?: boolean | null; /** * The menu key will be activated when entering the route * @@ -54,12 +56,12 @@ declare module 'vue-router' { * @example * the route is "user_detail", if it is set to "user_list", the menu "user_list" will be activated */ - activeMenu?: import('@elegant-router/types').RouteKey; + activeMenu?: import('@elegant-router/types').RouteKey | null; /** By default, the same route path will use one tab, if set to true, it will use multiple tabs */ - multiTab?: boolean; + multiTab?: boolean | null; /** If set, the route will be fixed in tabs, and the value is the order of fixed tabs */ fixedIndexInTab?: number | null; /** if set query parameters, it will be automatically carried when entering the route */ - query?: Record; + query?: { key: string; value: string }[] | null; } } diff --git a/src/views/manage/menu/modules/menu-operate-drawer.vue b/src/views/manage/menu/modules/menu-operate-drawer.vue index 6380267ca..6dedbe8a3 100644 --- a/src/views/manage/menu/modules/menu-operate-drawer.vue +++ b/src/views/manage/menu/modules/menu-operate-drawer.vue @@ -1,8 +1,6 @@