import axios from 'axios'
|
import $qxueyou from '@/config/qxueyou.js'
|
import { getUUID } from "@/utils/tool.js";
|
|
let createAxios = axios.create({
|
baseURL: $qxueyou.serverRoot,
|
timeout: 30000,
|
headers: {
|
"Content-Type": `application/json;charset=utf-8`
|
}
|
})
|
|
createAxios.all = axios.all
|
createAxios.spread = axios.spread
|
|
// Token 工具函数
|
const ACCESS_TOKEN_KEY = $qxueyou.ACCESS_TOKEN_KEY;
|
const REFRESH_TOKEN_KEY = $qxueyou.REFRESH_TOKEN_KEY;
|
export const tokenUtils = {
|
// 获取 Access Token
|
getAccessToken() {
|
return localStorage.getItem(ACCESS_TOKEN_KEY);
|
},
|
// 获取 Refresh Token
|
getRefreshToken() {
|
return localStorage.getItem(REFRESH_TOKEN_KEY);
|
},
|
// 设置 Token
|
setTokens(accessToken, refreshToken) {
|
if (accessToken) {
|
localStorage.setItem(ACCESS_TOKEN_KEY, accessToken);
|
}
|
if (refreshToken) {
|
localStorage.setItem(REFRESH_TOKEN_KEY, refreshToken);
|
}
|
},
|
// 清除 Token
|
clearTokens() {
|
localStorage.removeItem(ACCESS_TOKEN_KEY);
|
localStorage.removeItem(REFRESH_TOKEN_KEY);
|
},
|
// 检查 Token 是否存在
|
hasTokens() {
|
return !!(this.getAccessToken() && this.getRefreshToken());
|
},
|
}
|
let isRefreshing = false;
|
// 刷新 token 期间的请求队列
|
let refreshQueue = [];
|
// 刷新 Access Token
|
export async function refreshAccessToken() {
|
const currentRefreshToken = tokenUtils.getRefreshToken();
|
if (!currentRefreshToken) {
|
throw new Error("No refresh token available");
|
}
|
try {
|
const response = await createAxios.post(
|
`/system/auth/refresh-token?refreshToken=${currentRefreshToken}`
|
);
|
|
if (response.data && response.data.code === 0) {
|
const { accessToken, refreshToken: newRefreshToken } = response.data.data;
|
tokenUtils.setTokens(accessToken, newRefreshToken);
|
return accessToken;
|
} else {
|
throw new Error("Token refresh failed");
|
}
|
} catch (error) {
|
console.error('Token refresh error:', error);
|
throw error;
|
}
|
}
|
|
let strTrim = function(data) {
|
let newData = {...data}
|
Object.keys(newData).forEach((key) => {
|
if (typeof newData[key] === 'string') {
|
newData[key] = newData[key].trim()
|
}
|
})
|
return newData
|
}
|
|
//网络请求监听
|
createAxios.interceptors.request.use(
|
function(config) {
|
// 刷新 token 的请求不需要添加 Authorization header
|
if (!config.url.includes('/auth/refresh-token')) {
|
config.headers = {
|
...config.headers,
|
Authorization: localStorage.getItem('accessToken')
|
}
|
}
|
config.flag = getUUID().toString().slice(-4)
|
if (config.data) {
|
console.log(`data-${config.flag} `, config.data)
|
// config.data = JSON.stringify(config.data)
|
}
|
if (config.params) {
|
console.log(`params-${config.flag} `, config.params)
|
// config.params = strTrim(config.params)
|
}
|
return config
|
},
|
function(error) {
|
return Promise.reject(error)
|
}
|
)
|
|
createAxios.interceptors.response.use(
|
async response => {
|
const resultCode = response.data.code;
|
const originalRequest = response.config;
|
if (response.data && [500, 400].includes(resultCode)) {
|
console.log(response)
|
return response
|
}
|
if (response.data && resultCode == '401') {
|
if (!originalRequest._retry && tokenUtils.getRefreshToken) {
|
originalRequest._retry = true;
|
|
if (isRefreshing) {
|
// 如果正在刷新,将请求加入队列
|
return new Promise((resolve, reject) => {
|
refreshQueue.push({ resolve, reject, config: originalRequest });
|
});
|
}
|
|
isRefreshing = true;
|
|
try {
|
const newAccessToken = await refreshAccessToken();
|
|
// 处理队列中的请求
|
refreshQueue.forEach(({ resolve, config }) => {
|
config.headers.Authorization = newAccessToken;
|
resolve(createAxios(config));
|
});
|
refreshQueue = [];
|
|
// 重新发送原始请求
|
originalRequest.headers.Authorization = newAccessToken;
|
return createAxios(originalRequest)
|
} catch (refreshError) {
|
console.log(refreshError)
|
// 刷新失败,处理队列中的请求
|
refreshQueue.forEach(({ reject }) => {
|
reject(refreshError);
|
});
|
refreshQueue = [];
|
tokenUtils.clearTokens();
|
// $store.commit("session/loginFlag", false);
|
// $store.commit("session/userInfo", {});
|
// 可以在这里触发登录页面跳转
|
} finally {
|
isRefreshing = false;
|
}
|
} else {
|
tokenUtils.clearTokens();
|
// $store.commit("session/loginFlag", false);
|
// $store.commit("session/userInfo", {});
|
}
|
}
|
|
console.log(`url-${response.config.flag} `, response.config.url, response.data)
|
return response
|
},
|
error => {
|
// store.commit('network/changeNetworkState', false)
|
if (!error.response) return Promise.reject(error)
|
|
// store.commit('network/status', error.response.status)
|
if (401 === error.response.status) {
|
// 刷新 token 的请求返回 401 时,直接返回错误,不要抛出新的错误
|
if (error.config && error.config.url && error.config.url.includes('/auth/refresh-token')) {
|
return Promise.reject(error)
|
}
|
// store.commit('session/clearUser')
|
// store.commit('endea/clearShareK')
|
// store.commit('network/logout')
|
throw new Error('登录失效')
|
}
|
return Promise.reject(error)
|
}
|
)
|
|
export default createAxios
|