refactor: 将请求封装重构为函数模式

This commit is contained in:
yangsy
2026-01-05 11:30:20 +08:00
parent fd70f63fc9
commit 263dd5edfc
4 changed files with 52 additions and 55 deletions

View File

@@ -1,8 +1,8 @@
import { useUserStore } from '@/stores';
import { getAppEnvConfig, RequestClient } from '@/utils';
import { createHttpClient, getAppEnvConfig } from '@/utils';
import type { AxiosError } from 'axios';
export const ndmClient = new RequestClient({
export const ndmClient = createHttpClient({
requestInterceptor: async (config) => {
const userStore = useUserStore();
const { lampAuthorization, lampClientId, lampClientSecret } = getAppEnvConfig();
@@ -25,7 +25,7 @@ export const ndmClient = new RequestClient({
const userStore = useUserStore();
await userStore.lampLogin(stationCode);
error.config.headers.token = userStore.lampLoginResultRecord?.[stationCode]?.token ?? '';
return ndmClient.requestInstance(error.config);
return ndmClient.clientInstance(error.config);
}
return Promise.reject(error);
},

View File

@@ -1,9 +1,9 @@
import router from '@/router';
import { useUserStore } from '@/stores';
import { getAppEnvConfig, RequestClient } from '@/utils';
import { createHttpClient, getAppEnvConfig } from '@/utils';
import type { AxiosError } from 'axios';
export const userClient = new RequestClient({
export const userClient = createHttpClient({
requestInterceptor: (config) => {
const userStore = useUserStore();
const { lampAuthorization, lampClientId, lampClientSecret } = getAppEnvConfig();

View File

@@ -1,54 +1,41 @@
import type { Result } from '@/types';
import axios, { isAxiosError, type AxiosError, type AxiosInstance, type AxiosRequestConfig, type AxiosResponse, type CreateAxiosDefaults, type InternalAxiosRequestConfig } from 'axios';
import axios, { isAxiosError, type AxiosError, type AxiosRequestConfig, type AxiosResponse, type CreateAxiosDefaults, type InternalAxiosRequestConfig } from 'axios';
export type Response<T> = [err: AxiosError | null, data: T | null, resp: Result<T> | null];
export type HttpResponse<T> = [err: AxiosError | null, data: T | null, resp: Result<T> | null];
export interface RequestOptions extends CreateAxiosDefaults {
export interface HttpRequestOptions extends CreateAxiosDefaults {
requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
responseInterceptor?: (resp: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;
responseErrorInterceptor?: (error: any) => any;
}
export class RequestClient {
private instance: AxiosInstance;
constructor(config?: RequestOptions) {
this.instance = axios.create(config);
const requestInterceptor = config?.requestInterceptor ?? RequestClient.defaultRequestInterceptor;
const responseInterceptor = config?.responseInterceptor ?? RequestClient.defaultResponseInterceptor;
const responseErrorInterceptor = config?.responseErrorInterceptor ?? RequestClient.defaultResponseErrorInterceptor;
this.instance.interceptors.request.use(requestInterceptor);
this.instance.interceptors.response.use(responseInterceptor, responseErrorInterceptor);
}
private static defaultRequestInterceptor(config: InternalAxiosRequestConfig) {
return config;
}
private static defaultResponseInterceptor(response: AxiosResponse) {
return response;
}
private static defaultResponseErrorInterceptor(error: any) {
const err = error as AxiosError;
if (err.status === 401) {
}
if (err.status === 404) {
export const createHttpClient = (config?: HttpRequestOptions) => {
const defaultRequestInterceptor = (config: InternalAxiosRequestConfig) => config;
const defaultResponseInterceptor = (response: AxiosResponse) => response;
const defaultResponseErrorInterceptor = (error: any) => {
if (isAxiosError(error)) {
if (error.status === 401) {
// 处理 401 错误
}
if (error.status === 404) {
// 处理 404 错误
}
}
return Promise.reject(error);
}
};
public get requestInstance(): AxiosInstance {
return this.instance;
}
const requestInterceptor = config?.requestInterceptor ?? defaultRequestInterceptor;
const responseInterceptor = config?.responseInterceptor ?? defaultResponseInterceptor;
const responseErrorInterceptor = config?.responseErrorInterceptor ?? defaultResponseErrorInterceptor;
get<T>(url: string, options?: AxiosRequestConfig & { retRaw?: boolean }): Promise<Response<T>> {
const instance = axios.create(config);
instance.interceptors.request.use(requestInterceptor);
instance.interceptors.response.use(responseInterceptor, responseErrorInterceptor);
const httpGet = <T>(url: string, options?: AxiosRequestConfig & { retRaw?: boolean }): Promise<HttpResponse<T>> => {
const { retRaw, ...reqConfig } = options ?? {};
return new Promise((resolve) => {
this.instance
instance
.get(url, {
...reqConfig,
})
@@ -64,12 +51,12 @@ export class RequestClient {
resolve([err as AxiosError, null, null]);
});
});
}
};
post<T>(url: string, data?: AxiosRequestConfig['data'], options?: Partial<Omit<AxiosRequestConfig, 'data'>> & { retRaw?: boolean; upload?: boolean }): Promise<Response<T>> {
const httpPost = <T>(url: string, data?: AxiosRequestConfig['data'], options?: Partial<Omit<AxiosRequestConfig, 'data'>> & { retRaw?: boolean; upload?: boolean }): Promise<HttpResponse<T>> => {
const { retRaw, upload, ...reqConfig } = options ?? {};
return new Promise((resolve) => {
this.instance
instance
.post(url, data, { headers: { 'content-type': upload ? 'multipart/form-data' : 'application/json' }, ...reqConfig })
.then((res) => {
const resData = res.data;
@@ -83,12 +70,12 @@ export class RequestClient {
resolve([err as AxiosError, null, null]);
});
});
}
};
put<T>(url: string, data?: AxiosRequestConfig['data'], options?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<Response<T>> {
const httpPut = <T>(url: string, data?: AxiosRequestConfig['data'], options?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<HttpResponse<T>> => {
const reqConfig = options ?? {};
return new Promise((resolve) => {
this.instance
instance
.put<Result<T>>(url, data, { ...reqConfig })
.then((res) => {
resolve([null, res.data.data, res.data]);
@@ -97,12 +84,12 @@ export class RequestClient {
resolve([err as AxiosError, null, null]);
});
});
}
};
delete<T>(url: string, idList: string[], options?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<Response<T>> {
const httpDelete = <T>(url: string, idList: string[], options?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<HttpResponse<T>> => {
const reqConfig = options ?? {};
return new Promise((resolve) => {
this.instance
instance
.delete<Result<T>>(url, { ...reqConfig, data: idList })
.then((res) => {
resolve([null, res.data.data, res.data]);
@@ -111,11 +98,21 @@ export class RequestClient {
resolve([err as AxiosError, null, null]);
});
});
}
}
};
return {
get clientInstance() {
return instance;
},
get: httpGet,
post: httpPost,
put: httpPut,
delete: httpDelete,
};
};
// 从响应中解析出数据
export const unwrapResponse = <T>(resp: Response<T>) => {
export const unwrapResponse = <T>(resp: HttpResponse<T>) => {
const [err, data, result] = resp;
// 如果 err 存在说明有 http 错误,那么直接抛出错误,

View File

@@ -4,5 +4,5 @@ export * from './download';
export * from './env';
export * from './format-duration';
export * from './random-num';
export * from './request-client';
export * from './http-client';
export * from './sleep';