feat: 1. 添加axios全局路由拦截进行自动添加请求jwt。 2.重新整理路由表。 3. 文档列表新增版本差异对比。 4.菜单路由可访问列表通过对接接口返回,添加全局路由检测。

5. 修改统一认证登录和管理员登录是通过接口形式进行,存储返回的accessToken。    6. 修改交叉评查的部分样式
This commit is contained in:
2025-11-18 11:06:24 +08:00
parent 8a50671c39
commit bfe39e45a9
53 changed files with 9503 additions and 2796 deletions
+80
View File
@@ -43,6 +43,86 @@ const axiosInstance = axios.create({
}
});
// 请求白名单 - 这些接口不需要添加 Authorization 头
const AUTH_WHITELIST = [
'/auth/login',
'/auth/refresh',
'/auth/register',
'/oauth/token',
'/oauth/userinfo'
];
/**
* 检查请求URL是否在白名单中
*/
function isInAuthWhitelist(url?: string): boolean {
if (!url) return false;
return AUTH_WHITELIST.some(path => url.includes(path));
}
/**
* 请求拦截器 - 自动添加 Authorization 头
*/
axiosInstance.interceptors.request.use(
(config) => {
// 检查是否在白名单中
if (isInAuthWhitelist(config.url)) {
return config;
}
// 从 localStorage 获取 token (浏览器环境)
if (typeof window !== 'undefined') {
const token = localStorage.getItem('access_token');
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
}
return config;
},
(error) => {
return Promise.reject(error);
}
);
/**
* 自定义错误类:表示需要重新登录
*/
export class AuthenticationError extends Error {
constructor(message = 'Token 已过期或无效,请重新登录') {
super(message);
this.name = 'AuthenticationError';
}
}
/**
* 响应拦截器 - 处理 401 错误(token 过期)
*/
axiosInstance.interceptors.response.use(
(response) => {
return response;
},
(error) => {
if (isAxiosError(error) && error.response?.status === 401) {
// Token 过期或无效
console.warn('⚠️ Token 已过期或无效,请重新登录');
if (typeof window !== 'undefined') {
// 🌐 客户端环境:清除 localStorage 并跳转
localStorage.removeItem('access_token');
localStorage.removeItem('user_info');
window.location.href = '/login';
} else {
// 🖥️ 服务端环境:抛出特殊错误,由 loader/action 处理
console.warn('⚠️ [Server] 检测到 401 错误,抛出 AuthenticationError');
throw new AuthenticationError('Token 已过期或无效,请重新登录');
}
}
return Promise.reject(error);
}
);
// 最大重试次数
const MAX_RETRIES = 2;