import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios'; import axios from 'axios'; import type { Result } from '@/axios'; export type Response = [err: AxiosError | null, data: T | null, resp: Result | null]; export interface RequestOptions extends CreateAxiosDefaults { requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise; responseInterceptor?: (resp: AxiosResponse) => AxiosResponse | Promise; 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) { } return Promise.reject(error); } public get requestInstance(): AxiosInstance { return this.instance; } get(url: string, option?: AxiosRequestConfig & { retRaw?: boolean }): Promise> { const { retRaw, ...reqConfig } = option ?? {}; return new Promise((resolve) => { this.instance .get(url, { ...reqConfig, }) .then((res) => { if (retRaw) { resolve([null, res.data as T, null]); } else { const resData = res.data as Result; resolve([null, resData.data, resData]); } }) .catch((err) => { resolve([err as AxiosError, null, null]); }); }); } post(url: string, data?: AxiosRequestConfig['data'], option?: Partial> & { retRaw?: boolean; upload?: boolean }): Promise> { const { retRaw, upload, ...reqConfig } = option ?? {}; return new Promise((resolve) => { this.instance .post(url, data, { headers: { 'content-type': upload ? 'multipart/form-data' : 'application/json' }, ...reqConfig }) .then((res) => { const resData = res.data; if (retRaw) { resolve([null, resData as T, null]); } else { resolve([null, resData.data as T, resData as Result]); } }) .catch((err) => { resolve([err as AxiosError, null, null]); }); }); } put(url: string, data?: AxiosRequestConfig['data'], option?: Partial>): Promise> { const reqConfig = option ?? {}; return new Promise((resolve) => { this.instance .put>(url, data, { ...reqConfig }) .then((res) => { resolve([null, res.data.data, res.data]); }) .catch((err) => { resolve([err as AxiosError, null, null]); }); }); } delete(url: string, idList: string[], option?: Partial>): Promise> { const reqConfig = option ?? {}; return new Promise((resolve) => { this.instance .delete>(url, { ...reqConfig, data: idList }) .then((res) => { resolve([null, res.data.data, res.data]); }) .catch((err) => { resolve([err as AxiosError, null, null]); }); }); } }