request.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. import axios from 'axios'
  2. import {
  3. MessageBox,
  4. Message
  5. } from 'element-ui'
  6. import store from '@/store'
  7. import router from '@/router'
  8. const config = {
  9. baseURL: process.env.VUE_APP_BASE_API,
  10. withCredentials: true, // send cookies when cross-domain requests
  11. timeout: 10000 // request timeout
  12. }
  13. // create an axios instance
  14. const service = axios.create(config)
  15. let baseUrl = process.env.VUE_APP_KEYCLOAK_OPTIONS_URL
  16. if (baseUrl.charAt(0) === '/') {
  17. baseUrl = `${location.origin}${baseUrl}`
  18. }
  19. const realm = process.env.VUE_APP_KEYCLOAK_OPTIONS_REALM
  20. const keycloakService = axios.create({
  21. ...config,
  22. baseURL: `${baseUrl}/admin/realms/${realm}`
  23. })
  24. const tenantService = axios.create(config)
  25. const downloadService = axios.create(config)
  26. const CancelToken = axios.CancelToken
  27. let source = null
  28. function getCancelToken () {
  29. if (!source) {
  30. source = CancelToken.source()
  31. }
  32. return source.token
  33. }
  34. export function cancelRequest () {
  35. if (source) {
  36. source.cancel('abort')
  37. source = null
  38. }
  39. }
  40. // request interceptor
  41. service.interceptors.request.use(
  42. defaultRequestInterceptor,
  43. debug
  44. )
  45. keycloakService.interceptors.request.use(
  46. defaultRequestInterceptor,
  47. debug
  48. )
  49. tenantService.interceptors.request.use(
  50. defaultRequestInterceptor,
  51. debug
  52. )
  53. tenantService.interceptors.request.use(
  54. config => {
  55. const { tenant, org, user } = config.params || config.data || {}
  56. console.log('url', config.method, config.url)
  57. console.log('tenant', tenant)
  58. console.log('org', org)
  59. console.log('user', user)
  60. if (!tenant && !org && !user) {
  61. Message({
  62. type: 'warning',
  63. message: '缺失scope信息'
  64. })
  65. return Promise.reject()
  66. }
  67. return config
  68. },
  69. null
  70. )
  71. downloadService.interceptors.request.use(
  72. config => {
  73. config.responseType = 'blob'
  74. config.timeout = 60000
  75. config.background = true
  76. return config
  77. },
  78. debug
  79. )
  80. downloadService.interceptors.request.use(
  81. defaultRequestInterceptor,
  82. debug
  83. )
  84. // response interceptor
  85. service.interceptors.response.use(
  86. responseInterceptor,
  87. responseErrorInterceptor
  88. )
  89. keycloakService.interceptors.response.use(
  90. response => response.data,
  91. responseErrorInterceptor
  92. )
  93. tenantService.interceptors.response.use(
  94. responseInterceptor,
  95. responseErrorInterceptor
  96. )
  97. export default service
  98. export const keycloakRequest = keycloakService
  99. export const tenantRequest = tenantService
  100. export const downloadRequest = downloadService
  101. function defaultRequestInterceptor (config) {
  102. // do something before request is sent
  103. if (!store.getters.token) {
  104. return Promise.reject()
  105. }
  106. config.headers['Authorization'] = `Bearer ${store.getters.token}`
  107. if (!config.background) {
  108. config.cancelToken = getCancelToken()
  109. }
  110. return config
  111. }
  112. function debug (error) {
  113. console.log('http debug', error) // for debug
  114. return Promise.reject(error)
  115. }
  116. function responseInterceptor (response) {
  117. const res = response.data || {}
  118. if (res.success) {
  119. return res
  120. }
  121. if (!response.config?.custom) {
  122. Message({
  123. type: 'error',
  124. message: res.errMessage || '请求失败'
  125. })
  126. }
  127. return Promise.reject(res)
  128. }
  129. function responseErrorInterceptor (error) {
  130. const isCancel = !error || axios.isCancel(error)
  131. if (isCancel) {
  132. return Promise.reject({ isCancel })
  133. }
  134. const { response, config } = error
  135. if (response) {
  136. const { status } = response
  137. if (status === 401) {
  138. if (store.getters.token) {
  139. try {
  140. store.dispatch('user/clearToken')
  141. MessageBox.close()
  142. } finally {
  143. MessageBox.confirm(
  144. '登录状态已过期,请重新登录',
  145. '系统提示',
  146. {
  147. type: 'warning',
  148. confirmButtonText: '重新登录',
  149. center: true,
  150. showClose: false,
  151. showCancelButton: false,
  152. closeOnClickModal: false,
  153. closeOnPressEscape: false,
  154. closeOnHashChange: false
  155. }
  156. ).then(() => {
  157. store.dispatch('user/logout')
  158. })
  159. }
  160. }
  161. return Promise.reject({ isCancel: true })
  162. }
  163. if (status === 403) {
  164. Message({
  165. type: 'warning',
  166. message: '暂无相关权限,请联系管理员'
  167. })
  168. return Promise.reject({ isCancel: true })
  169. }
  170. if (status === 423) {
  171. try {
  172. store.dispatch('user/clearToken')
  173. MessageBox.close()
  174. } finally {
  175. MessageBox.confirm(
  176. '系统已锁定,请联系管理员',
  177. '系统提示',
  178. {
  179. type: 'warning',
  180. showClose: false,
  181. showConfirmButton: false,
  182. showCancelButton: false,
  183. closeOnClickModal: false,
  184. closeOnPressEscape: false,
  185. closeOnHashChange: false
  186. }
  187. )
  188. router.replace('/error')
  189. }
  190. return Promise.reject({ isCancel: true })
  191. }
  192. if (!config?.custom) {
  193. const { errMessage, errorMessage } = response.data
  194. Message({
  195. type: 'error',
  196. message: errMessage || errorMessage || `请求异常[${status}]`
  197. })
  198. }
  199. return Promise.reject({ ...response.data })
  200. }
  201. let { message } = error
  202. if (!config?.custom) {
  203. if (message) {
  204. if (/timeout/.test(message)) {
  205. message = '请求超时'
  206. }
  207. } else {
  208. message = '请求异常'
  209. }
  210. Message({
  211. type: 'error',
  212. message
  213. })
  214. }
  215. return Promise.reject({ errCode: -1, errMessage: message })
  216. }