feat: Dynamically get the menu from the back end
This commit is contained in:
@@ -3,16 +3,14 @@ import type { Router } from 'vue-router';
|
||||
import { LOGIN_PATH } from '@vben/constants';
|
||||
import { $t } from '@vben/locales';
|
||||
import { startProgress, stopProgress } from '@vben/utils';
|
||||
import { generatorMenus, generatorRoutes } from '@vben-core/helpers';
|
||||
import { preferences } from '@vben-core/preferences';
|
||||
import { useAccessStore } from '@vben-core/stores';
|
||||
|
||||
import { useTitle } from '@vueuse/core';
|
||||
|
||||
import { generateAccess } from '#/forward/access';
|
||||
import { dynamicRoutes, essentialsRouteNames } from '#/router/routes';
|
||||
|
||||
const forbiddenPage = () => import('#/views/_essential/fallback/forbidden.vue');
|
||||
|
||||
/**
|
||||
* 通用守卫配置
|
||||
* @param router
|
||||
@@ -96,22 +94,16 @@ function setupAccessGuard(router: Router) {
|
||||
// 当前登录用户拥有的角色标识列表
|
||||
const userRoles = accessStore.getUserRoles;
|
||||
|
||||
const accessibleRoutes = await generatorRoutes(
|
||||
dynamicRoutes,
|
||||
userRoles,
|
||||
// 如果 route.meta.menuVisibleWithForbidden = true
|
||||
// 生成菜单和路由
|
||||
const { accessibleMenus, accessibleRoutes } = await generateAccess({
|
||||
roles: userRoles,
|
||||
router,
|
||||
// 则会在菜单中显示,但是访问会被重定向到403
|
||||
// 这里可以指定403页面
|
||||
forbiddenPage,
|
||||
);
|
||||
// 动态添加到router实例内
|
||||
accessibleRoutes.forEach((route) => router.addRoute(route));
|
||||
|
||||
// 生成菜单
|
||||
const menus = await generatorMenus(accessibleRoutes, router);
|
||||
routes: dynamicRoutes,
|
||||
});
|
||||
|
||||
// 保存菜单信息和路由信息
|
||||
accessStore.setAccessMenus(menus);
|
||||
accessStore.setAccessMenus(accessibleMenus);
|
||||
accessStore.setAccessRoutes(accessibleRoutes);
|
||||
const redirectPath = (from.query.redirect ?? to.path) as string;
|
||||
|
||||
|
@@ -15,7 +15,7 @@ const fallbackNotFoundRoute: RouteRecordRaw = {
|
||||
hideInTab: true,
|
||||
title: '404',
|
||||
},
|
||||
name: 'Fallback',
|
||||
name: 'FallbackNotFound',
|
||||
path: '/:path(.*)*',
|
||||
};
|
||||
|
||||
|
@@ -15,14 +15,108 @@ const routes: RouteRecordRaw[] = [
|
||||
},
|
||||
name: 'Demos',
|
||||
path: '/demos',
|
||||
redirect: '/demos/fallback/403',
|
||||
redirect: '/demos/access/frontend',
|
||||
children: [
|
||||
{
|
||||
meta: {
|
||||
icon: 'mdi:shield-key-outline',
|
||||
title: $t('page.demos.access.title'),
|
||||
},
|
||||
name: 'Access',
|
||||
path: '/access',
|
||||
redirect: '/access/frontend',
|
||||
children: [
|
||||
{
|
||||
name: 'AccessFrontend',
|
||||
path: 'frontend',
|
||||
meta: {
|
||||
icon: 'mdi:table-key',
|
||||
title: $t('page.demos.access.frontend-control'),
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'AccessFrontendPageControl',
|
||||
path: 'page-control',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/index.vue'),
|
||||
meta: {
|
||||
icon: 'mdi:page-previous-outline',
|
||||
title: $t('page.demos.access.page'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessFrontendButtonControl',
|
||||
path: 'button-control',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/button-control.vue'),
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: $t('page.demos.access.button'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessFrontendTest1',
|
||||
path: 'access-test-1',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/access-test-1.vue'),
|
||||
meta: {
|
||||
authority: ['admin'],
|
||||
icon: 'mdi:button-cursor',
|
||||
title: $t('page.demos.access.access-test-1'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessFrontendTest2',
|
||||
path: 'access-test-2',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/access-test-2.vue'),
|
||||
meta: {
|
||||
authority: ['user'],
|
||||
icon: 'mdi:button-cursor',
|
||||
title: $t('page.demos.access.access-test-2'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'AccessBackend',
|
||||
path: 'backend',
|
||||
component: () => import('#/views/demos/access/backend/index.vue'),
|
||||
meta: {
|
||||
icon: 'mdi:cloud-key-outline',
|
||||
title: $t('page.demos.access.backend-control'),
|
||||
},
|
||||
children: [
|
||||
{
|
||||
name: 'AccessBackendPageControl',
|
||||
path: 'page-control',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/index.vue'),
|
||||
meta: {
|
||||
icon: 'mdi:page-previous-outline',
|
||||
title: $t('page.demos.access.page'),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'AccessBackendButtonControl',
|
||||
path: 'button-control',
|
||||
component: () =>
|
||||
import('#/views/demos/access/frontend/button-control.vue'),
|
||||
meta: {
|
||||
icon: 'mdi:button-cursor',
|
||||
title: $t('page.demos.access.button'),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
meta: {
|
||||
icon: 'mdi:lightbulb-error-outline',
|
||||
title: $t('page.demos.fallback.title'),
|
||||
},
|
||||
name: 'FallbackLayout',
|
||||
name: 'Fallback',
|
||||
path: '/fallback',
|
||||
redirect: '/fallback/403',
|
||||
children: [
|
||||
|
Reference in New Issue
Block a user