111
This commit is contained in:
120
Web/src/composables/ApiService.ts
Normal file
120
Web/src/composables/ApiService.ts
Normal file
@@ -0,0 +1,120 @@
|
||||
import { navigateTo } from "#app";
|
||||
import { RequestExtend } from "@/extends/RequestExtend";
|
||||
import { BaseConfig } from "@/config/BaseConfig";
|
||||
import type { IResultData } from "@/model/common/ResultData";
|
||||
|
||||
type HttpMethod = "get" | "post" | "put" | "delete" | "patch";
|
||||
type RequestParams = Record<string, unknown>;
|
||||
|
||||
export type HandledRedirectError = {
|
||||
handled: true;
|
||||
redirectTo: string;
|
||||
message: string;
|
||||
};
|
||||
|
||||
export class ApiService {
|
||||
private static initialized = false;
|
||||
|
||||
private static request = new RequestExtend({
|
||||
baseURL: BaseConfig.BaseUrl,
|
||||
timeout: 60000
|
||||
});
|
||||
|
||||
private static isResultData(value: unknown): value is IResultData {
|
||||
return typeof value === "object" && value !== null && "code" in value && "msg" in value;
|
||||
}
|
||||
|
||||
public static isHandledRedirectError(error: unknown): error is HandledRedirectError {
|
||||
return typeof error === "object" && error !== null && "handled" in error && error.handled === true;
|
||||
}
|
||||
|
||||
private static redirectToLogin() {
|
||||
if (typeof localStorage !== "undefined") {
|
||||
localStorage.removeItem("token");
|
||||
localStorage.removeItem("userInfo");
|
||||
}
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
void navigateTo("/home", { replace: true });
|
||||
}
|
||||
}
|
||||
|
||||
private static ensureInitialized() {
|
||||
if (this.initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
RequestExtend.addRequestInterceptor({
|
||||
onFulfilled: (config) => {
|
||||
const token = typeof localStorage !== "undefined" ? localStorage.getItem("token") : "";
|
||||
|
||||
if (token) {
|
||||
config.headers = {
|
||||
...config.headers,
|
||||
Authorization: `Bearer ${token}`
|
||||
};
|
||||
}
|
||||
|
||||
config.timeout = 60000;
|
||||
return config;
|
||||
}
|
||||
});
|
||||
|
||||
RequestExtend.addResponseInterceptor({
|
||||
onFulfilled: (response) => {
|
||||
if (!this.isResultData(response.data)) {
|
||||
return response;
|
||||
}
|
||||
const result = response.data;
|
||||
if (result.code === 401) {
|
||||
console.log(result.data);
|
||||
} else if (result.code === 40101) {
|
||||
this.redirectToLogin();
|
||||
throw {
|
||||
handled: true,
|
||||
redirectTo: "/login/login",
|
||||
message: result.msg || "登录已失效"
|
||||
} satisfies HandledRedirectError;
|
||||
} else if (result.code === 500) {
|
||||
// 跳转错误页面
|
||||
} else if (result.code === 404) {
|
||||
// 跳转不存在页面
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
onRejected: (error) => {
|
||||
if (error && typeof error === "object" && "status" in error) {
|
||||
// console.log("接口错误:", error);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
});
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
public static async ApiRequest<T = unknown>(
|
||||
method: HttpMethod,
|
||||
url: string,
|
||||
params: RequestParams = {}
|
||||
): Promise<IResultData<T>> {
|
||||
this.ensureInitialized();
|
||||
|
||||
switch (method) {
|
||||
case "get":
|
||||
return await this.request.get<IResultData<T>>(url, { params });
|
||||
case "post":
|
||||
return await this.request.post<IResultData<T>>(url, params);
|
||||
case "put":
|
||||
return await this.request.put<IResultData<T>>(url, params);
|
||||
case "delete":
|
||||
return await this.request.delete<IResultData<T>>(url, { params });
|
||||
case "patch":
|
||||
return await this.request.patch<IResultData<T>>(url, params);
|
||||
default:
|
||||
throw new Error(`不支持的请求方法: ${method}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user