Skip to content

Commit

Permalink
feat(projects): 添加路由拦截判断权限
Browse files Browse the repository at this point in the history
  • Loading branch information
chansee97 committed Aug 14, 2022
1 parent c646819 commit 4acb525
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 39 deletions.
2 changes: 1 addition & 1 deletion mock/module/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const userInfo = {
role: 'admin',
password: '123456',
token,
permissions: [
userRoutes: [
{
name: 'dashboard',
path: '/dashboard',
Expand Down
4 changes: 2 additions & 2 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ async function setupApp() {
setupAssets();
// 创建vue实例
const app = createApp(App);
// 安装router
await setupRouter(app);
// 安装pinia全局状态库
setupStore(app);
// 安装router
await setupRouter(app);
// 挂载
app.mount('#app');
}
Expand Down
27 changes: 11 additions & 16 deletions src/router/guard/index.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@
import type { Router } from 'vue-router';
import { getToken } from '@/utils/auth';

import { createPermissionGuard } from './permission';

const appTitle = import.meta.env.VITE_APP_TITLE;

export function setupRouterGuard(router: Router) {
const isLogin = Boolean(getToken());

router.beforeEach((to, _from, next) => {
// 登录鉴权
if (!isLogin) {
if (to.name === 'login') {
next();
} else {
const redirect = to.fullPath;
next({ path: '/login', query: { redirect } });
}
return false;
}
router.beforeEach(async (to, from, next) => {
// 开始 loadingBar
window.$loadingBar?.start();
// 权限操作
await createPermissionGuard(to, from, next);
});
router.afterEach((to) => {
// 修改网页标题
document.title = `${to.meta.title}——${appTitle}`;
next();
// 结束 loadingBar
window.$loadingBar?.finish();
});
// router.afterEach((_to) => {});
}
37 changes: 37 additions & 0 deletions src/router/guard/permission.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { RouteLocationNormalized, NavigationGuardNext } from 'vue-router';
import { getToken } from '@/utils/auth';
import { useRouteStore, useAuthStore } from '@/store';

export async function createPermissionGuard(
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext,
) {
const isLogin = Boolean(getToken());
const routeStore = useRouteStore();

// 判断路由有无进行初始化
if (!routeStore.isInitAuthRoute) {
// 没有初始化路由 => 登录鉴权
// 登录鉴权
if (!isLogin) {
if (to.name === 'login') {
next();
} else {
const redirect = to.fullPath;
next({ path: '/login', query: { redirect } });
}
return false;
}

// 有登录但是没有路由,初始化路由等
await routeStore.initAuthRoute();
}
// 权限路由已经加载,仍然未找到,重定向到not-found
// if (to.name === 'not-found-page') {
// next({ name: 'not-found-page', replace: true });
// }

// next({ name: 'root' });
next();
}
2 changes: 1 addition & 1 deletion src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const routes: RouteRecordRaw[] = [
{
path: '/',
name: 'root',
redirect: '/test1',
redirect: '/test/test1',
component: BasicLayout,
children: [
{
Expand Down
12 changes: 10 additions & 2 deletions src/router/routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
// import { BasicLayout } from '@/layouts/index';

export const constantRoutes = [
{
path: '/no-found',
name: 'not-found',
component: () => import('@/views/inherit-page/not-found/index.vue'),
meta: {
title: '找不到页面',
},
},
{
path: '/no-permission',
name: 'no-permission',
Expand All @@ -19,10 +27,10 @@ export const constantRoutes = [
},
{
path: '/:pathMatch(.*)*',
name: '404',
name: 'not-found-page',
component: () => import('@/views/inherit-page/not-found/index.vue'),
meta: {
title: '错误404',
title: '找不到页面',
},
},
];
13 changes: 5 additions & 8 deletions src/store/modules/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ export const useAuthStore = defineStore('auth-store', {
// 等待数据写入完成
const catchSuccess = await this.catchUserInfo(data);
// 初始化侧边菜单
await this.setRouterStore(data.permissions);
const { setMenus } = useRouteStore();
await setMenus();
// 登录写入信息成功
if (catchSuccess) {
// 进行重定向跳转
Expand All @@ -65,7 +66,9 @@ export const useAuthStore = defineStore('auth-store', {
});
return;
}
// 如果不成功写到后面

// 如果不成功则重置存储
this.resetAuthStore();
},

/* 缓存用户信息 */
Expand All @@ -82,11 +85,5 @@ export const useAuthStore = defineStore('auth-store', {

return catchSuccess;
},

/* 将路由表等信息推送到routeStore */
async setRouterStore(permissions: Auth.UserInfoPermissions[]) {
const { setMenus } = useRouteStore();
setMenus(permissions);
},
},
});
1 change: 1 addition & 0 deletions src/store/modules/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './app';
export * from './auth';
export * from './route';
25 changes: 18 additions & 7 deletions src/store/modules/route.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,29 @@
import { defineStore } from 'pinia';
import { renderIcon } from '@/utils/icon';
import { renderIcon, getUserInfo } from '@/utils';
import type { MenuOption } from 'naive-ui';
// import { useAuthStore } from './auth';

interface RuutesStatus {
// const authStore = useAuthStore();

interface RoutesStatus {
isInitAuthRoute: boolean;
menus: any;
}
export const useRouteStore = defineStore('route-store', {
state: (): RuutesStatus => {
state: (): RoutesStatus => {
return {
isInitAuthRoute: false,
menus: [],
};
},
actions: {
setMenus(data: Auth.UserInfoPermissions[]) {
this.menus = this.transformAuthRoutesToMenus(data);
async setMenus() {
const { userRoutes } = getUserInfo();
this.menus = this.transformAuthRoutesToMenus(userRoutes);
},
// 将返回的路由表渲染成侧边栏
transformAuthRoutesToMenus(data: Auth.UserInfoPermissions[]): MenuOption[] {
return data.map((item) => {
transformAuthRoutesToMenus(userRoutes: Auth.UserInfoPermissions[]): MenuOption[] {
return userRoutes.map((item) => {
const target: MenuOption = {
label: item.meta.title,
key: item.path,
Expand All @@ -33,5 +39,10 @@ export const useRouteStore = defineStore('route-store', {
return target;
});
},

async initAuthRoute() {
await this.setMenus();
this.isInitAuthRoute = true;
},
},
});
2 changes: 1 addition & 1 deletion src/types/business.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ declare namespace Auth {
/* token */
token: string;
/* 权限路由 */
permissions: UserInfoPermissions[];
userRoutes: UserInfoPermissions[];
}
interface UserInfoPermissions {
name: string;
Expand Down
4 changes: 3 additions & 1 deletion src/types/route.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,12 @@ declare namespace AppRoute {
/* 是否开启页面缓存 */
keepAlive?: boolean;
/* 有些路由我们并不想在菜单中显示,比如某些编辑页面。 */
hideMenu?: boolean;
hide?: boolean;
/* 菜单排序。 */
order?: number;
/* 嵌套外链 */
herf?: string;
/** 当前路由需要选中的菜单项(用于跳转至不在左侧菜单显示的路由且需要高亮某个菜单的情况) */
activeMenu?: RouteKey;
}
}

1 comment on commit 4acb525

@vercel
Copy link

@vercel vercel bot commented on 4acb525 Aug 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

ench-admin – ./

ench-admin-whyhenin.vercel.app
ench-admin-git-main-whyhenin.vercel.app
ench-admin.vercel.app

Please sign in to comment.