diff --git a/src/router/guard/index.ts b/src/router/guard/index.ts index 532078b94..37ed7e5d3 100644 --- a/src/router/guard/index.ts +++ b/src/router/guard/index.ts @@ -1,24 +1,17 @@ import type { Router } from 'vue-router'; import { useTitle } from '@vueuse/core'; -import { useRouteStore } from '@/store'; +import { handlePagePermission } from './permission'; /** * 路由守卫函数 * @param router - 路由实例 */ export function createRouterGuide(router: Router) { - const routeStore = useRouteStore(); - const { initDynamicRoute } = useRouteStore(); - router.beforeEach(async (to, from, next) => { - if (!routeStore.isAddedDynamicRoute) { - await initDynamicRoute(router); - next(); - return; - } // 开始 loadingBar window.$loadingBar?.start(); - next(); + // 页面跳转权限处理 + await handlePagePermission(to, from, next, router); }); router.afterEach(to => { // 设置document title diff --git a/src/router/guard/permission.ts b/src/router/guard/permission.ts index ff8b4c563..7734075ba 100644 --- a/src/router/guard/permission.ts +++ b/src/router/guard/permission.ts @@ -1 +1,71 @@ -export default {}; +import type { Router, RouteLocationNormalized, NavigationGuardNext } from 'vue-router'; +import { useAuthStore, useRouteStore } from '@/store'; +import { exeStrategyActions } from '@/utils'; + +/** 处理路由页面的权限 */ +export async function handlePagePermission( + to: RouteLocationNormalized, + from: RouteLocationNormalized, + next: NavigationGuardNext, + router: Router +) { + const auth = useAuthStore(); + const route = useRouteStore(); + const { initDynamicRoute, getRouteName } = useRouteStore(); + + const permissions = to.meta.permissions || []; + const needLogin = Boolean(to.meta?.requiresAuth) || Boolean(permissions.length); + const hasPermission = !permissions.length || permissions.includes(auth.role); + + if (!route.isAddedDynamicRoute) { + // 添加动态路由 + await initDynamicRoute(router); + + if (to.name === getRouteName('redirect-not-found')) { + // 动态路由没有加载导致重定向到了redirect-not-found,等待动态路由加载好了,回到重定向之前的路由 + next({ path: to.fullPath, replace: true, query: to.query }); + return; + } + } + + const actions: Common.StrategyAction[] = [ + // 已登录状态跳转登录页,跳转至首页 + [ + auth.isLogin && to.name === getRouteName('login'), + () => { + next({ name: getRouteName('root') }); + } + ], + // 不需要登录权限的页面直接通行 + [ + !needLogin, + () => { + next(); + } + ], + // 未登录状态进入需要登录权限的页面 + [ + !auth.isLogin && needLogin, + () => { + const redirect = to.fullPath; + next({ name: getRouteName('login'), query: { redirect } }); + } + ], + // 登录状态进入需要登录权限的页面,有权限直接通行 + [ + auth.isLogin && needLogin && hasPermission, + () => { + next(); + } + ], + [ + // 登录状态进入需要登录权限的页面,无权限,重定向到无权限页面 + auth.isLogin && needLogin && !hasPermission, + () => { + next({ name: getRouteName('no-permission') }); + } + ] + ]; + + exeStrategyActions(actions); +} diff --git a/src/store/modules/route/index.ts b/src/store/modules/route/index.ts index 68d8fcf28..22c18d64a 100644 --- a/src/store/modules/route/index.ts +++ b/src/store/modules/route/index.ts @@ -17,9 +17,15 @@ interface RouteStore { isAddedDynamicRoute: Ref; /** 初始化动态路由 */ initDynamicRoute(router: Router): Promise; - /** 获取路由名称(优先使用) */ + /** + * 获取路由名称 + * @description getRouteName 和 getRoutePath 优先使用 getRouteName + */ getRouteName(key: AuthRoute.RouteKey): AuthRoute.RouteKey; - /** 获取路由路径 */ + /** + * 获取路由路径 + * @description getRouteName 和 getRoutePath 优先使用 getRouteName + */ getRoutePath(key: AuthRoute.RouteKey): AuthRoute.RoutePath<''> | undefined; /** 获取路由路径 */ getRouteTitle(key: AuthRoute.RouteKey): string | undefined; diff --git a/src/utils/router/helpers.ts b/src/utils/router/helpers.ts index db71b76bd..2c3762d05 100644 --- a/src/utils/router/helpers.ts +++ b/src/utils/router/helpers.ts @@ -44,6 +44,7 @@ export function transformAuthRouteToVueRoute(item: AuthRoute.Route) { itemRoute.children = [ { path: '', + name: item.name, component: getViewComponent(item.name) } ];