request-client.ts 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import type { AxiosInstance, AxiosResponse } from 'axios';
  2. import type { RequestClientConfig, RequestClientOptions } from './types';
  3. import { bindMethods, merge } from '@vben/utils';
  4. import axios from 'axios';
  5. import { FileDownloader } from './modules/downloader';
  6. import { InterceptorManager } from './modules/interceptor';
  7. import { FileUploader } from './modules/uploader';
  8. class RequestClient {
  9. public addRequestInterceptor: InterceptorManager['addRequestInterceptor'];
  10. public addResponseInterceptor: InterceptorManager['addResponseInterceptor'];
  11. public download: FileDownloader['download'];
  12. // 是否正在刷新token
  13. public isRefreshing = false;
  14. // 刷新token队列
  15. public refreshTokenQueue: ((token: string) => void)[] = [];
  16. public upload: FileUploader['upload'];
  17. private readonly instance: AxiosInstance;
  18. /**
  19. * 构造函数,用于创建Axios实例
  20. * @param options - Axios请求配置,可选
  21. */
  22. constructor(options: RequestClientOptions = {}) {
  23. // 合并默认配置和传入的配置
  24. const defaultConfig: RequestClientOptions = {
  25. headers: {
  26. 'Content-Type': 'application/json;charset=utf-8',
  27. },
  28. responseReturn: 'raw',
  29. // 默认超时时间
  30. timeout: 10_000,
  31. };
  32. const { ...axiosConfig } = options;
  33. const requestConfig = merge(axiosConfig, defaultConfig);
  34. this.instance = axios.create(requestConfig);
  35. bindMethods(this);
  36. // 实例化拦截器管理器
  37. const interceptorManager = new InterceptorManager(this.instance);
  38. this.addRequestInterceptor =
  39. interceptorManager.addRequestInterceptor.bind(interceptorManager);
  40. this.addResponseInterceptor =
  41. interceptorManager.addResponseInterceptor.bind(interceptorManager);
  42. // 实例化文件上传器
  43. const fileUploader = new FileUploader(this);
  44. this.upload = fileUploader.upload.bind(fileUploader);
  45. // 实例化文件下载器
  46. const fileDownloader = new FileDownloader(this);
  47. this.download = fileDownloader.download.bind(fileDownloader);
  48. }
  49. /**
  50. * DELETE请求方法
  51. */
  52. public delete<T = any>(
  53. url: string,
  54. config?: RequestClientConfig,
  55. ): Promise<T> {
  56. return this.request<T>(url, { ...config, method: 'DELETE' });
  57. }
  58. /**
  59. * GET请求方法
  60. */
  61. public get<T = any>(url: string, config?: RequestClientConfig): Promise<T> {
  62. return this.request<T>(url, { ...config, method: 'GET' });
  63. }
  64. /**
  65. * POST请求方法
  66. */
  67. public post<T = any>(
  68. url: string,
  69. data?: any,
  70. config?: RequestClientConfig,
  71. ): Promise<T> {
  72. return this.request<T>(url, { ...config, data, method: 'POST' });
  73. }
  74. /**
  75. * PUT请求方法
  76. */
  77. public put<T = any>(
  78. url: string,
  79. data?: any,
  80. config?: RequestClientConfig,
  81. ): Promise<T> {
  82. return this.request<T>(url, { ...config, data, method: 'PUT' });
  83. }
  84. /**
  85. * 通用的请求方法
  86. */
  87. public async request<T>(
  88. url: string,
  89. config: RequestClientConfig,
  90. ): Promise<T> {
  91. try {
  92. const response: AxiosResponse<T> = await this.instance({
  93. url,
  94. ...config,
  95. });
  96. return response as T;
  97. } catch (error: any) {
  98. throw error.response ? error.response.data : error;
  99. }
  100. }
  101. }
  102. export { RequestClient };