Files
AI_OJ_FRONTEND/src/access/index.ts
meowrain fad13e00e5 feat(auth): 实现用户认证状态持久化及权限控制优化
- 新增 pinia-plugin-persistedstate 实现用户状态本地存储
- 重构 API 响应类型为统一模块管理
- 优化路由守卫逻辑,支持 token 自动登录
- 修复权限检查逻辑错误,调整 AI 聊天页访问权限
- 新增用户信息获取接口及类型定义
2026-01-07 20:14:40 +08:00

64 lines
2.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** 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();
});