request.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. import axios from 'axios' // 引入axios
  2. import { ElMessage, ElMessageBox } from 'element-plus'
  3. import { useUserStore } from '@/pinia/modules/user'
  4. import { emitter } from '@/utils/bus.js'
  5. import router from '@/router/index'
  6. const service = axios.create({
  7. baseURL: import.meta.env.VITE_BASE_API,
  8. timeout: 99999
  9. })
  10. let acitveAxios = 0
  11. let timer
  12. const showLoading = () => {
  13. acitveAxios++
  14. if (timer) {
  15. clearTimeout(timer)
  16. }
  17. timer = setTimeout(() => {
  18. if (acitveAxios > 0) {
  19. emitter.emit('showLoading')
  20. }
  21. }, 400)
  22. }
  23. const closeLoading = () => {
  24. acitveAxios--
  25. if (acitveAxios <= 0) {
  26. clearTimeout(timer)
  27. emitter.emit('closeLoading')
  28. }
  29. }
  30. // http request 拦截器
  31. service.interceptors.request.use(
  32. config => {
  33. if (!config.donNotShowLoading) {
  34. showLoading()
  35. }
  36. const userStore = useUserStore()
  37. config.headers = {
  38. 'Content-Type': 'application/json',
  39. 'x-token': userStore.token,
  40. 'x-user-id': userStore.userInfo.ID,
  41. ...config.headers
  42. }
  43. return config
  44. },
  45. error => {
  46. closeLoading()
  47. ElMessage({
  48. showClose: true,
  49. message: error,
  50. type: 'error'
  51. })
  52. return error
  53. }
  54. )
  55. // http response 拦截器
  56. service.interceptors.response.use(
  57. response => {
  58. const userStore = useUserStore()
  59. closeLoading()
  60. if (response.headers['new-token']) {
  61. userStore.setToken(response.headers['new-token'])
  62. }
  63. if (response.data.code === 0 || response.headers.success === 'true') {
  64. if (response.headers.msg) {
  65. response.data.msg = decodeURI(response.headers.msg)
  66. }
  67. return response.data
  68. } else {
  69. ElMessage({
  70. showClose: true,
  71. message: response.data.msg || decodeURI(response.headers.msg),
  72. type: 'error'
  73. })
  74. if (response.data.data && response.data.data.reload) {
  75. userStore.token = ''
  76. localStorage.clear()
  77. router.push({ name: 'Login', replace: true })
  78. }
  79. return response.data.msg ? response.data : response
  80. }
  81. },
  82. error => {
  83. closeLoading()
  84. if (!error.response) {
  85. ElMessageBox.confirm(`
  86. <p>检测到请求错误</p>
  87. <p>${error}</p>
  88. `, '请求报错', {
  89. dangerouslyUseHTMLString: true,
  90. distinguishCancelAndClose: true,
  91. confirmButtonText: '稍后重试',
  92. cancelButtonText: '取消'
  93. })
  94. return
  95. }
  96. switch (error.response.status) {
  97. case 500:
  98. ElMessageBox.confirm(`
  99. <p>检测到接口错误${error}</p>
  100. <p>错误码<span style="color:red"> 500 </span>:此类错误内容常见于后台panic,请先查看后台日志,如果影响您正常使用可强制登出清理缓存</p>
  101. `, '接口报错', {
  102. dangerouslyUseHTMLString: true,
  103. distinguishCancelAndClose: true,
  104. confirmButtonText: '清理缓存',
  105. cancelButtonText: '取消'
  106. })
  107. .then(() => {
  108. const userStore = useUserStore()
  109. userStore.token = ''
  110. localStorage.clear()
  111. router.push({ name: 'Login', replace: true })
  112. })
  113. break
  114. case 404:
  115. ElMessageBox.confirm(`
  116. <p>检测到接口错误${error}</p>
  117. <p>错误码<span style="color:red"> 404 </span>:此类错误多为接口未注册(或未重启)或者请求路径(方法)与api路径(方法)不符--如果为自动化代码请检查是否存在空格</p>
  118. `, '接口报错', {
  119. dangerouslyUseHTMLString: true,
  120. distinguishCancelAndClose: true,
  121. confirmButtonText: '我知道了',
  122. cancelButtonText: '取消'
  123. })
  124. break
  125. }
  126. return error
  127. }
  128. )
  129. export default service