110 lines
4.0 KiB
JavaScript
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.

import axiosInstance from '../api/axiosConfig';
import router from '../router'; // 引入 Vue Router 实例
import { justLoggedIn } from './authSessionState'; // Import the flag
const USER_INFO_URL = '/user'; // 获取用户信息的API端点
const TEMP_PRIVILEGE_URL = '/user/temp_privilege'; // 获取用户临时权限的API端点
/**
* 从 sessionStorage 中安全地读取和解析用户信息。
* @returns {Object|null} 用户信息对象或null。
*/
export const getStoredUser = () => {
const storedUser = sessionStorage.getItem('currentUser');
if (storedUser) {
try {
return JSON.parse(storedUser);
} catch (e) {
console.error('Error parsing stored user info:', e);
return null;
}
}
return null;
};
/**
* 检查Token是否存在且理论上是否在有效期内。
* 服务端 /user接口会验证实际有效期。
* @returns {boolean} 如果存在token则返回true否则false。
*/
export const hasValidToken = () => {
const token = localStorage.getItem('access_token');
// 简单的存在性检查,实际有效期由 /user 接口判断
return !!token;
};
/**
* 获取当前用户信息。
* 如果Token无效或过期API会返回401响应拦截器将处理清除token。
* @returns {Promise<Object|null>} 用户信息对象或null如果未登录或获取失败
*/
export const getUserInfo = async () => {
if (!hasValidToken()) {
throw new Error('No valid token found');
}
try {
const response = await axiosInstance.get(USER_INFO_URL);
const user = response.data;
try {
const tempResp = await axiosInstance.get(TEMP_PRIVILEGE_URL);
if (tempResp.data) {
if (tempResp.data.temp_privilege !== undefined) {
user.temp_privilege = tempResp.data.temp_privilege;
} else if (typeof tempResp.data.privilege === 'string') {
// 后端返回字段名为 privilege
user.temp_privilege = tempResp.data.privilege;
}
}
} catch (e) {
// 若临时权限接口失败,仅记录错误,不影响主流程
console.error('Failed to fetch temp privilege:', e);
}
// 将合并后的用户信息存入 sessionStorage
sessionStorage.setItem('currentUser', JSON.stringify(user));
return user;
} catch (error) {
// 清除可能存在的无效用户信息
sessionStorage.removeItem('currentUser');
throw error;
}
};
/**
* 处理用户登出。
* 仅清除本地存储的认证信息。
*/
export const logoutUser = () => { // 不再是 async因为它不执行异步导航
// console.log('jwt.js: logoutUser called. Clearing local storage.');
localStorage.removeItem('access_token');
localStorage.removeItem('user_id');
sessionStorage.removeItem('currentUser'); // 同时清除sessionStorage中的用户信息
// 导航将由调用者(如路由守卫)处理
};
/**
* 登录成功后调用存储token和用户信息并处理重定向。
* @param {string} accessToken - 从登录API获取的访问令牌。
* @param {string} userId - 用户ID。
*/
export const loginSuccess = (accessToken, userId) => {
// 清除可能存在的旧数据
// localStorage.removeItem('access_token');
// localStorage.removeItem('user_id');
// sessionStorage.removeItem('currentUser');
// 存储新的认证信息
localStorage.setItem('access_token', accessToken);
if (userId) {
localStorage.setItem('user_id', userId);
}
// 设置登录标志
justLoggedIn.value = true;
// 获取重定向路径优先使用查询参数中的redirect否则跳转到首页
const currentRoute = router.currentRoute.value;
const redirectPath = currentRoute.query.redirect || '/';
// 使用replace而不是push避免在历史记录中留下登录页面
router.replace(redirectPath);
};