- 新增 pinia-plugin-persistedstate 实现用户状态本地存储 - 重构 API 响应类型为统一模块管理 - 优化路由守卫逻辑,支持 token 自动登录 - 修复权限检查逻辑错误,调整 AI 聊天页访问权限 - 新增用户信息获取接口及类型定义
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
/** src/access/index.ts */
|
||
import type { RouteLocationNormalizedGeneric } from "vue-router";
|
||
import router from "../router/router";
|
||
import type { LoginUesr } from "../store/types";
|
||
import { useUserStore } from "../store/user";
|
||
import ACCESS_ENUM from "./accessEnum";
|
||
import checkAccess from "./checkAccess";
|
||
import { getAccessToken } from "@/utils/token";
|
||
|
||
/**
|
||
* 检查是否需要权限访问
|
||
* @param to 要访问的路由
|
||
* @param loginUser 当前登录用户
|
||
* @returns 如果需要权限访问且权限不足,返回重定向路径;否则返回空字符串
|
||
*/
|
||
const redirectWithAccess = (
|
||
to: RouteLocationNormalizedGeneric,
|
||
loginUser: LoginUesr
|
||
): string => {
|
||
// 获取要访问的路由的权限
|
||
const needAccess: string = to.meta?.access ?? ACCESS_ENUM.NOT_LOGIN; //?? 运算符, 如果 to.meta?.access 为 undefined 或 null,
|
||
// 则使用 ACCESS_ENUM.NOT_LOGIN 作为默认值
|
||
// 必须要登录才能访问的页面
|
||
if (needAccess !== ACCESS_ENUM.NOT_LOGIN) {
|
||
// 如果说当前是未登录状态 那直接给他跳登录页面去
|
||
if (
|
||
!loginUser ||
|
||
!loginUser.userRole ||
|
||
loginUser.userRole === ACCESS_ENUM.NOT_LOGIN
|
||
) {
|
||
return `/user/login?redirect=${to.fullPath}`;
|
||
}
|
||
// 权限不足,跳到无权限页面
|
||
if (!checkAccess(loginUser, needAccess)) {
|
||
return "/noAuth";
|
||
}
|
||
}
|
||
return "";
|
||
};
|
||
// 这里接收异步函数,是因为下面要调用 userStore.getLoginUser()
|
||
router.beforeEach(async (to, from, next) => {
|
||
const userStore = useUserStore(); // 必须在守卫内部获取 store,确保 pinia 已安装
|
||
console.log("登陆用户信息", userStore.loginUser);
|
||
let loginUser = userStore.loginUser;
|
||
// 如果之前没登陆过,且有 token,尝试自动登录
|
||
// 没有 token 时不调用 API,避免未登录状态重复弹出错误提示
|
||
if (!loginUser || !loginUser.userRole || loginUser.userRole === ACCESS_ENUM.NOT_LOGIN) {
|
||
const token = getAccessToken();
|
||
if (token) {
|
||
await userStore.getLoginUser();
|
||
loginUser = userStore.loginUser;
|
||
}
|
||
}
|
||
|
||
// 检查是否需要权限访问
|
||
const redirectUrl = redirectWithAccess(to, loginUser);
|
||
if (redirectUrl) {
|
||
next(redirectUrl);
|
||
return;
|
||
}
|
||
// 未重定向时,继续导航
|
||
next();
|
||
});
|