request.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import axios from 'axios';
  2. import { MessagePlugin as Message } from 'tdesign-vue-next';
  3. import { local, download } from '@/utils/tool';
  4. import { get, isEmpty } from 'lodash';
  5. import qs from 'qs';
  6. import { h } from 'vue';
  7. function createService() {
  8. // 创建一个 axios 实例
  9. const service = axios.create();
  10. // HTTP request 拦截器
  11. service.interceptors.request.use(
  12. (config) => {
  13. if (config.download) {
  14. config.responseType ??= 'blob';
  15. }
  16. return config;
  17. },
  18. (error) => {
  19. // 失败
  20. return Promise.reject(error);
  21. }
  22. );
  23. // HTTP response 拦截器
  24. service.interceptors.response.use(
  25. (response) => {
  26. // 以下代码看后端是否有统一在接口里增加外层code的规范
  27. // if (response.data.code && response.data.code !== 200) {
  28. // Message.error({
  29. // content: response.data.message,
  30. // icon: () => h(IconFaceFrownFill),
  31. // });
  32. // }
  33. if (response.config.download && response.config.responseType === 'blob') {
  34. download(response);
  35. }
  36. return response.data;
  37. },
  38. (error) => {
  39. const err = (text) => {
  40. Message.error({
  41. content:
  42. error.response && error.response.data && error.response.data.message
  43. ? error.response.data.message
  44. : text,
  45. });
  46. };
  47. if (error.response) {
  48. switch (error.response.status) {
  49. case 404:
  50. err(`${error?.config?.url} 服务器资源不存在`);
  51. break;
  52. case 500:
  53. err(`${error?.config?.url} 服务器内部错误`);
  54. break;
  55. case 401:
  56. err('登录状态已过期,需要重新登录');
  57. local.clear();
  58. window.location.href = '/';
  59. break;
  60. case 403:
  61. err(`${error?.config?.url} 没有权限访问该资源`);
  62. break;
  63. default:
  64. err('未知错误!');
  65. }
  66. } else {
  67. err('请求超时,服务器无响应!');
  68. }
  69. return Promise.reject(
  70. error.response && error.response.data ? error.response.data : null
  71. );
  72. }
  73. );
  74. return service;
  75. }
  76. function stringify(data) {
  77. return qs.stringify(data, { allowDots: true, encode: false });
  78. }
  79. /**
  80. * @description 创建请求方法
  81. * @param {Object} service axios 实例
  82. */
  83. function createRequest(service) {
  84. return function (config) {
  85. const env = import.meta.env;
  86. const token = local.get(env.VITE_APP_TOKEN_PREFIX);
  87. const configDefault = {
  88. headers: {
  89. 'Authorization': `Bearer ${token}`,
  90. 'Content-Type': get(
  91. config,
  92. 'headers.Content-Type',
  93. 'application/json;charset=UTF-8'
  94. ),
  95. },
  96. timeout: 60000,
  97. baseURL:
  98. env.VITE_HTTP_PROXY === 'Y'
  99. ? env.VITE_APP_PROXY_PREFIX
  100. : env.VITE_APP_BASE_URL,
  101. data: {},
  102. };
  103. const option = Object.assign(configDefault, config);
  104. // json
  105. if (!isEmpty(option.params)) {
  106. option.url = `${option.url}?${stringify(option.params)}`;
  107. option.params = {};
  108. }
  109. return service(option);
  110. };
  111. }
  112. // 用于真实网络请求的实例和请求方法
  113. export const service = createService();
  114. export const request = createRequest(service);