refactor(projects): new route guard
This commit is contained in:
parent
c11d56da29
commit
37d20b8e0d
2
.env
2
.env
@ -12,7 +12,7 @@ VITE_ICON_PREFIX=icon
|
||||
VITE_ICON_LOCAL_PREFIX=icon-local
|
||||
|
||||
# auth route mode: static | dynamic
|
||||
VITE_AUTH_ROUTE_MODE=dynamic
|
||||
VITE_AUTH_ROUTE_MODE=static
|
||||
|
||||
# static auth route home
|
||||
VITE_ROUTE_HOME=home
|
||||
|
@ -13,7 +13,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: '403',
|
||||
i18nKey: 'route.403',
|
||||
constant: true
|
||||
constant: true,
|
||||
hideInMenu: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -23,7 +24,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: '404',
|
||||
i18nKey: 'route.404',
|
||||
constant: true
|
||||
constant: true,
|
||||
hideInMenu: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -33,7 +35,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: '500',
|
||||
i18nKey: 'route.500',
|
||||
constant: true
|
||||
constant: true,
|
||||
hideInMenu: true
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -184,7 +187,8 @@ export const generatedRoutes: GeneratedRoute[] = [
|
||||
meta: {
|
||||
title: 'login',
|
||||
i18nKey: 'route.login',
|
||||
constant: true
|
||||
constant: true,
|
||||
hideInMenu: true
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
import type { Router } from 'vue-router';
|
||||
import { createRouteGuard } from './route';
|
||||
import { createProgressGuard } from './progress';
|
||||
import { createDocumentTitleGuard } from './title';
|
||||
import { createPermissionGuard } from './permission';
|
||||
// import { createPermissionGuard } from './permission';
|
||||
|
||||
/**
|
||||
* Router guard
|
||||
@ -10,6 +11,7 @@ import { createPermissionGuard } from './permission';
|
||||
*/
|
||||
export function createRouterGuard(router: Router) {
|
||||
createProgressGuard(router);
|
||||
createPermissionGuard(router);
|
||||
createRouteGuard(router);
|
||||
// createPermissionGuard(router);
|
||||
createDocumentTitleGuard(router);
|
||||
}
|
||||
|
@ -1,142 +0,0 @@
|
||||
import type { NavigationGuardNext, RouteLocationNormalized, Router } from 'vue-router';
|
||||
import type { RouteKey, RoutePath } from '@elegant-router/types';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { localStg } from '@/utils/storage';
|
||||
|
||||
export function createPermissionGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const pass = await createAuthRouteGuard(to, from, next);
|
||||
|
||||
if (!pass) return;
|
||||
|
||||
// 1. route with href
|
||||
if (to.meta.href) {
|
||||
window.open(to.meta.href, '_blank');
|
||||
next({ path: from.fullPath, replace: true, query: from.query, hash: to.hash });
|
||||
}
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
const needLogin = !to.meta.constant;
|
||||
const routeRoles = to.meta.roles || [];
|
||||
const rootRoute: RouteKey = 'root';
|
||||
const loginRoute: RouteKey = 'login';
|
||||
const noPermissionRoute: RouteKey = '403';
|
||||
|
||||
// check whether the user has permission to access the route
|
||||
// 1. if the route's "roles" is empty, then it is allowed to access
|
||||
// 2. if the user is super admin in static route, then it is allowed to access
|
||||
// 3. if the user's role is included in the route's "roles", then it is allowed to access
|
||||
const hasPermission =
|
||||
!routeRoles.length || authStore.isStaticSuper || authStore.userInfo.roles.some(role => routeRoles.includes(role));
|
||||
|
||||
const strategicPatterns: CommonType.StrategicPattern[] = [
|
||||
// 1. if it is login route when logged in, change to the root page
|
||||
{
|
||||
condition: isLogin && to.name === loginRoute,
|
||||
callback: () => {
|
||||
next({ name: rootRoute });
|
||||
}
|
||||
},
|
||||
// 2. if is is constant route, then it is allowed to access directly
|
||||
{
|
||||
condition: !needLogin,
|
||||
callback: () => {
|
||||
next();
|
||||
}
|
||||
},
|
||||
// 3. if the route need login but the user is not logged in, then switch to the login page
|
||||
{
|
||||
condition: !isLogin && needLogin,
|
||||
callback: () => {
|
||||
next({ name: loginRoute, query: { redirect: to.fullPath } });
|
||||
}
|
||||
},
|
||||
// 4. if the user is logged in and has permission, then it is allowed to access
|
||||
{
|
||||
condition: isLogin && needLogin && hasPermission,
|
||||
callback: () => {
|
||||
next();
|
||||
}
|
||||
},
|
||||
// 5. if the user is logged in but does not have permission, then switch to the 403 page
|
||||
{
|
||||
condition: isLogin && needLogin && !hasPermission,
|
||||
callback: () => {
|
||||
next({ name: noPermissionRoute });
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
strategicPatterns.some(({ condition, callback }) => {
|
||||
if (condition) {
|
||||
callback();
|
||||
}
|
||||
|
||||
return condition;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async function createAuthRouteGuard(
|
||||
to: RouteLocationNormalized,
|
||||
_from: RouteLocationNormalized,
|
||||
next: NavigationGuardNext
|
||||
) {
|
||||
const notFoundRoute: RouteKey = 'not-found';
|
||||
const isNotFoundRoute = to.name === notFoundRoute;
|
||||
|
||||
// 1. If the route is the constant route but is not the "not-found" route, then it is allowed to access.
|
||||
if (to.meta.constant && !isNotFoundRoute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 2. If the auth route is initialized but is not the "not-found" route, then it is allowed to access.
|
||||
const routeStore = useRouteStore();
|
||||
if (routeStore.isInitAuthRoute && !isNotFoundRoute) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// 3. If the route is initialized, check whether the route exists.
|
||||
if (routeStore.isInitAuthRoute && isNotFoundRoute) {
|
||||
const exist = await routeStore.getIsAuthRouteExist(to.path as RoutePath);
|
||||
|
||||
if (exist) {
|
||||
const noPermissionRoute: RouteKey = '403';
|
||||
|
||||
next({ name: noPermissionRoute });
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 4. If the user is not logged in, then redirect to the login page.
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
if (!isLogin) {
|
||||
const loginRoute: RouteKey = 'login';
|
||||
const redirect = to.fullPath;
|
||||
|
||||
next({ name: loginRoute, query: { redirect } });
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 5. init auth route
|
||||
await routeStore.initAuthRoute();
|
||||
|
||||
// 6. the route is caught by the "not-found" route because the auto route is not initialized. after the auto route is initialized, redirect to the original route.
|
||||
if (isNotFoundRoute) {
|
||||
const rootRoute: RouteKey = 'root';
|
||||
const path = to.redirectedFrom?.name === rootRoute ? '/' : to.fullPath;
|
||||
|
||||
next({ path, replace: true, query: to.query, hash: to.hash });
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
196
src/router/guard/route.ts
Normal file
196
src/router/guard/route.ts
Normal file
@ -0,0 +1,196 @@
|
||||
import type {
|
||||
LocationQueryRaw,
|
||||
NavigationGuardNext,
|
||||
RouteLocationNormalized,
|
||||
RouteLocationRaw,
|
||||
Router
|
||||
} from 'vue-router';
|
||||
import type { RouteKey, RoutePath } from '@elegant-router/types';
|
||||
import { useAuthStore } from '@/store/modules/auth';
|
||||
import { useRouteStore } from '@/store/modules/route';
|
||||
import { localStg } from '@/utils/storage';
|
||||
|
||||
/**
|
||||
* create route guard
|
||||
*
|
||||
* @param router router instance
|
||||
*/
|
||||
export function createRouteGuard(router: Router) {
|
||||
router.beforeEach(async (to, from, next) => {
|
||||
const location = await initRoute(to);
|
||||
|
||||
if (location) {
|
||||
next(location);
|
||||
return;
|
||||
}
|
||||
|
||||
const authStore = useAuthStore();
|
||||
|
||||
const rootRoute: RouteKey = 'root';
|
||||
const loginRoute: RouteKey = 'login';
|
||||
const noAuthorizationRoute: RouteKey = '403';
|
||||
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
const needLogin = !to.meta.constant;
|
||||
const routeRoles = to.meta.roles || [];
|
||||
|
||||
const hasRole = authStore.userInfo.roles.some(role => routeRoles.includes(role));
|
||||
|
||||
const hasAuth = authStore.isStaticSuper || !routeRoles.length || hasRole;
|
||||
|
||||
const routeSwitches: CommonType.StrategicPattern[] = [
|
||||
// if it is login route when logged in, then switch to the root page
|
||||
{
|
||||
condition: isLogin && to.name === loginRoute,
|
||||
callback: () => {
|
||||
next({ name: rootRoute });
|
||||
}
|
||||
},
|
||||
// if is is constant route, then it is allowed to access directly
|
||||
{
|
||||
condition: !needLogin,
|
||||
callback: () => {
|
||||
handleRouteSwitch(to, from, next);
|
||||
}
|
||||
},
|
||||
// if the route need login but the user is not logged in, then switch to the login page
|
||||
{
|
||||
condition: !isLogin && needLogin,
|
||||
callback: () => {
|
||||
next({ name: loginRoute, query: { redirect: to.fullPath } });
|
||||
}
|
||||
},
|
||||
// if the user is logged in and has authorization, then it is allowed to access
|
||||
{
|
||||
condition: isLogin && needLogin && hasAuth,
|
||||
callback: () => {
|
||||
handleRouteSwitch(to, from, next);
|
||||
}
|
||||
},
|
||||
// if the user is logged in but does not have authorization, then switch to the 403 page
|
||||
{
|
||||
condition: isLogin && needLogin && !hasAuth,
|
||||
callback: () => {
|
||||
next({ name: noAuthorizationRoute });
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
routeSwitches.some(({ condition, callback }) => {
|
||||
if (condition) {
|
||||
callback();
|
||||
}
|
||||
|
||||
return condition;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize route
|
||||
*
|
||||
* @param to to route
|
||||
*/
|
||||
async function initRoute(to: RouteLocationNormalized): Promise<RouteLocationRaw | null> {
|
||||
const routeStore = useRouteStore();
|
||||
|
||||
const notFoundRoute: RouteKey = 'not-found';
|
||||
const isNotFoundRoute = to.name === notFoundRoute;
|
||||
|
||||
// if the constant route is not initialized, then initialize the constant route
|
||||
if (!routeStore.isInitConstantRoute) {
|
||||
await routeStore.initConstantRoute();
|
||||
|
||||
// the route is captured by the "not-found" route because the constant route is not initialized
|
||||
// after the constant route is initialized, redirect to the original route
|
||||
if (isNotFoundRoute) {
|
||||
const path = to.fullPath;
|
||||
|
||||
const location: RouteLocationRaw = {
|
||||
path,
|
||||
replace: true,
|
||||
query: to.query,
|
||||
hash: to.hash
|
||||
};
|
||||
|
||||
return location;
|
||||
}
|
||||
}
|
||||
|
||||
// if the route is the constant route but is not the "not-found" route, then it is allowed to access.
|
||||
if (to.meta.constant && !isNotFoundRoute) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// the auth route is initialized
|
||||
// it is not the "not-found" route, then it is allowed to access
|
||||
if (routeStore.isInitAuthRoute && !isNotFoundRoute) {
|
||||
return null;
|
||||
}
|
||||
// it is captured by the "not-found" route, then check whether the route exists
|
||||
if (routeStore.isInitAuthRoute && isNotFoundRoute) {
|
||||
const exist = await routeStore.getIsAuthRouteExist(to.path as RoutePath);
|
||||
const noPermissionRoute: RouteKey = '403';
|
||||
|
||||
if (exist) {
|
||||
const location: RouteLocationRaw = {
|
||||
name: noPermissionRoute
|
||||
};
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// if the auth route is not initialized, then initialize the auth route
|
||||
const isLogin = Boolean(localStg.get('token'));
|
||||
// initialize the auth route requires the user to be logged in, if not, redirect to the login page
|
||||
if (!isLogin) {
|
||||
const loginRoute: RouteKey = 'login';
|
||||
const redirect = to.fullPath;
|
||||
|
||||
const query: LocationQueryRaw = to.name !== loginRoute ? { redirect } : {};
|
||||
|
||||
const location: RouteLocationRaw = {
|
||||
name: loginRoute,
|
||||
query
|
||||
};
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
// initialize the auth route
|
||||
await routeStore.initAuthRoute();
|
||||
|
||||
// the route is captured by the "not-found" route because the auth route is not initialized
|
||||
// after the auth route is initialized, redirect to the original route
|
||||
if (isNotFoundRoute) {
|
||||
const rootRoute: RouteKey = 'root';
|
||||
const path = to.redirectedFrom?.name === rootRoute ? '/' : to.fullPath;
|
||||
|
||||
const location: RouteLocationRaw = {
|
||||
path,
|
||||
replace: true,
|
||||
query: to.query,
|
||||
hash: to.hash
|
||||
};
|
||||
|
||||
return location;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function handleRouteSwitch(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) {
|
||||
// route with href
|
||||
if (to.meta.href) {
|
||||
window.open(to.meta.href, '_blank');
|
||||
|
||||
next({ path: from.fullPath, replace: true, query: from.query, hash: to.hash });
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
}
|
@ -6,7 +6,7 @@ import {
|
||||
createWebHashHistory,
|
||||
createWebHistory
|
||||
} from 'vue-router';
|
||||
import { createRoutes } from './routes';
|
||||
import { createBuiltinVueRoutes } from './routes/builtin';
|
||||
import { createRouterGuard } from './guard';
|
||||
|
||||
const { VITE_ROUTER_HISTORY_MODE = 'history', VITE_BASE_URL } = import.meta.env;
|
||||
@ -17,11 +17,9 @@ const historyCreatorMap: Record<Env.RouterHistoryMode, (base?: string) => Router
|
||||
memory: createMemoryHistory
|
||||
};
|
||||
|
||||
const { constantVueRoutes } = createRoutes();
|
||||
|
||||
export const router = createRouter({
|
||||
history: historyCreatorMap[VITE_ROUTER_HISTORY_MODE](VITE_BASE_URL),
|
||||
routes: constantVueRoutes
|
||||
routes: createBuiltinVueRoutes()
|
||||
});
|
||||
|
||||
/** Setup Vue Router */
|
||||
|
31
src/router/routes/builtin.ts
Normal file
31
src/router/routes/builtin.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import type { CustomRoute } from '@elegant-router/types';
|
||||
import { layouts, views } from '../elegant/imports';
|
||||
import { getRoutePath, transformElegantRoutesToVueRoutes } from '../elegant/transform';
|
||||
|
||||
export const ROOT_ROUTE: CustomRoute = {
|
||||
name: 'root',
|
||||
path: '/',
|
||||
redirect: getRoutePath(import.meta.env.VITE_ROUTE_HOME) || '/home',
|
||||
meta: {
|
||||
title: 'root',
|
||||
constant: true
|
||||
}
|
||||
};
|
||||
|
||||
const NOT_FOUND_ROUTE: CustomRoute = {
|
||||
name: 'not-found',
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: 'layout.blank$view.404',
|
||||
meta: {
|
||||
title: 'not-found',
|
||||
constant: true
|
||||
}
|
||||
};
|
||||
|
||||
/** builtin routes, it must be constant and setup in vue-router */
|
||||
const builtinRoutes: CustomRoute[] = [ROOT_ROUTE, NOT_FOUND_ROUTE];
|
||||
|
||||
/** create builtin vue routes */
|
||||
export function createBuiltinVueRoutes() {
|
||||
return transformElegantRoutesToVueRoutes(builtinRoutes, layouts, views);
|
||||
}
|
@ -1,29 +1,14 @@
|
||||
import type { CustomRoute, ElegantConstRoute, ElegantRoute } from '@elegant-router/types';
|
||||
import { generatedRoutes } from '../elegant/routes';
|
||||
import { layouts, views } from '../elegant/imports';
|
||||
import { getRoutePath, transformElegantRoutesToVueRoutes } from '../elegant/transform';
|
||||
|
||||
export const ROOT_ROUTE: CustomRoute = {
|
||||
name: 'root',
|
||||
path: '/',
|
||||
redirect: getRoutePath(import.meta.env.VITE_ROUTE_HOME) || '/home',
|
||||
meta: {
|
||||
title: 'root',
|
||||
constant: true
|
||||
}
|
||||
};
|
||||
import { transformElegantRoutesToVueRoutes } from '../elegant/transform';
|
||||
|
||||
/**
|
||||
* custom routes
|
||||
*
|
||||
* @link https://github.com/soybeanjs/elegant-router?tab=readme-ov-file#custom-route
|
||||
*/
|
||||
const customRoutes: CustomRoute[] = [
|
||||
ROOT_ROUTE,
|
||||
{
|
||||
name: 'not-found',
|
||||
path: '/:pathMatch(.*)*',
|
||||
component: 'layout.blank$view.404',
|
||||
meta: {
|
||||
title: 'not-found',
|
||||
constant: true
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'exception',
|
||||
path: '/exception',
|
||||
@ -69,8 +54,8 @@ const customRoutes: CustomRoute[] = [
|
||||
}
|
||||
];
|
||||
|
||||
/** Create routes */
|
||||
export function createRoutes() {
|
||||
/** create routes when the auth route mode is static */
|
||||
export function createStaticRoutes() {
|
||||
const constantRoutes: ElegantRoute[] = [];
|
||||
|
||||
const authRoutes: ElegantRoute[] = [];
|
||||
@ -83,10 +68,8 @@ export function createRoutes() {
|
||||
}
|
||||
});
|
||||
|
||||
const constantVueRoutes = transformElegantRoutesToVueRoutes(constantRoutes, layouts, views);
|
||||
|
||||
return {
|
||||
constantVueRoutes,
|
||||
constantRoutes,
|
||||
authRoutes
|
||||
};
|
||||
}
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { request } from '../request';
|
||||
|
||||
/** get constant routes */
|
||||
export function fetchGetConstantRoutes() {
|
||||
return request<Api.Route.MenuRoute[]>({ url: '/route/getConstantRoutes' });
|
||||
}
|
||||
|
||||
/** get user routes */
|
||||
export function fetchGetUserRoutes() {
|
||||
return request<Api.Route.UserRoute>({ url: '/route/getUserRoutes' });
|
||||
|
@ -1,13 +1,14 @@
|
||||
import { computed, ref } from 'vue';
|
||||
import { computed, ref, shallowRef } from 'vue';
|
||||
import type { RouteRecordRaw } from 'vue-router';
|
||||
import { defineStore } from 'pinia';
|
||||
import { useBoolean } from '@sa/hooks';
|
||||
import type { CustomRoute, ElegantConstRoute, LastLevelRouteKey, RouteKey, RouteMap } from '@elegant-router/types';
|
||||
import { SetupStoreId } from '@/enum';
|
||||
import { router } from '@/router';
|
||||
import { ROOT_ROUTE, createRoutes, getAuthVueRoutes } from '@/router/routes';
|
||||
import { createStaticRoutes, getAuthVueRoutes } from '@/router/routes';
|
||||
import { ROOT_ROUTE } from '@/router/routes/builtin';
|
||||
import { getRouteName, getRoutePath } from '@/router/elegant/transform';
|
||||
import { fetchGetUserRoutes, fetchIsRouteExist } from '@/service/api';
|
||||
import { fetchGetConstantRoutes, fetchGetUserRoutes, fetchIsRouteExist } from '@/service/api';
|
||||
import { useAppStore } from '../app';
|
||||
import { useAuthStore } from '../auth';
|
||||
import { useTabStore } from '../tab';
|
||||
@ -27,8 +28,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
const appStore = useAppStore();
|
||||
const authStore = useAuthStore();
|
||||
const tabStore = useTabStore();
|
||||
const { bool: isInitConstantRoute, setBool: setIsInitConstantRoute } = useBoolean();
|
||||
const { bool: isInitAuthRoute, setBool: setIsInitAuthRoute } = useBoolean();
|
||||
const removeRouteFns: (() => void)[] = [];
|
||||
|
||||
/**
|
||||
* Auth route mode
|
||||
@ -51,6 +52,15 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
routeHome.value = routeKey;
|
||||
}
|
||||
|
||||
/** auth routes */
|
||||
const authRoutes = shallowRef<ElegantConstRoute[]>([]);
|
||||
|
||||
function addAuthRoutes(routes: ElegantConstRoute[]) {
|
||||
authRoutes.value = [...authRoutes.value, ...routes];
|
||||
}
|
||||
|
||||
const removeRouteFns: (() => void)[] = [];
|
||||
|
||||
/** Global menus */
|
||||
const menus = ref<App.Global.Menu[]>([]);
|
||||
const searchMenus = computed(() => transformMenuToSearchMenus(menus.value));
|
||||
@ -74,9 +84,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
* @param routes Vue routes
|
||||
*/
|
||||
function getCacheRoutes(routes: RouteRecordRaw[]) {
|
||||
const { constantVueRoutes } = createRoutes();
|
||||
|
||||
cacheRoutes.value = getCacheRouteNames([...constantVueRoutes, ...routes]);
|
||||
cacheRoutes.value = getCacheRouteNames(routes);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -145,6 +153,27 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
removeRouteFns.length = 0;
|
||||
}
|
||||
|
||||
/** init constant route */
|
||||
async function initConstantRoute() {
|
||||
if (isInitConstantRoute.value) return;
|
||||
|
||||
if (authRouteMode.value === 'static') {
|
||||
const { constantRoutes } = createStaticRoutes();
|
||||
|
||||
addAuthRoutes(constantRoutes);
|
||||
} else {
|
||||
const { data, error } = await fetchGetConstantRoutes();
|
||||
|
||||
if (!error) {
|
||||
addAuthRoutes(data);
|
||||
}
|
||||
}
|
||||
|
||||
handleAuthRoutes();
|
||||
|
||||
setIsInitConstantRoute(true);
|
||||
}
|
||||
|
||||
/** Init auth route */
|
||||
async function initAuthRoute() {
|
||||
if (authRouteMode.value === 'static') {
|
||||
@ -158,11 +187,17 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
|
||||
/** Init static auth route */
|
||||
async function initStaticAuthRoute() {
|
||||
const { authRoutes } = createRoutes();
|
||||
const { authRoutes: staticAuthRoutes } = createStaticRoutes();
|
||||
|
||||
const filteredAuthRoutes = filterAuthRoutesByRoles(authRoutes, authStore.userInfo.roles);
|
||||
if (authStore.isStaticSuper) {
|
||||
addAuthRoutes(staticAuthRoutes);
|
||||
} else {
|
||||
const filteredAuthRoutes = filterAuthRoutesByRoles(staticAuthRoutes, authStore.userInfo.roles);
|
||||
|
||||
handleAuthRoutes(filteredAuthRoutes);
|
||||
addAuthRoutes(filteredAuthRoutes);
|
||||
}
|
||||
|
||||
handleAuthRoutes();
|
||||
|
||||
setIsInitAuthRoute(true);
|
||||
}
|
||||
@ -174,7 +209,9 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
if (!error) {
|
||||
const { routes, home } = data;
|
||||
|
||||
handleAuthRoutes(routes);
|
||||
addAuthRoutes(routes);
|
||||
|
||||
handleAuthRoutes();
|
||||
|
||||
setRouteHome(home);
|
||||
|
||||
@ -184,18 +221,12 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle routes
|
||||
*
|
||||
* @param routes Auth routes
|
||||
*/
|
||||
function handleAuthRoutes(routes: ElegantConstRoute[]) {
|
||||
const sortRoutes = sortRoutesByOrder(routes);
|
||||
/** handle auth routes */
|
||||
function handleAuthRoutes() {
|
||||
const sortRoutes = sortRoutesByOrder(authRoutes.value);
|
||||
|
||||
const vueRoutes = getAuthVueRoutes(sortRoutes);
|
||||
|
||||
resetVueRoutes();
|
||||
|
||||
addRoutesToVueRouter(vueRoutes);
|
||||
|
||||
getGlobalMenus(sortRoutes);
|
||||
@ -210,6 +241,10 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
*/
|
||||
function addRoutesToVueRouter(routes: RouteRecordRaw[]) {
|
||||
routes.forEach(route => {
|
||||
if (route.name && router.hasRoute(route.name)) {
|
||||
router.removeRoute(route.name);
|
||||
}
|
||||
|
||||
const removeFn = router.addRoute(route);
|
||||
addRemoveRouteFn(removeFn);
|
||||
});
|
||||
@ -256,9 +291,7 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
}
|
||||
|
||||
if (authRouteMode.value === 'static') {
|
||||
const { authRoutes } = createRoutes();
|
||||
|
||||
return isRouteExistByRouteName(routeName, authRoutes);
|
||||
return isRouteExistByRouteName(routeName, authRoutes.value);
|
||||
}
|
||||
|
||||
const { data } = await fetchIsRouteExist(routeName);
|
||||
@ -297,6 +330,8 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
reCacheRoutesByKey,
|
||||
reCacheRoutesByKeys,
|
||||
breadcrumbs,
|
||||
initConstantRoute,
|
||||
isInitConstantRoute,
|
||||
initAuthRoute,
|
||||
isInitAuthRoute,
|
||||
setIsInitAuthRoute,
|
||||
|
@ -10,14 +10,6 @@ import { useSvgIcon } from '@/hooks/common/icon';
|
||||
* @param roles Roles
|
||||
*/
|
||||
export function filterAuthRoutesByRoles(routes: ElegantConstRoute[], roles: string[]) {
|
||||
// in static mode of auth route, the super admin role is defined in front-end
|
||||
const SUPER_ROLE = 'R_SUPER';
|
||||
|
||||
// if the user is super admin, then it is allowed to access all routes
|
||||
if (roles.includes(SUPER_ROLE)) {
|
||||
return routes;
|
||||
}
|
||||
|
||||
return routes.flatMap(route => filterAuthRouteByRoles(route, roles));
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,7 @@ interface Props {
|
||||
module?: UnionKey.LoginModule;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
module: 'pwd-login'
|
||||
});
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const appStore = useAppStore();
|
||||
const themeStore = useThemeStore();
|
||||
@ -37,7 +35,7 @@ const moduleMap: Record<UnionKey.LoginModule, LoginModule> = {
|
||||
'bind-wechat': { label: loginModuleRecord['bind-wechat'], component: BindWechat }
|
||||
};
|
||||
|
||||
const activeModule = computed(() => moduleMap[props.module]);
|
||||
const activeModule = computed(() => moduleMap[props.module || 'pwd-login']);
|
||||
|
||||
const bgThemeColor = computed(() =>
|
||||
themeStore.darkMode ? getColorPalette(themeStore.themeColor, 7) : themeStore.themeColor
|
||||
|
Loading…
Reference in New Issue
Block a user