173 lines
4.8 KiB
TypeScript
173 lines
4.8 KiB
TypeScript
import axios from "axios";
|
||
import { errorCodeType } from "./error-code-type";
|
||
import { ElMessage } from "element-plus";
|
||
import store from "@/store/index";
|
||
|
||
const service = axios.create({
|
||
baseURL: "/api",
|
||
timeout: 60 * 1000 * 3,
|
||
headers: { "Content-Type": "application/json;charset=utf-8" },
|
||
});
|
||
|
||
// 认证状态管理
|
||
let isAuthenticated = false;
|
||
let isAuthenticating = false;
|
||
const requestQueue: Array<() => void> = [];
|
||
|
||
// 执行队列中的请求
|
||
const executeQueue = () => {
|
||
while (requestQueue.length > 0) {
|
||
const nextRequest = requestQueue.shift();
|
||
if (nextRequest) nextRequest();
|
||
}
|
||
};
|
||
|
||
// 请求拦截器
|
||
service.interceptors.request.use(
|
||
(config) => {
|
||
const isAuthRequest = config.url === "/cn_authenticate";
|
||
|
||
if (!isAuthRequest) {
|
||
if (isAuthenticating) {
|
||
return new Promise((resolve) => {
|
||
requestQueue.push(() => {
|
||
resolve(service(config));
|
||
});
|
||
});
|
||
}
|
||
|
||
const token = window.sessionStorage.getItem("token");
|
||
if (token) {
|
||
config.headers["Authorization"] = `Bearer ${token}`;
|
||
}
|
||
|
||
if (!isAuthenticated) {
|
||
return new Promise((resolve) => {
|
||
requestQueue.push(() => {
|
||
resolve(service(config));
|
||
});
|
||
});
|
||
}
|
||
} else {
|
||
if (isAuthenticating) {
|
||
return Promise.reject({ message: "认证中", isHandled: true });
|
||
}
|
||
isAuthenticating = true;
|
||
config.headers["Authorization"] = "";
|
||
}
|
||
|
||
// get请求参数处理(保持原逻辑)
|
||
// if (config.method === "get" && config.params) {
|
||
// // 这里用 toLowerCase() 确保兼容
|
||
// let url = config.url + "?";
|
||
// for (const propName of Object.keys(config.params)) {
|
||
// const value = config.params[propName];
|
||
// const part = encodeURIComponent(propName) + "=";
|
||
// if (value !== null && typeof value !== "undefined") {
|
||
// if (typeof value === "object") {
|
||
// for (const key of Object.keys(value)) {
|
||
// const params = propName + "[" + key + "]";
|
||
// const subPart = encodeURIComponent(params) + "=";
|
||
// url += subPart + encodeURIComponent(value[key]) + "&";
|
||
// }
|
||
// } else {
|
||
// url += part + encodeURIComponent(value) + "&";
|
||
// }
|
||
// }
|
||
// }
|
||
// url = url.slice(0, -1);
|
||
// config.params = {};
|
||
// config.url = url;
|
||
// }
|
||
return config;
|
||
},
|
||
(error) => {
|
||
console.log(error);
|
||
return Promise.reject(error);
|
||
}
|
||
);
|
||
|
||
// 响应拦截器(保持原逻辑,略作兼容处理)
|
||
let refreshQueue: any = [];
|
||
let isRefreshing = false;
|
||
|
||
service.interceptors.response.use(
|
||
(res) => {
|
||
if (res.config.url === "/cn_authenticate") {
|
||
isAuthenticating = false;
|
||
|
||
if (res.data.code === "A0000") {
|
||
isAuthenticated = true;
|
||
setTimeout(executeQueue, 1000);
|
||
} else {
|
||
isAuthenticated = false;
|
||
setTimeout(executeQueue, 1000);
|
||
}
|
||
}
|
||
|
||
const code = res.data["code"] || "A0000";
|
||
const msg =
|
||
errorCodeType(code) || res.data["msg"] || errorCodeType("default");
|
||
|
||
if (code === "A0000") {
|
||
return Promise.resolve(res.data);
|
||
} else if (code === "A0025") {
|
||
isAuthenticated = false;
|
||
const originalRequest = res.config;
|
||
|
||
if (!isRefreshing) {
|
||
isRefreshing = true;
|
||
return store
|
||
.dispatch(
|
||
"loginAction",
|
||
JSON.parse(window.localStorage.getItem("adminInfo") || "{}")
|
||
)
|
||
.then(() => {
|
||
isAuthenticated = true;
|
||
refreshQueue.forEach((callback: any) => callback());
|
||
refreshQueue = [];
|
||
return service(originalRequest);
|
||
})
|
||
.catch((err) => {
|
||
console.error("刷新失败:", err);
|
||
refreshQueue.forEach((callback: any) => callback());
|
||
refreshQueue = [];
|
||
return Promise.reject(err);
|
||
})
|
||
.finally(() => {
|
||
isRefreshing = false;
|
||
});
|
||
} else {
|
||
return new Promise((resolve) => {
|
||
refreshQueue.push(() => resolve(service(originalRequest)));
|
||
});
|
||
}
|
||
} else {
|
||
return Promise.reject(res.data);
|
||
}
|
||
},
|
||
(error) => {
|
||
if (error.isHandled) return Promise.reject(error);
|
||
|
||
if (error.config?.url === "/cn_authenticate") {
|
||
isAuthenticating = false;
|
||
isAuthenticated = false;
|
||
setTimeout(executeQueue, 1000);
|
||
}
|
||
|
||
console.log("err" + error);
|
||
let { message } = error;
|
||
if (message === "Network Error") {
|
||
message = "后端接口连接异常";
|
||
} else if (message.includes("timeout")) {
|
||
message = "系统接口请求超时";
|
||
} else if (message.includes("Request failed with status code")) {
|
||
message = `系统接口${message.substr(message.length - 3)}异常`;
|
||
}
|
||
|
||
return Promise.reject(error);
|
||
}
|
||
);
|
||
|
||
export default service;
|