import axios, { AxiosRequestConfig, AxiosResponse } from 'axios'; export interface QueryProps extends AxiosRequestConfig { supportRetry?: boolean; successCode?: number | string; retryCount?: number; intervals?: number; statusCodeField?: string; cache?: boolean; clearCache?: boolean; ref?: { cancel: () => void; }; } type DefaultResponse = { data: T; [propsName: string]: any; }; const INTERVALS = 3 * 1000; const RETRYCOUNT = 3; const SUCCESS_CODE = 0; const STATUS_CODE_FIELD = 'code'; const CLEAR_CACHE = true; const reTry = (params: QueryProps) => { const { retryCount, url, intervals } = params; return new Promise((resolve, reject) => { if (retryCount === 1) { reject(`${url} 重试请求次数超过上限,请检查参数`); } else { setTimeout(() => { params.retryCount! -= 1; resolve(restQuery(params)); }, intervals); } }); }; const saveDataToGlobal = (url: string, data: T) => { (globalThis as any)[url] = Object.freeze(data); }; export const restQuery = async (params: QueryProps) => { const { supportRetry = false, successCode, retryCount, intervals, cache, clearCache, statusCodeField, ref, ...requestConfig } = params; if (!successCode) params.successCode = SUCCESS_CODE; if (!retryCount) params.retryCount = RETRYCOUNT; if (!intervals) params.intervals = INTERVALS; if (!statusCodeField) params.statusCodeField = STATUS_CODE_FIELD; if (!clearCache) params.clearCache = CLEAR_CACHE; const axiosParams: AxiosRequestConfig = { ...requestConfig, }; if (ref) { const { CancelToken } = axios; const source = CancelToken.source(); axiosParams.cancelToken = source.token; ref.cancel = (str?: string) => { console.warn(str); return source.cancel(str); }; } if (supportRetry) { try { const result = (await axios(axiosParams)) as AxiosResponse< DefaultResponse >; const { data } = result; if (data[params.statusCodeField!] === params.successCode) { return data; } return reTry(params) as Promise>; } catch (error) { return reTry(params) as Promise>; } } else { if (cache && !clearCache) { const data: DefaultResponse = (globalThis as any).url; if (data) return data; } const result = (await axios(axiosParams)) as AxiosResponse< DefaultResponse >; const { data } = result; if (cache) saveDataToGlobal(axiosParams.url!, data); return data; } };