From 913c22c84fc9a4221fdfff6bae0e79a68fd09b17 Mon Sep 17 00:00:00 2001 From: vben Date: Sun, 27 Jun 2021 23:58:14 +0800 Subject: [PATCH] feat(menu): the route is automatically mapped to the menu --- CHANGELOG.zh_CN.md | 8 + src/enums/appEnum.ts | 2 + src/hooks/web/usePermission.ts | 8 +- src/layouts/default/feature/index.vue | 4 +- src/router/guard/index.ts | 8 +- src/router/guard/permissionGuard.ts | 8 +- src/router/helper/routeHelper.ts | 2 + src/router/menus/index.ts | 55 +++- src/router/menus/modules/about.ts | 11 - src/router/menus/modules/dashboard.ts | 22 -- src/router/menus/modules/demo/charts.ts | 45 --- src/router/menus/modules/demo/comp.ts | 279 ------------------- src/router/menus/modules/demo/excel.ts | 29 -- src/router/menus/modules/demo/feat.ts | 130 --------- src/router/menus/modules/demo/flow.ts | 17 -- src/router/menus/modules/demo/iframe.ts | 25 -- src/router/menus/modules/demo/level.ts | 37 --- src/router/menus/modules/demo/page.ts | 121 -------- src/router/menus/modules/demo/permission.ts | 49 ---- src/router/menus/modules/demo/setup.ts | 14 - src/router/menus/modules/demo/system.ts | 34 --- src/router/routes/basic.ts | 2 + src/router/routes/modules/about.ts | 2 + src/router/routes/modules/dashboard.ts | 1 + src/router/routes/modules/demo/charts.ts | 1 + src/router/routes/modules/demo/comp.ts | 1 + src/router/routes/modules/demo/feat.ts | 1 + src/router/routes/modules/demo/flow.ts | 1 + src/router/routes/modules/demo/iframe.ts | 1 + src/router/routes/modules/demo/level.ts | 1 + src/router/routes/modules/demo/page.ts | 1 + src/router/routes/modules/demo/permission.ts | 1 + src/router/routes/modules/demo/setup.ts | 2 + src/router/routes/modules/demo/system.ts | 2 + src/settings/projectSetting.ts | 2 +- src/store/modules/app.ts | 2 +- src/store/modules/permission.ts | 112 +++++--- src/store/modules/user.ts | 2 +- src/utils/http/axios/checkStatus.ts | 4 +- types/vue-router.d.ts | 1 + 40 files changed, 159 insertions(+), 889 deletions(-) delete mode 100644 src/router/menus/modules/about.ts delete mode 100644 src/router/menus/modules/dashboard.ts delete mode 100644 src/router/menus/modules/demo/charts.ts delete mode 100644 src/router/menus/modules/demo/comp.ts delete mode 100644 src/router/menus/modules/demo/excel.ts delete mode 100644 src/router/menus/modules/demo/feat.ts delete mode 100644 src/router/menus/modules/demo/flow.ts delete mode 100644 src/router/menus/modules/demo/iframe.ts delete mode 100644 src/router/menus/modules/demo/level.ts delete mode 100644 src/router/menus/modules/demo/page.ts delete mode 100644 src/router/menus/modules/demo/permission.ts delete mode 100644 src/router/menus/modules/demo/setup.ts delete mode 100644 src/router/menus/modules/demo/system.ts diff --git a/CHANGELOG.zh_CN.md b/CHANGELOG.zh_CN.md index 9a2fd36e3d6..febf6f3bc99 100644 --- a/CHANGELOG.zh_CN.md +++ b/CHANGELOG.zh_CN.md @@ -1,7 +1,15 @@ ## Wip +### ⚡ Performance Improvements + - **Icon** 移除 Icon 组件全局注册,防止特定情况下热更新问题 +### ✨ Features + +- **Menu** 新增 `permissionMode=PermissionModeEnum.ROUTE_MAPPING`模式 + - 项目默认改为该模式,删除原有菜单文件 + - 如果之前已经写好了菜单,可以更改为`PermissionModeEnum.ROLE`模式即可 + ## 2.5.1(2021-06-26) ### ⚡ Performance Improvements diff --git a/src/enums/appEnum.ts b/src/enums/appEnum.ts index b2c9826ecb5..63869d20b98 100644 --- a/src/enums/appEnum.ts +++ b/src/enums/appEnum.ts @@ -33,6 +33,8 @@ export enum PermissionModeEnum { ROLE = 'ROLE', // black BACK = 'BACK', + // route mapping + ROUTE_MAPPING = 'ROUTE_MAPPING', } // Route switching animation diff --git a/src/hooks/web/usePermission.ts b/src/hooks/web/usePermission.ts index 9ab87974720..102674ed6ac 100644 --- a/src/hooks/web/usePermission.ts +++ b/src/hooks/web/usePermission.ts @@ -31,7 +31,7 @@ export function usePermission() { appStore.setProjectConfig({ permissionMode: projectSetting.permissionMode === PermissionModeEnum.BACK - ? PermissionModeEnum.ROLE + ? PermissionModeEnum.ROUTE_MAPPING : PermissionModeEnum.BACK, }); location.reload(); @@ -59,7 +59,7 @@ export function usePermission() { function hasPermission(value?: RoleEnum | RoleEnum[] | string | string[], def = true): boolean { const permMode = projectSetting.permissionMode; - if (PermissionModeEnum.ROLE === permMode) { + if (PermissionModeEnum.ROUTE_MAPPING === permMode) { // Visible by default if (!value) { return def; @@ -89,9 +89,9 @@ export function usePermission() { * @param roles */ async function changeRole(roles: RoleEnum | RoleEnum[]): Promise { - if (projectSetting.permissionMode !== PermissionModeEnum.ROLE) { + if (projectSetting.permissionMode !== PermissionModeEnum.ROUTE_MAPPING) { throw new Error( - 'Please switch PermissionModeEnum to ROLE mode in the configuration to operate!' + 'Please switch PermissionModeEnum to ROUTE_MAPPING mode in the configuration to operate!' ); } diff --git a/src/layouts/default/feature/index.vue b/src/layouts/default/feature/index.vue index a6b64b1e259..0787014a10a 100644 --- a/src/layouts/default/feature/index.vue +++ b/src/layouts/default/feature/index.vue @@ -5,7 +5,7 @@ import { useRootSetting } from '/@/hooks/setting/useRootSetting'; import { useHeaderSetting } from '/@/hooks/setting/useHeaderSetting'; import { useDesign } from '/@/hooks/web/useDesign'; - import { useUserStoreWidthOut } from '/@/store/modules/user'; + import { useUserStoreWithOut } from '/@/store/modules/user'; import { SettingButtonPositionEnum } from '/@/enums/appEnum'; import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; @@ -22,7 +22,7 @@ setup() { const { getUseOpenBackTop, getShowSettingButton, getSettingButtonPosition, getFullContent } = useRootSetting(); - const userStore = useUserStoreWidthOut(); + const userStore = useUserStoreWithOut(); const { prefixCls } = useDesign('setting-drawer-fearure'); const { getShowHeader } = useHeaderSetting(); diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts index a88191d39e4..8bd42796403 100644 --- a/src/router/guard/index.ts +++ b/src/router/guard/index.ts @@ -1,6 +1,6 @@ import type { Router, RouteLocationNormalized } from 'vue-router'; -import { useAppStoreWidthOut } from '/@/store/modules/app'; -import { useUserStoreWidthOut } from '/@/store/modules/user'; +import { useAppStoreWithOut } from '/@/store/modules/app'; +import { useUserStoreWithOut } from '/@/store/modules/user'; import { useTransitionSetting } from '/@/hooks/setting/useTransitionSetting'; import { AxiosCanceler } from '/@/utils/http/axios/axiosCancel'; import { Modal, notification } from 'ant-design-vue'; @@ -46,8 +46,8 @@ function createPageGuard(router: Router) { // Used to handle page loading status function createPageLoadingGuard(router: Router) { - const userStore = useUserStoreWidthOut(); - const appStore = useAppStoreWidthOut(); + const userStore = useUserStoreWithOut(); + const appStore = useAppStoreWithOut(); const { getOpenPageLoading } = useTransitionSetting(); router.beforeEach(async (to) => { if (!userStore.getToken) { diff --git a/src/router/guard/permissionGuard.ts b/src/router/guard/permissionGuard.ts index c03e99d57d9..5b731305d86 100644 --- a/src/router/guard/permissionGuard.ts +++ b/src/router/guard/permissionGuard.ts @@ -1,9 +1,9 @@ import type { Router, RouteRecordRaw } from 'vue-router'; -import { usePermissionStoreWidthOut } from '/@/store/modules/permission'; +import { usePermissionStoreWithOut } from '/@/store/modules/permission'; import { PageEnum } from '/@/enums/pageEnum'; -import { useUserStoreWidthOut } from '/@/store/modules/user'; +import { useUserStoreWithOut } from '/@/store/modules/user'; import { PAGE_NOT_FOUND_ROUTE } from '/@/router/routes/basic'; @@ -12,8 +12,8 @@ const LOGIN_PATH = PageEnum.BASE_LOGIN; const whitePathList: PageEnum[] = [LOGIN_PATH]; export function createPermissionGuard(router: Router) { - const userStore = useUserStoreWidthOut(); - const permissionStore = usePermissionStoreWidthOut(); + const userStore = useUserStoreWithOut(); + const permissionStore = usePermissionStoreWithOut(); router.beforeEach(async (to, from, next) => { // Jump to the 404 page after processing the login if (from.path === LOGIN_PATH && to.name === PAGE_NOT_FOUND_ROUTE.name) { diff --git a/src/router/helper/routeHelper.ts b/src/router/helper/routeHelper.ts index f37cc4214c3..507f21a5c13 100644 --- a/src/router/helper/routeHelper.ts +++ b/src/router/helper/routeHelper.ts @@ -65,6 +65,8 @@ function dynamicImport( // Turn background objects into routing objects export function transformObjToRoute(routeList: AppRouteModule[]): T[] { + console.log(routeList); + routeList.forEach((route) => { const component = route.component as string; if (component) { diff --git a/src/router/menus/index.ts b/src/router/menus/index.ts index d7fe609179f..bbd6190459e 100644 --- a/src/router/menus/index.ts +++ b/src/router/menus/index.ts @@ -1,7 +1,7 @@ import type { Menu, MenuModule } from '/@/router/types'; import type { RouteRecordNormalized } from 'vue-router'; -import { useAppStoreWidthOut } from '/@/store/modules/app'; +import { useAppStoreWithOut } from '/@/store/modules/app'; import { usePermissionStore } from '/@/store/modules/permission'; import { transformMenuModule, getAllParentPath } from '/@/router/helper/menuHelper'; import { filter } from '/@/utils/helper/treeHelper'; @@ -23,9 +23,21 @@ Object.keys(modules).forEach((key) => { // =========================== // ==========Helper=========== // =========================== + +const getPermissionMode = () => { + const appStore = useAppStoreWithOut(); + return appStore.getProjectConfig.permissionMode; +}; const isBackMode = () => { - const appStore = useAppStoreWidthOut(); - return appStore.getProjectConfig.permissionMode === PermissionModeEnum.BACK; + return getPermissionMode() === PermissionModeEnum.BACK; +}; + +const isRouteMappingMode = () => { + return getPermissionMode() === PermissionModeEnum.ROUTE_MAPPING; +}; + +const isRoleMode = () => { + return getPermissionMode() === PermissionModeEnum.ROLE; }; const staticMenus: Menu[] = []; @@ -41,40 +53,53 @@ const staticMenus: Menu[] = []; async function getAsyncMenus() { const permissionStore = usePermissionStore(); - return !isBackMode() ? staticMenus : permissionStore.getBackMenuList; + if (isBackMode()) { + return permissionStore.getBackMenuList; + } + if (isRouteMappingMode()) { + return permissionStore.getFrontMenuList.filter((item) => !item.hideMenu); + } + return staticMenus; } export const getMenus = async (): Promise => { const menus = await getAsyncMenus(); - const routes = router.getRoutes(); - - return !isBackMode() ? filter(menus, basicFilter(routes)) : menus; + if (isRoleMode()) { + const routes = router.getRoutes(); + return filter(menus, basicFilter(routes)); + } + return menus; }; export async function getCurrentParentPath(currentPath: string) { const menus = await getAsyncMenus(); - const allParentPath = await getAllParentPath(menus, currentPath); - return allParentPath?.[0]; } // Get the level 1 menu, delete children export async function getShallowMenus(): Promise { const menus = await getAsyncMenus(); - const routes = router.getRoutes(); const shallowMenuList = menus.map((item) => ({ ...item, children: undefined })); - return !isBackMode() ? shallowMenuList.filter(basicFilter(routes)) : shallowMenuList; + if (isRoleMode()) { + const routes = router.getRoutes(); + return shallowMenuList.filter(basicFilter(routes)); + } + return shallowMenuList; } // Get the children of the menu export async function getChildrenMenus(parentPath: string) { const menus = await getMenus(); const parent = menus.find((item) => item.path === parentPath); - if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) return [] as Menu[]; - const routes = router.getRoutes(); - - return !isBackMode() ? filter(parent.children, basicFilter(routes)) : parent.children; + if (!parent || !parent.children || !!parent?.meta?.hideChildrenInMenu) { + return [] as Menu[]; + } + if (isRoleMode()) { + const routes = router.getRoutes(); + return filter(parent.children, basicFilter(routes)); + } + return parent.children; } function basicFilter(routes: RouteRecordNormalized[]) { diff --git a/src/router/menus/modules/about.ts b/src/router/menus/modules/about.ts deleted file mode 100644 index 1c36b37d351..00000000000 --- a/src/router/menus/modules/about.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const about: MenuModule = { - orderNo: 100000, - menu: { - path: '/about/index', - name: t('routes.dashboard.about'), - }, -}; -export default about; diff --git a/src/router/menus/modules/dashboard.ts b/src/router/menus/modules/dashboard.ts deleted file mode 100644 index 5834475f530..00000000000 --- a/src/router/menus/modules/dashboard.ts +++ /dev/null @@ -1,22 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 10, - menu: { - name: t('routes.dashboard.dashboard'), - path: '/dashboard', - - children: [ - { - path: 'analysis', - name: t('routes.dashboard.analysis'), - }, - { - path: 'workbench', - name: t('routes.dashboard.workbench'), - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/charts.ts b/src/router/menus/modules/demo/charts.ts deleted file mode 100644 index 842c241956d..00000000000 --- a/src/router/menus/modules/demo/charts.ts +++ /dev/null @@ -1,45 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 500, - menu: { - name: t('routes.demo.charts.charts'), - path: '/charts', - - children: [ - { - path: 'aMap', - name: t('routes.demo.charts.aMap'), - }, - - { - path: 'baiduMap', - name: t('routes.demo.charts.baiduMap'), - }, - { - path: 'googleMap', - name: t('routes.demo.charts.googleMap'), - }, - { - path: 'echarts', - name: 'Echarts', - children: [ - { - path: 'map', - name: t('routes.demo.charts.map'), - }, - { - path: 'line', - name: t('routes.demo.charts.line'), - }, - { - path: 'pie', - name: t('routes.demo.charts.pie'), - }, - ], - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/comp.ts b/src/router/menus/modules/demo/comp.ts deleted file mode 100644 index e375aa4fdcf..00000000000 --- a/src/router/menus/modules/demo/comp.ts +++ /dev/null @@ -1,279 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 30, - menu: { - name: t('routes.demo.comp.comp'), - path: '/comp', - tag: { dot: true }, - children: [ - { - path: 'basic', - name: t('routes.demo.comp.basic'), - }, - { - path: 'form', - name: t('routes.demo.form.form'), - - children: [ - { - path: 'basic', - name: t('routes.demo.form.basic'), - }, - { - path: 'useForm', - name: t('routes.demo.form.useForm'), - }, - { - path: 'refForm', - name: t('routes.demo.form.refForm'), - }, - { - path: 'advancedForm', - name: t('routes.demo.form.advancedForm'), - }, - { - path: 'ruleForm', - name: t('routes.demo.form.ruleForm'), - }, - { - path: 'dynamicForm', - name: t('routes.demo.form.dynamicForm'), - }, - { - path: 'customerForm', - name: t('routes.demo.form.customerForm'), - }, - { - path: 'appendForm', - name: t('routes.demo.form.appendForm'), - }, - ], - }, - { - path: 'table', - name: t('routes.demo.table.table'), - - children: [ - { - path: 'basic', - name: t('routes.demo.table.basic'), - }, - { - path: 'treeTable', - name: t('routes.demo.table.treeTable'), - }, - { - path: 'fetchTable', - name: t('routes.demo.table.fetchTable'), - }, - { - path: 'fixedColumn', - name: t('routes.demo.table.fixedColumn'), - }, - { - path: 'customerCell', - name: t('routes.demo.table.customerCell'), - }, - { - path: 'formTable', - name: t('routes.demo.table.formTable'), - }, - { - path: 'useTable', - name: t('routes.demo.table.useTable'), - }, - { - path: 'refTable', - name: t('routes.demo.table.refTable'), - }, - { - path: 'multipleHeader', - name: t('routes.demo.table.multipleHeader'), - }, - { - path: 'mergeHeader', - name: t('routes.demo.table.mergeHeader'), - }, - { - path: 'expandTable', - name: t('routes.demo.table.expandTable'), - }, - { - path: 'fixedHeight', - name: t('routes.demo.table.fixedHeight'), - }, - { - path: 'footerTable', - name: t('routes.demo.table.footerTable'), - }, - { - path: 'editCellTable', - name: t('routes.demo.table.editCellTable'), - }, - { - path: 'editRowTable', - name: t('routes.demo.table.editRowTable'), - }, - { - path: 'authColumn', - name: t('routes.demo.table.authColumn'), - }, - ], - }, - { - path: 'cropper', - name: t('routes.demo.comp.cropperImage'), - tag: { - content: 'new', - }, - }, - { - path: 'countTo', - name: t('routes.demo.comp.countTo'), - }, - { - path: 'timestamp', - name: t('routes.demo.comp.time'), - }, - { - path: 'transition', - name: t('routes.demo.comp.transition'), - }, - - { - path: 'modal', - name: t('routes.demo.comp.modal'), - }, - { - path: 'drawer', - name: t('routes.demo.comp.drawer'), - }, - { - path: 'desc', - name: t('routes.demo.comp.desc'), - }, - { - path: 'qrcode', - name: t('routes.demo.comp.qrcode'), - }, - { - path: 'strength-meter', - name: t('routes.demo.comp.strength'), - }, - { - path: 'upload', - name: t('routes.demo.comp.upload'), - }, - { - path: 'loading', - name: t('routes.demo.comp.loading'), - }, - { - path: 'tree', - name: t('routes.demo.comp.tree'), - - children: [ - { - path: 'basic', - name: t('routes.demo.comp.treeBasic'), - }, - { - path: 'editTree', - name: t('routes.demo.comp.editTree'), - }, - { - path: 'actionTree', - name: t('routes.demo.comp.actionTree'), - }, - ], - }, - { - name: t('routes.demo.editor.editor'), - path: 'editor', - children: [ - { - path: 'json', - name: t('routes.demo.editor.jsonEditor'), - }, - { - path: 'markdown', - name: t('routes.demo.editor.markdown'), - children: [ - { - path: 'index', - name: t('routes.demo.editor.tinymceBasic'), - }, - { - path: 'editor', - name: t('routes.demo.editor.tinymceForm'), - }, - ], - }, - { - path: 'tinymce', - name: t('routes.demo.editor.tinymce'), - children: [ - { - path: 'index', - name: t('routes.demo.editor.tinymceBasic'), - }, - { - path: 'editor', - name: t('routes.demo.editor.tinymceForm'), - }, - ], - }, - ], - }, - { - path: 'scroll', - name: t('routes.demo.comp.scroll'), - children: [ - { - path: 'basic', - name: t('routes.demo.comp.scrollBasic'), - }, - { - path: 'action', - name: t('routes.demo.comp.scrollAction'), - }, - { - path: 'virtualScroll', - name: t('routes.demo.comp.virtualScroll'), - }, - ], - }, - { - path: 'lazy', - name: t('routes.demo.comp.lazy'), - children: [ - { - path: 'basic', - name: t('routes.demo.comp.lazyBasic'), - }, - { - path: 'transition', - name: t('routes.demo.comp.lazyTransition'), - }, - ], - }, - { - path: 'verify', - name: t('routes.demo.comp.verify'), - children: [ - { - path: 'drag', - name: t('routes.demo.comp.verifyDrag'), - }, - { - path: 'rotate', - name: t('routes.demo.comp.verifyRotate'), - }, - ], - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/excel.ts b/src/router/menus/modules/demo/excel.ts deleted file mode 100644 index d8844daa345..00000000000 --- a/src/router/menus/modules/demo/excel.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 500, - menu: { - name: t('routes.demo.excel.excel'), - path: '/excel', - children: [ - { - path: 'customExport', - name: t('routes.demo.excel.customExport'), - }, - { - path: 'jsonExport', - name: t('routes.demo.excel.jsonExport'), - }, - { - path: 'arrayExport', - name: t('routes.demo.excel.arrayExport'), - }, - { - path: 'importExcel', - name: t('routes.demo.excel.importExcel'), - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/feat.ts b/src/router/menus/modules/demo/feat.ts deleted file mode 100644 index bec820a55ec..00000000000 --- a/src/router/menus/modules/demo/feat.ts +++ /dev/null @@ -1,130 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 19, - menu: { - name: t('routes.demo.feat.feat'), - path: '/feat', - children: [ - { - path: 'icon', - name: t('routes.demo.feat.icon'), - }, - { - path: 'ws', - name: t('routes.demo.feat.ws'), - }, - { - name: t('routes.demo.feat.sessionTimeout'), - path: 'session-timeout', - }, - { - path: 'tabs', - name: t('routes.demo.feat.tabs'), - }, - - { - path: 'context-menu', - name: t('routes.demo.feat.contextMenu'), - }, - { - path: 'download', - name: t('routes.demo.feat.download'), - }, - { - path: 'print', - name: t('routes.demo.feat.print'), - }, - { - path: 'click-out-side', - name: t('routes.demo.feat.clickOutSide'), - }, - { - path: 'img-preview', - name: t('routes.demo.feat.imgPreview'), - }, - { - path: 'copy', - name: t('routes.demo.feat.copy'), - }, - { - path: 'msg', - name: t('routes.demo.feat.msg'), - }, - { - path: 'watermark', - name: t('routes.demo.feat.watermark'), - }, - { - path: 'ripple', - name: t('routes.demo.feat.ripple'), - }, - { - path: 'full-screen', - name: t('routes.demo.feat.fullScreen'), - }, - { - path: 'error-log', - name: t('routes.demo.feat.errorLog'), - }, - - { - name: t('routes.demo.excel.excel'), - path: 'excel', - children: [ - { - path: 'customExport', - name: t('routes.demo.excel.customExport'), - }, - { - path: 'jsonExport', - name: t('routes.demo.excel.jsonExport'), - }, - { - path: 'arrayExport', - name: t('routes.demo.excel.arrayExport'), - }, - { - path: 'importExcel', - name: t('routes.demo.excel.importExcel'), - }, - ], - }, - { - name: t('routes.demo.feat.breadcrumb'), - path: 'breadcrumb', - - children: [ - // { - // path: 'flat', - // name: t('routes.demo.feat.breadcrumbFlat'), - // }, - // { - // path: 'flatDetail', - // name: t('routes.demo.feat.breadcrumbFlatDetail'), - // }, - { - path: 'children', - name: t('routes.demo.feat.breadcrumbChildren'), - }, - ], - }, - { - path: 'testTab', - name: t('routes.demo.feat.tab'), - children: [ - { - path: 'id1', - name: t('routes.demo.feat.tab1'), - }, - { - path: 'id2', - name: t('routes.demo.feat.tab2'), - }, - ], - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/flow.ts b/src/router/menus/modules/demo/flow.ts deleted file mode 100644 index c9e75ba9182..00000000000 --- a/src/router/menus/modules/demo/flow.ts +++ /dev/null @@ -1,17 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 5000, - menu: { - name: t('routes.demo.flow.name'), - path: '/flow', - children: [ - { - path: 'flowChart', - name: t('routes.demo.flow.flowChart'), - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/iframe.ts b/src/router/menus/modules/demo/iframe.ts deleted file mode 100644 index b224b65c29c..00000000000 --- a/src/router/menus/modules/demo/iframe.ts +++ /dev/null @@ -1,25 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 1000, - menu: { - name: t('routes.demo.iframe.frame'), - path: '/frame', - children: [ - { - path: 'doc', - name: t('routes.demo.iframe.doc'), - }, - { - path: 'antv', - name: t('routes.demo.iframe.antv'), - }, - { - path: 'https://vvbin.cn/doc-next/', - name: t('routes.demo.iframe.docExternal'), - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/level.ts b/src/router/menus/modules/demo/level.ts deleted file mode 100644 index f8fb486cfff..00000000000 --- a/src/router/menus/modules/demo/level.ts +++ /dev/null @@ -1,37 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 2000, - menu: { - name: t('routes.demo.level.level'), - path: '/level', - children: [ - { - path: 'menu1', - name: 'Menu1', - children: [ - { - path: 'menu1-1', - name: 'Menu1-1', - children: [ - { - path: 'menu1-1-1', - name: 'Menu1-1-1', - }, - ], - }, - { - path: 'menu1-2', - name: 'Menu1-2', - }, - ], - }, - { - path: 'menu2', - name: 'Menu2', - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/page.ts b/src/router/menus/modules/demo/page.ts deleted file mode 100644 index cd0ec65c057..00000000000 --- a/src/router/menus/modules/demo/page.ts +++ /dev/null @@ -1,121 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 20, - menu: { - name: t('routes.demo.page.page'), - path: '/page-demo', - - children: [ - { - path: 'form', - name: t('routes.demo.page.form'), - - children: [ - { - path: 'basic', - name: t('routes.demo.page.formBasic'), - }, - { - path: 'step', - name: t('routes.demo.page.formStep'), - }, - { - path: 'high', - name: t('routes.demo.page.formHigh'), - }, - ], - }, - { - path: 'desc', - name: t('routes.demo.page.desc'), - - children: [ - { - path: 'basic', - name: t('routes.demo.page.descBasic'), - }, - { - path: 'high', - name: t('routes.demo.page.descHigh'), - }, - ], - }, - { - path: 'result', - name: t('routes.demo.page.result'), - - children: [ - { - path: 'success', - name: t('routes.demo.page.resultSuccess'), - }, - { - path: 'fail', - name: t('routes.demo.page.resultFail'), - }, - ], - }, - { - path: 'exception', - name: t('routes.demo.page.exception'), - children: [ - { - path: '403', - name: t('403'), - }, - { - path: '404', - name: t('404'), - }, - { - path: '500', - name: t('500'), - }, - { - path: 'net-work-error', - name: t('routes.demo.page.netWorkError'), - }, - { - path: 'not-data', - name: t('routes.demo.page.notData'), - }, - ], - }, - { - path: 'account', - name: t('routes.demo.page.account'), - children: [ - { - path: 'center', - name: t('routes.demo.page.accountCenter'), - }, - { - path: 'setting', - name: t('routes.demo.page.accountSetting'), - }, - ], - }, - { - path: 'list', - name: t('routes.demo.page.list'), - children: [ - { - path: 'basic', - name: t('routes.demo.page.listBasic'), - }, - { - path: 'card', - name: t('routes.demo.page.listCard'), - }, - { - path: 'search', - name: t('routes.demo.page.listSearch'), - }, - ], - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/permission.ts b/src/router/menus/modules/demo/permission.ts deleted file mode 100644 index 1fca9b4951c..00000000000 --- a/src/router/menus/modules/demo/permission.ts +++ /dev/null @@ -1,49 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 15, - menu: { - name: t('routes.demo.permission.permission'), - path: '/permission', - children: [ - { - path: 'front', - name: t('routes.demo.permission.front'), - children: [ - { - path: 'page', - name: t('routes.demo.permission.frontPage'), - }, - { - path: 'btn', - name: t('routes.demo.permission.frontBtn'), - }, - { - path: 'auth-pageA', - name: t('routes.demo.permission.frontTestA'), - }, - { - path: 'auth-pageB', - name: t('routes.demo.permission.frontTestB'), - }, - ], - }, - { - path: 'back', - name: t('routes.demo.permission.back'), - children: [ - { - path: 'page', - name: t('routes.demo.permission.backPage'), - }, - { - path: 'btn', - name: t('routes.demo.permission.backBtn'), - }, - ], - }, - ], - }, -}; -export default menu; diff --git a/src/router/menus/modules/demo/setup.ts b/src/router/menus/modules/demo/setup.ts deleted file mode 100644 index b09d1829b07..00000000000 --- a/src/router/menus/modules/demo/setup.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const setup: MenuModule = { - orderNo: 90000, - menu: { - path: '/setup/index', - name: t('routes.demo.setup.page'), - tag: { - content: 'new', - }, - }, -}; -export default setup; diff --git a/src/router/menus/modules/demo/system.ts b/src/router/menus/modules/demo/system.ts deleted file mode 100644 index 7f24d0c9855..00000000000 --- a/src/router/menus/modules/demo/system.ts +++ /dev/null @@ -1,34 +0,0 @@ -import type { MenuModule } from '/@/router/types'; -import { t } from '/@/hooks/web/useI18n'; - -const menu: MenuModule = { - orderNo: 2000, - menu: { - name: t('routes.demo.system.moduleName'), - path: '/system', - children: [ - { - path: 'account', - name: t('routes.demo.system.account'), - }, - { - path: 'role', - name: t('routes.demo.system.role'), - }, - { - path: 'menu', - name: t('routes.demo.system.menu'), - }, - { - path: 'dept', - name: t('routes.demo.system.dept'), - }, - - { - path: 'changePassword', - name: t('routes.demo.system.password'), - }, - ], - }, -}; -export default menu; diff --git a/src/router/routes/basic.ts b/src/router/routes/basic.ts index aabf28b8f4f..397693daf20 100644 --- a/src/router/routes/basic.ts +++ b/src/router/routes/basic.ts @@ -10,6 +10,7 @@ export const PAGE_NOT_FOUND_ROUTE: AppRouteRecordRaw = { meta: { title: 'ErrorPage', hideBreadcrumb: true, + hideMenu: true, }, children: [ { @@ -31,6 +32,7 @@ export const REDIRECT_ROUTE: AppRouteRecordRaw = { meta: { title: REDIRECT_NAME, hideBreadcrumb: true, + hideMenu: true, }, children: [ { diff --git a/src/router/routes/modules/about.ts b/src/router/routes/modules/about.ts index 897a4264759..03cb42511c3 100644 --- a/src/router/routes/modules/about.ts +++ b/src/router/routes/modules/about.ts @@ -9,8 +9,10 @@ const dashboard: AppRouteModule = { component: LAYOUT, redirect: '/about/index', meta: { + hideChildrenInMenu: true, icon: 'simple-icons:about-dot-me', title: t('routes.dashboard.about'), + orderNo: 100000, }, children: [ { diff --git a/src/router/routes/modules/dashboard.ts b/src/router/routes/modules/dashboard.ts index 7c050805395..12df83cd3b0 100644 --- a/src/router/routes/modules/dashboard.ts +++ b/src/router/routes/modules/dashboard.ts @@ -9,6 +9,7 @@ const dashboard: AppRouteModule = { component: LAYOUT, redirect: '/dashboard/analysis', meta: { + orderNo: 10, icon: 'ion:grid-outline', title: t('routes.dashboard.dashboard'), }, diff --git a/src/router/routes/modules/demo/charts.ts b/src/router/routes/modules/demo/charts.ts index ac0a58a4509..c36b5eed24b 100644 --- a/src/router/routes/modules/demo/charts.ts +++ b/src/router/routes/modules/demo/charts.ts @@ -9,6 +9,7 @@ const charts: AppRouteModule = { component: LAYOUT, redirect: '/charts/echarts/map', meta: { + orderNo: 500, icon: 'ion:bar-chart-outline', title: t('routes.demo.charts.charts'), }, diff --git a/src/router/routes/modules/demo/comp.ts b/src/router/routes/modules/demo/comp.ts index 88e9608a033..c7648ba7fec 100644 --- a/src/router/routes/modules/demo/comp.ts +++ b/src/router/routes/modules/demo/comp.ts @@ -9,6 +9,7 @@ const comp: AppRouteModule = { component: LAYOUT, redirect: '/comp/basic', meta: { + orderNo: 30, icon: 'ion:layers-outline', title: t('routes.demo.comp.comp'), }, diff --git a/src/router/routes/modules/demo/feat.ts b/src/router/routes/modules/demo/feat.ts index 6a51be42fbe..48438a24893 100644 --- a/src/router/routes/modules/demo/feat.ts +++ b/src/router/routes/modules/demo/feat.ts @@ -9,6 +9,7 @@ const feat: AppRouteModule = { component: LAYOUT, redirect: '/feat/icon', meta: { + orderNo: 19, icon: 'ion:git-compare-outline', title: t('routes.demo.feat.feat'), }, diff --git a/src/router/routes/modules/demo/flow.ts b/src/router/routes/modules/demo/flow.ts index c4bc8911c6b..4654c9b9ebf 100644 --- a/src/router/routes/modules/demo/flow.ts +++ b/src/router/routes/modules/demo/flow.ts @@ -9,6 +9,7 @@ const charts: AppRouteModule = { component: LAYOUT, redirect: '/flow/flowChart', meta: { + orderNo: 5000, icon: 'tabler:chart-dots', title: t('routes.demo.flow.name'), }, diff --git a/src/router/routes/modules/demo/iframe.ts b/src/router/routes/modules/demo/iframe.ts index 0e8c479e9ab..95b21d68102 100644 --- a/src/router/routes/modules/demo/iframe.ts +++ b/src/router/routes/modules/demo/iframe.ts @@ -10,6 +10,7 @@ const iframe: AppRouteModule = { component: LAYOUT, redirect: '/frame/doc', meta: { + orderNo: 1000, icon: 'ion:tv-outline', title: t('routes.demo.iframe.frame'), }, diff --git a/src/router/routes/modules/demo/level.ts b/src/router/routes/modules/demo/level.ts index f95e5c0a5ca..3cee3755d59 100644 --- a/src/router/routes/modules/demo/level.ts +++ b/src/router/routes/modules/demo/level.ts @@ -9,6 +9,7 @@ const permission: AppRouteModule = { component: LAYOUT, redirect: '/level/menu1/menu1-1/menu1-1-1', meta: { + orderNo: 2000, icon: 'ion:menu-outline', title: t('routes.demo.level.level'), }, diff --git a/src/router/routes/modules/demo/page.ts b/src/router/routes/modules/demo/page.ts index c9e99e9483c..17ab276a988 100644 --- a/src/router/routes/modules/demo/page.ts +++ b/src/router/routes/modules/demo/page.ts @@ -12,6 +12,7 @@ const page: AppRouteModule = { component: LAYOUT, redirect: '/page-demo/form/basic', meta: { + orderNo: 20, icon: 'ion:aperture-outline', title: t('routes.demo.page.page'), }, diff --git a/src/router/routes/modules/demo/permission.ts b/src/router/routes/modules/demo/permission.ts index d46f5208ce3..e8763628f9a 100644 --- a/src/router/routes/modules/demo/permission.ts +++ b/src/router/routes/modules/demo/permission.ts @@ -10,6 +10,7 @@ const permission: AppRouteModule = { component: LAYOUT, redirect: '/permission/front/page', meta: { + orderNo: 15, icon: 'ion:key-outline', title: t('routes.demo.permission.permission'), }, diff --git a/src/router/routes/modules/demo/setup.ts b/src/router/routes/modules/demo/setup.ts index 04e152a6ef6..b58f9af2a01 100644 --- a/src/router/routes/modules/demo/setup.ts +++ b/src/router/routes/modules/demo/setup.ts @@ -9,6 +9,8 @@ const setup: AppRouteModule = { component: LAYOUT, redirect: '/setup/index', meta: { + orderNo: 90000, + hideChildrenInMenu: true, icon: 'simple-icons:about-dot-me', title: t('routes.demo.setup.page'), }, diff --git a/src/router/routes/modules/demo/system.ts b/src/router/routes/modules/demo/system.ts index 479353d6428..66e19da23c9 100644 --- a/src/router/routes/modules/demo/system.ts +++ b/src/router/routes/modules/demo/system.ts @@ -9,6 +9,7 @@ const system: AppRouteModule = { component: LAYOUT, redirect: '/system/account', meta: { + orderNo: 2000, icon: 'ion:settings-outline', title: t('routes.demo.system.moduleName'), }, @@ -26,6 +27,7 @@ const system: AppRouteModule = { path: 'account_detail/:id', name: 'AccountDetail', meta: { + hideMenu: true, title: t('routes.demo.system.account_detail'), ignoreKeepAlive: true, showMenu: false, diff --git a/src/settings/projectSetting.ts b/src/settings/projectSetting.ts index 4c9d412ae40..0d4415b89d8 100644 --- a/src/settings/projectSetting.ts +++ b/src/settings/projectSetting.ts @@ -24,7 +24,7 @@ const setting: ProjectConfig = { settingButtonPosition: SettingButtonPositionEnum.AUTO, // Permission mode - permissionMode: PermissionModeEnum.ROLE, + permissionMode: PermissionModeEnum.ROUTE_MAPPING, // Permission-related cache is stored in sessionStorage or localStorage permissionCacheType: CacheTypeEnum.LOCAL, diff --git a/src/store/modules/app.ts b/src/store/modules/app.ts index cb759c3bf6c..72f9bf6c3cd 100644 --- a/src/store/modules/app.ts +++ b/src/store/modules/app.ts @@ -103,6 +103,6 @@ export const useAppStore = defineStore({ }); // Need to be used outside the setup -export function useAppStoreWidthOut() { +export function useAppStoreWithOut() { return useAppStore(store); } diff --git a/src/store/modules/permission.ts b/src/store/modules/permission.ts index 380f0356089..e9abbf00b88 100644 --- a/src/store/modules/permission.ts +++ b/src/store/modules/permission.ts @@ -4,7 +4,7 @@ import { defineStore } from 'pinia'; import { store } from '/@/store'; import { useI18n } from '/@/hooks/web/useI18n'; import { useUserStore } from './user'; -import { useAppStoreWidthOut } from './app'; +import { useAppStoreWithOut } from './app'; import { toRaw } from 'vue'; import { transformObjToRoute, flatMultiLevelRoutes } from '/@/router/helper/routeHelper'; import { transformRouteToMenu } from '/@/router/helper/menuHelper'; @@ -32,6 +32,7 @@ interface PermissionState { lastBuildMenuTime: number; // Backstage menu list backMenuList: Menu[]; + frontMenuList: Menu[]; } export const usePermissionStore = defineStore({ id: 'app-permission', @@ -43,6 +44,8 @@ export const usePermissionStore = defineStore({ lastBuildMenuTime: 0, // Backstage menu list backMenuList: [], + // menu List + frontMenuList: [], }), getters: { getPermCodeList(): string[] | number[] { @@ -51,6 +54,9 @@ export const usePermissionStore = defineStore({ getBackMenuList(): Menu[] { return this.backMenuList; }, + getFrontMenuList(): Menu[] { + return this.frontMenuList; + }, getLastBuildMenuTime(): number { return this.lastBuildMenuTime; }, @@ -68,6 +74,10 @@ export const usePermissionStore = defineStore({ list?.length > 0 && this.setLastBuildMenuTime(); }, + setFrontMenuList(list: Menu[]) { + this.frontMenuList = list; + }, + setLastBuildMenuTime() { this.lastBuildMenuTime = new Date().getTime(); }, @@ -88,52 +98,70 @@ export const usePermissionStore = defineStore({ async buildRoutesAction(): Promise { const { t } = useI18n(); const userStore = useUserStore(); - const appStore = useAppStoreWidthOut(); + const appStore = useAppStoreWithOut(); let routes: AppRouteRecordRaw[] = []; const roleList = toRaw(userStore.getRoleList) || []; const { permissionMode = projectSetting.permissionMode } = appStore.getProjectConfig; - // role permissions - if (permissionMode === PermissionModeEnum.ROLE) { - const routeFilter = (route: AppRouteRecordRaw) => { - const { meta } = route; - const { roles } = meta || {}; - if (!roles) return true; - return roleList.some((role) => roles.includes(role)); - }; - routes = filter(asyncRoutes, routeFilter); - routes = routes.filter(routeFilter); - // Convert multi-level routing to level 2 routing - routes = flatMultiLevelRoutes(routes); + + const routeFilter = (route: AppRouteRecordRaw) => { + const { meta } = route; + const { roles } = meta || {}; + if (!roles) return true; + return roleList.some((role) => roles.includes(role)); + }; + + switch (permissionMode) { + case PermissionModeEnum.ROLE: + routes = filter(asyncRoutes, routeFilter); + routes = routes.filter(routeFilter); + // Convert multi-level routing to level 2 routing + routes = flatMultiLevelRoutes(routes); + break; + + case PermissionModeEnum.ROUTE_MAPPING: + routes = filter(asyncRoutes, routeFilter); + routes = routes.filter(routeFilter); + const menuList = transformRouteToMenu(asyncRoutes); + menuList.sort((a, b) => { + return (a.meta?.orderNo || 0) - (b.meta?.orderNo || 0); + }); + this.setFrontMenuList(menuList); + // Convert multi-level routing to level 2 routing + routes = flatMultiLevelRoutes(routes); + break; + // If you are sure that you do not need to do background dynamic permissions, please comment the entire judgment below - } else if (permissionMode === PermissionModeEnum.BACK) { - const { createMessage } = useMessage(); - - createMessage.loading({ - content: t('sys.app.menuLoading'), - duration: 1, - }); - - // !Simulate to obtain permission codes from the background, - // this function may only need to be executed once, and the actual project can be put at the right time by itself - let routeList: AppRouteRecordRaw[] = []; - try { - this.changePermissionCode(); - routeList = (await getMenuList()) as AppRouteRecordRaw[]; - } catch (error) { - console.error(error); - } - - // Dynamically introduce components - routeList = transformObjToRoute(routeList); - - // Background routing to menu structure - const backMenuList = transformRouteToMenu(routeList); - this.setBackMenuList(backMenuList); - - routeList = flatMultiLevelRoutes(routeList); - routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; + case PermissionModeEnum.BACK: + const { createMessage } = useMessage(); + + createMessage.loading({ + content: t('sys.app.menuLoading'), + duration: 1, + }); + + // !Simulate to obtain permission codes from the background, + // this function may only need to be executed once, and the actual project can be put at the right time by itself + let routeList: AppRouteRecordRaw[] = []; + try { + this.changePermissionCode(); + routeList = (await getMenuList()) as AppRouteRecordRaw[]; + } catch (error) { + console.error(error); + } + + // Dynamically introduce components + routeList = transformObjToRoute(routeList); + + // Background routing to menu structure + const backMenuList = transformRouteToMenu(routeList); + this.setBackMenuList(backMenuList); + + routeList = flatMultiLevelRoutes(routeList); + routes = [PAGE_NOT_FOUND_ROUTE, ...routeList]; + break; } + routes.push(ERROR_LOG_ROUTE); return routes; }, @@ -141,6 +169,6 @@ export const usePermissionStore = defineStore({ }); // Need to be used outside the setup -export function usePermissionStoreWidthOut() { +export function usePermissionStoreWithOut() { return usePermissionStore(store); } diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index 6f8ac2b76da..bfef499718b 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -128,6 +128,6 @@ export const useUserStore = defineStore({ }); // Need to be used outside the setup -export function useUserStoreWidthOut() { +export function useUserStoreWithOut() { return useUserStore(store); } diff --git a/src/utils/http/axios/checkStatus.ts b/src/utils/http/axios/checkStatus.ts index f6b65b9bf9f..1c132ee766d 100644 --- a/src/utils/http/axios/checkStatus.ts +++ b/src/utils/http/axios/checkStatus.ts @@ -3,7 +3,7 @@ import { useMessage } from '/@/hooks/web/useMessage'; import { useI18n } from '/@/hooks/web/useI18n'; // import router from '/@/router'; // import { PageEnum } from '/@/enums/pageEnum'; -import { useUserStoreWidthOut } from '/@/store/modules/user'; +import { useUserStoreWithOut } from '/@/store/modules/user'; import projectSetting from '/@/settings/projectSetting'; import { SessionTimeoutProcessingEnum } from '/@/enums/appEnum'; @@ -17,7 +17,7 @@ export function checkStatus( errorMessageMode: ErrorMessageMode = 'message' ): void { const { t } = useI18n(); - const userStore = useUserStoreWidthOut(); + const userStore = useUserStoreWithOut(); let errMessage = ''; switch (status) { diff --git a/types/vue-router.d.ts b/types/vue-router.d.ts index c8422750e2f..525679c27a7 100644 --- a/types/vue-router.d.ts +++ b/types/vue-router.d.ts @@ -2,6 +2,7 @@ export {}; declare module 'vue-router' { interface RouteMeta extends Record { + orderNo?: number; // title title: string; // Whether to ignore permissions