Vue\vue3_admin\src\permission.ts
// 路由鉴权,项目当中路由能不能被访问的设置
import router from "./router";
import setting from './setting'
// 任意路由切换实现进度条业务---> npm install --save nprogress npm i --save-dev @types/nprogress
// 引入进度条
import nprogress from 'nprogress';
nprogress.configure({ showSpinner: false });
// 引入进度条样式
// import 'nprogress/nprogress.css' // 灵活配置放入 全局样式配置:/src/styles/main.scss
// 获取用户相关的小仓库内部token数据,去判断用户是否登录成功
// 组件外部引入仓库需要引入pinia大仓库
import pinia from "./stores";
import useUserStore from '@/stores/modules/user'
import { GET_TOKEN, REMOVE_TOKEN } from '@/utils/token';
import type { tokenType } from "./api/user/type";
// import { storeToRefs } from "pinia";
// console.log(userStore.userInfo());
// // 重置路由
// const resetRouter = () => {
// const userStore = useUserStore();
// userStore.userAsyncRoute.forEach((route: any) => {
// const { name } = route;
// if (name && router.hasRoute(name)) router.removeRoute(name);
// });
// };
// // 白名单
// const whiteList = ["login", '404'];
// console.log("路由守卫");
// 全局守卫:项目当中任意路由切换都会触发的钩子
//全局前置守卫
router.beforeEach(async (to: any, from: any, next: any) => {
// 获取用户仓库
const userStore = useUserStore(pinia)
// 动态标题
document.title = `${setting.title} - ${to.meta.title}`
//to:你将要访问那个路由
//from:你从来个路由而来
//next:路由的放行函数
nprogress.start()
//获取token,去判断用户登录、还是未登录
//获取用户名字
// const username = userStore.username
// console.log('路由前',userStore.userButtons, userStore.userAsyncRoute);
// const { userAsyncRoute, userButtons } = storeToRefs(userStore);
// console.log('token', GET_TOKEN(), 'username', GET_USERNAME());
// console.log('token', userStore.token, 'username', userStore.username, 'userAsyncRoute', userStore.userAsyncRoute);
const token: tokenType = {
'token': GET_TOKEN() as string
}
//用户登录判断
// if (localStorage.getItem("TOKEN")) {
// console.log(token, token.token);
if (typeof token.token != "object" && GET_TOKEN()) {
// if (GET_TOKEN()) {
// 已经登录成功,访问login,不能访问,指向首页
// console.log("路由前验证token是否存在-存在");
// console.log(GET_TOKEN());
if (to.path == '/login') {
next({ path: '/' })
} else {
//登录成功访问其余六个路由(登录排除)
// 判断动态路由列表
if (!userStore.userAsyncRoute.length || !userStore.userButtons.length) {
// console.log('路由前验证路由表', router.getRoutes())
// console.log('路由前验证路由表不存在!', router.getRoutes())
try {
//获取用户信息
await userStore.userInfo()
// console.log("用户信息获取成功");
//放行
//万一:刷新的时候是异步路由,有可能获取到用户信息、异步路由还没有加载完毕,出现空白的效果
next({ ...to, replace: true })
} catch (error) {
//token过期:获取不到用户信息了,或获取用户信息失败
//用户手动修改本地存储token
if (token) {
// 强制退出登录->用户相关的数据清空
// console.log('token过期');
await userStore.userLogout(token)
next({ path: '/login', query: { redirect: to.path } })
} else {
REMOVE_TOKEN()
next({ path: '/login', query: { redirect: to.path } })
}
}
} else {
// 如果动态路由表存在则放行
// console.log('路由前验证路由表存在!', router.getRoutes())
next()
}
}
} else {
// console.log('token不存在!', to.path);
//用户未登录判断
if (to.path == '/login') {
// console.log('跳转登录', to.path);
next()
} else {
next({ path: '/login', query: { redirect: to.path } })
}
}
})
// // 2.判断是访问登陆页,有 Token 就在当前页面,没有 Token 重置路由到登陆页
// if (to.path.toLocaleLowerCase() === '/login') {
// if (userStore.token) return next(from.fullPath);
// resetRouter(); // 没有token 就重置路由
// return next(); // 放行去登录页
// }
// // 3.判断访问页面是否在路由白名单地址(静态路由)中,如果存在直接放行
// if (whiteList.includes(to.path)) return next();
// // 4.判断是否有 Token,没有重定向到 login 页面
// if (userStore.token) return next({ path: '/login', replace: true });
// // 5.我们判断 vuex里面的设置的菜单列表是否为空,为空就重新获取列表添加路由
// if (!userStore.userAsyncRoute.length) {
// await userStore.userInfo();
// return next({ ...to, replace: true }); // 在已有的路由里自己匹配,replace: true 允许用户手贱点回退
// }
// // 8.正常访问页面
// next();
// });
//全局后置守卫
// router.afterEach((to: any, from: any) => {
router.afterEach(() => {
// console.log(to,from);
nprogress.done()
})
// 路由鉴权:路由组件访问权限的设置
// 全部路由组件:登录|404|任意路由|首页|数据大屏|权限管理(三个子路由)|商品管理(四个子路由)
// 用户未登录:可以访问login,其他六个路由不能访问并指定login
// 用户登录成功:不可以访问login并指定首页,可以访问其余路由