axios-wrapper.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /* eslint-disable no-console */
  2. /* eslint-disable no-param-reassign */
  3. import _ from 'lodash';
  4. import Axios from 'axios';
  5. import { Util, Error } from 'naf-core';
  6. // import { Indicator } from 'mint-ui';
  7. import type { IOptionsType, IQueryType, IRequestResult } from './types.util';
  8. const { trimData, isNullOrUndefined } = Util;
  9. const { ErrorCode } = Error;
  10. let currentRequests = 0;
  11. // // 参数类型设置
  12. // type valueType = string | number | object | boolean | Array<any>;
  13. // type queryType = string | number | boolean;
  14. // export interface IQueryType {
  15. // [props: string]: queryType;
  16. // }
  17. // export interface IOptionsType {
  18. // [props: string]: valueType;
  19. // }
  20. // export interface IRequestResult {
  21. // errcode: string | number;
  22. // errmsg: string | number;
  23. // details?: string;
  24. // [props: string]: any;
  25. // }
  26. export class AxiosWrapper {
  27. constructor({ baseUrl = import.meta.env.VITE_REQUEST_BASE, unwrap = true } = {}) {
  28. this.baseUrl = baseUrl;
  29. this.unwrap = unwrap;
  30. }
  31. baseUrl: string;
  32. unwrap: boolean;
  33. // 替换uri中的参数变量
  34. static merge(uri: string, query: IQueryType) {
  35. if (!uri.includes(':')) {
  36. return uri;
  37. }
  38. const keys = [];
  39. const regexp = /\/:([a-z0-9_]+)/gi;
  40. let res;
  41. // eslint-disable-next-line no-cond-assign
  42. while ((res = regexp.exec(uri)) != null) {
  43. keys.push(res[1]);
  44. }
  45. keys.forEach((key) => {
  46. const val = _.get(query, key);
  47. if (!isNullOrUndefined(val)) {
  48. uri = uri.replace(`:${key}`, `${val}`);
  49. }
  50. });
  51. return uri;
  52. }
  53. $get(uri: string, query?: IQueryType, options?: IOptionsType) {
  54. return this.$request(uri, undefined, query, options);
  55. }
  56. $post(uri: string, data: object = {}, query?: IQueryType, options?: IOptionsType) {
  57. return this.$request(uri, data, query, options);
  58. }
  59. $delete(uri: string, data: object = {}, query?: IQueryType, options: IOptionsType = {}) {
  60. options = { ...options, method: 'delete' };
  61. return this.$request(uri, data, query, options);
  62. }
  63. async $request(uri: string, data?: object, query?: IQueryType, options?: IOptionsType) {
  64. if (query && _.isObject(query)) {
  65. const keys = Object.keys(query);
  66. for (const key of keys) {
  67. const val = _.get(query, key);
  68. if (val === '') {
  69. delete query[key];
  70. }
  71. }
  72. }
  73. if (_.isObject(query) && _.isObject(options)) {
  74. options = { ...options, params: query, method: 'get' };
  75. } else if (_.isObject(query) && !query.params) {
  76. options = { params: query };
  77. } else if (_.isObject(query) && query.params) {
  78. options = query;
  79. }
  80. if (!options) options = {};
  81. if (options.params) options.params = trimData(options.params, null, null);
  82. const params = _.get(options, 'params');
  83. const url = AxiosWrapper.merge(uri, params as IQueryType);
  84. currentRequests += 1;
  85. // Indicator.open({
  86. // spinnerType: 'fading-circle',
  87. // });
  88. try {
  89. let returnData: any;
  90. const axios = Axios.create({
  91. baseURL: this.baseUrl
  92. });
  93. // if (util.token && util.token !== null) axios.defaults.headers.common.Authorization = util.token;
  94. const token = localStorage.getItem('token');
  95. const apiToken = localStorage.getItem('apiToken');
  96. if (token) axios.defaults.headers.common['token'] = token;
  97. if (apiToken) axios.defaults.headers.common['api-token'] = apiToken;
  98. const res = await axios.request({
  99. method: isNullOrUndefined(data) ? 'get' : 'post',
  100. url,
  101. data,
  102. responseType: 'json',
  103. ...options
  104. });
  105. const returnRes: IRequestResult = res.data;
  106. const { errcode, errmsg, details } = returnRes;
  107. if (errcode) {
  108. console.warn(`[${uri}] fail: ${errcode}-${errmsg} ${details}`);
  109. return returnRes;
  110. }
  111. // unwrap data
  112. if (this.unwrap) {
  113. returnData = returnRes;
  114. }
  115. // 处理apiToken
  116. const { apiToken: at, ...others } = returnData;
  117. if (at) localStorage.setItem('apiToken', at);
  118. return others;
  119. } catch (err: any) {
  120. let errmsg = '接口请求失败,请稍后重试';
  121. if (err.response) {
  122. const { status } = err.response;
  123. if (status === 401) errmsg = '用户认证失败,请重新登录';
  124. if (status === 403) errmsg = '当前用户不允许执行该操作';
  125. }
  126. console.error(
  127. `[AxiosWrapper] 接口请求失败: ${err.config && err.config.url} -
  128. ${err.message}`
  129. );
  130. return { errcode: ErrorCode.SERVICE_FAULT, errmsg, details: err.message };
  131. } finally {
  132. /* eslint-disable */
  133. currentRequests -= 1;
  134. if (currentRequests <= 0) {
  135. currentRequests = 0;
  136. // Indicator.close();
  137. }
  138. }
  139. }
  140. }