Axios.ts 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. import type { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios';
  2. import axios from 'axios';
  3. import { AxiosCanceler } from './axiosCancel';
  4. import { isFunction } from '/@/utils/is';
  5. import { cloneDeep } from 'lodash-es';
  6. import type { RequestOptions, CreateAxiosOptions, Result, UploadFileParams } from './types';
  7. // import { ContentTypeEnum } from '/@/enums/httpEnum';
  8. import { errorResult } from './const';
  9. import { ContentTypeEnum } from '/@/enums/httpEnum';
  10. export * from './axiosTransform';
  11. /**
  12. * @description: axios模块
  13. */
  14. export class VAxios {
  15. private axiosInstance: AxiosInstance;
  16. private readonly options: CreateAxiosOptions;
  17. constructor(options: CreateAxiosOptions) {
  18. this.options = options;
  19. this.axiosInstance = axios.create(options);
  20. this.setupInterceptors();
  21. }
  22. /**
  23. * @description: 创建axios实例
  24. */
  25. private createAxios(config: CreateAxiosOptions): void {
  26. this.axiosInstance = axios.create(config);
  27. }
  28. private getTransform() {
  29. const { transform } = this.options;
  30. return transform;
  31. }
  32. getAxios(): AxiosInstance {
  33. return this.axiosInstance;
  34. }
  35. /**
  36. * @description: 重新配置axios
  37. */
  38. configAxios(config: CreateAxiosOptions) {
  39. if (!this.axiosInstance) {
  40. return;
  41. }
  42. this.createAxios(config);
  43. }
  44. /**
  45. * @description: 设置通用header
  46. */
  47. setHeader(headers: any): void {
  48. if (!this.axiosInstance) {
  49. return;
  50. }
  51. Object.assign(this.axiosInstance.defaults.headers, headers);
  52. }
  53. /**
  54. * @description: 拦截器配置
  55. */
  56. private setupInterceptors() {
  57. const transform = this.getTransform();
  58. if (!transform) {
  59. return;
  60. }
  61. const {
  62. requestInterceptors,
  63. requestInterceptorsCatch,
  64. responseInterceptors,
  65. responseInterceptorsCatch,
  66. } = transform;
  67. const axiosCanceler = new AxiosCanceler();
  68. // 请求拦截器配置处理
  69. this.axiosInstance.interceptors.request.use((config: AxiosRequestConfig) => {
  70. const { headers: { ignoreCancelToken } = { ignoreCancelToken: false } } = config;
  71. !ignoreCancelToken && axiosCanceler.addPending(config);
  72. if (requestInterceptors && isFunction(requestInterceptors)) {
  73. config = requestInterceptors(config);
  74. }
  75. return config;
  76. }, undefined);
  77. // 请求拦截器错误捕获
  78. requestInterceptorsCatch &&
  79. isFunction(requestInterceptorsCatch) &&
  80. this.axiosInstance.interceptors.request.use(undefined, requestInterceptorsCatch);
  81. // 响应结果拦截器处理
  82. this.axiosInstance.interceptors.response.use((res: AxiosResponse<any>) => {
  83. res && axiosCanceler.removePending(res.config);
  84. if (responseInterceptors && isFunction(responseInterceptors)) {
  85. res = responseInterceptors(res);
  86. }
  87. return res;
  88. }, undefined);
  89. // 响应结果拦截器错误捕获
  90. responseInterceptorsCatch &&
  91. isFunction(responseInterceptorsCatch) &&
  92. this.axiosInstance.interceptors.response.use(undefined, responseInterceptorsCatch);
  93. }
  94. /**
  95. * @description: 文件上传
  96. */
  97. uploadFile<T = any>(config: AxiosRequestConfig, params: UploadFileParams) {
  98. const formData = new window.FormData();
  99. if (params.data) {
  100. Object.keys(params.data).forEach((key) => {
  101. if (!params.data) return;
  102. const value = params.data[key];
  103. if (Array.isArray(value)) {
  104. value.forEach((item) => {
  105. formData.append(`${key}[]`, item);
  106. });
  107. return;
  108. }
  109. formData.append(key, params.data[key]);
  110. });
  111. }
  112. formData.append(params.name || 'file', params.file, params.filename);
  113. return this.axiosInstance.request<T>({
  114. ...config,
  115. method: 'POST',
  116. data: formData,
  117. headers: {
  118. 'Content-type': ContentTypeEnum.FORM_DATA,
  119. ignoreCancelToken: true,
  120. },
  121. });
  122. }
  123. /**
  124. * @description: 请求方法
  125. */
  126. request<T = any>(config: AxiosRequestConfig, options?: RequestOptions): Promise<T> {
  127. let conf: AxiosRequestConfig = cloneDeep(config);
  128. const transform = this.getTransform();
  129. const { requestOptions } = this.options;
  130. const opt: RequestOptions = Object.assign({}, requestOptions, options);
  131. const { beforeRequestHook, requestCatch, transformRequestData } = transform || {};
  132. if (beforeRequestHook && isFunction(beforeRequestHook)) {
  133. conf = beforeRequestHook(conf, opt);
  134. }
  135. return new Promise((resolve, reject) => {
  136. this.axiosInstance
  137. .request<any, AxiosResponse<Result>>(conf)
  138. .then((res: AxiosResponse<Result>) => {
  139. if (transformRequestData && isFunction(transformRequestData)) {
  140. const ret = transformRequestData(res, opt);
  141. ret !== errorResult ? resolve(ret) : reject(new Error('request error!'));
  142. return;
  143. }
  144. resolve((res as unknown) as Promise<T>);
  145. })
  146. .catch((e: Error) => {
  147. if (requestCatch && isFunction(requestCatch)) {
  148. reject(requestCatch(e));
  149. return;
  150. }
  151. reject(e);
  152. });
  153. });
  154. }
  155. }