axios.ts 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. import axios, { AxiosRequestConfig, AxiosRequestHeaders } from 'axios';
  2. import { showMessage } from './status'; // 引入状态码文件
  3. import { ElMessage, ElMessageBox } from 'element-plus' // 引入el 提示框,这个项目里用什么组件库这里引什么
  4. import { useAppStore } from '@/stores/index'
  5. import router from '@/router'
  6. // 设置接口超时时间
  7. axios.defaults.timeout = 60000;
  8. // 请求地址,这里是动态赋值的的环境变量,下一篇会细讲,这里跳过
  9. // @ts-ignore
  10. axios.defaults.baseURL = 'https://apidoc.raycos.net'//import.meta.env.VITE_API_URL; http://192.168.8.103:9999 https://apidoc.raycos.net
  11. // 请求拦截器
  12. axios.interceptors.request.use(function (config) {
  13. const store = useAppStore();
  14. config.headers['Content-Type'] = 'application/json;charset=UTF-8';
  15. // 统一设置用户身份 token
  16. if (store.user && store.user.token) {
  17. (config.headers as AxiosRequestHeaders).Authorization = `Bearer ${store.user.token}`
  18. }
  19. return config
  20. }, function (error) {
  21. return Promise.reject(error)
  22. })
  23. // 控制登录过期的锁(是否正在处理登录过期)
  24. let isRefreshing = false
  25. let isShowingError = false;
  26. // 响应拦截器
  27. axios.interceptors.response.use(function (response) {
  28. // 统一处理接口响应错误,如 token 过期无效、服务端异常等
  29. const status = response.data.status
  30. const store = useAppStore();
  31. /* 正确响应 */
  32. if (!status || status === 200) {
  33. return response
  34. }
  35. /* 错误响应 */
  36. // 登录过期处理
  37. if (status === 401) {
  38. if (isRefreshing) return Promise.reject(response)
  39. isRefreshing = true
  40. ElMessageBox.confirm('登录已过期,您可以取消停留在此页面,或确认重新登录', '登录过期', {
  41. confirmButtonText: '确认',
  42. cancelButtonText: '取消'
  43. })
  44. .then(() => {
  45. // 清除本地登录状态
  46. store.setUser(null)
  47. // 跳转到登录页
  48. router.push({
  49. name: 'login',
  50. query: {
  51. redirect: router.currentRoute.value.fullPath
  52. }
  53. })
  54. })
  55. .catch(() => { })
  56. .finally(() => {
  57. isRefreshing = false
  58. })
  59. // 抛出异常
  60. return Promise.reject(response)
  61. }
  62. // 其他错误响应
  63. return response;
  64. }, function (error) {
  65. const { response } = error;
  66. if (response) {
  67. // 请求已发出,但是不在2xx的范围
  68. showMessage(response.code); // 传入响应码,匹配响应码对应信息
  69. ElMessage.error(response.data.message || '请求失败,请稍后重试');
  70. return Promise.reject(response.data);
  71. } else {
  72. // 处理网络错误或请求未发出的情况
  73. // 处理网络错误或请求未发出的情况
  74. if (!isShowingError) {
  75. isShowingError = true;
  76. //ElMessage.error('网络连接异常,请稍后再试!');
  77. setTimeout(() => {
  78. isShowingError = false; // 重置标志位
  79. }, 3000); // 3秒后允许再次显示错误
  80. }
  81. return Promise.reject(error);
  82. }
  83. })
  84. // 封装 GET POST 请求并导出
  85. export function request(url = '', params = {}, type = 'POST') {
  86. //设置 url params type 的默认值
  87. return new Promise((resolve, reject) => {
  88. let promise
  89. // 根据请求类型设置请求方法
  90. switch (type.toUpperCase()) {
  91. case 'GET':
  92. promise = axios({
  93. url,
  94. params,
  95. method: 'GET'
  96. });
  97. break;
  98. case 'POST':
  99. promise = axios({
  100. url,
  101. data: params,
  102. method: 'POST'
  103. });
  104. break;
  105. case 'PUT':
  106. promise = axios({
  107. url,
  108. data: params,
  109. method: 'PUT'
  110. });
  111. break;
  112. default:
  113. promise = axios({
  114. url,
  115. data: params,
  116. method: 'POST' // 默认为POST
  117. });
  118. }
  119. //处理返回
  120. promise.then(res => {
  121. resolve(res)
  122. }).catch(err => {
  123. reject(err)
  124. })
  125. })
  126. }