request.ts 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. import { breakpointsTailwind } from '@vueuse/core'
  2. import { ElMessage } from 'element-plus'
  3. import useMemberStore from '@/stores/member'
  4. import qs from 'qs'
  5. interface ConfigOption {
  6. showErrorMessage?: boolean
  7. showSuccessMessage?: boolean,
  8. headers?: Headers
  9. }
  10. interface FetchOptions {
  11. baseURL: string
  12. headers: Record<string, any>
  13. onRequest?: (data: any) => void
  14. onResponse?: (data: any) => void
  15. onResponseError?: (data: any) => void
  16. showErrorMessage?: boolean
  17. showSuccessMessage?: boolean
  18. watch: boolean
  19. }
  20. class Http {
  21. private options: FetchOptions = {
  22. baseURL: '',
  23. headers: {},
  24. watch: false
  25. }
  26. public constructor() {
  27. /**
  28. * 全局请求拦截器
  29. */
  30. this.options.onRequest = (data) => {
  31. const runtimeConfig = useRuntimeConfig()
  32. this.options.baseURL = runtimeConfig.public.VITE_APP_BASE_URL || `${location.origin}/api/`
  33. this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_SITEID_KEY] = useCookie('siteId').value || runtimeConfig.public.VITE_SITE_ID
  34. this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_CHANNEL_KEY] = 'pc'
  35. if (getToken()) this.options.headers[runtimeConfig.public.VITE_REQUEST_HEADER_TOKEN_KEY] = getToken()
  36. }
  37. /**
  38. * 全局响应拦截器
  39. */
  40. this.options.onResponse = ({ response, options }) => {
  41. const { _data: data } = response
  42. this.handleNetworkError(response)
  43. if (data.code != undefined) {
  44. if (data.code == 1) {
  45. if (options.showSuccessMessage) ElMessage({ message: data.msg, type: 'success' })
  46. } else {
  47. if (data.code == 0 || data.code == 400) {
  48. ElMessage({ message: data.msg, type: 'error' })
  49. } else {
  50. this.handleAuthError(data.code)
  51. }
  52. }
  53. }
  54. }
  55. }
  56. public get(url: string, query = {}, config: ConfigOption = {}) {
  57. url += '?' + qs.stringify(query)
  58. return this.request(url, 'GET', {}, config)
  59. }
  60. public post(url: string, body = {}, config: ConfigOption = {}) {
  61. return this.request(url, 'POST', { body }, config)
  62. }
  63. public put(url: string, body = {}, config: ConfigOption = {}) {
  64. return this.request(url, 'PUT', { body }, config)
  65. }
  66. public delete(url: string, config: ConfigOption = {}) {
  67. return this.request(url, 'DELETE', {}, config)
  68. }
  69. /**
  70. * 发送请求
  71. * @param url
  72. * @param method
  73. * @param param
  74. * @param config
  75. */
  76. private request(url: string, method: string, param: AnyObject = {}, config: ConfigOption = {}) {
  77. return new Promise((resolve, reject) => {
  78. setTimeout(() => {
  79. // 处理首次请求baseurl空的问题
  80. const runtimeConfig = useRuntimeConfig()
  81. !this.options.baseURL && (this.options.baseURL = runtimeConfig.public.VITE_APP_BASE_URL || `${location.origin}/api/`)
  82. this.options.baseURL.substr(-1) != '/' && (this.options.baseURL += '/')
  83. // 处理数组格式
  84. for (const key in param.query) {
  85. if (param.query[key] instanceof Array) {
  86. param.query[key].forEach((item, index) => {
  87. param.query[`${key}[${index}]`] = item
  88. });
  89. delete param.query[key]
  90. }
  91. }
  92. useFetch(url, { ...this.options, method, ...config, ...param }).then((response) => {
  93. const { data: { value }, error } = response
  94. if (value) {
  95. if (value.code && value.code == 1) {
  96. resolve(value)
  97. } else {
  98. if (value.type && value.type == 'application/zip') {
  99. resolve(value)
  100. } else {
  101. reject(value)
  102. }
  103. }
  104. } else {
  105. reject(error)
  106. }
  107. }).catch(err => {
  108. reject(err)
  109. })
  110. }, this.options.baseURL ? 0 : 500);
  111. })
  112. }
  113. private handleAuthError(code: number) {
  114. switch (code) {
  115. case 401:
  116. useMemberStore().logout()
  117. break;
  118. }
  119. }
  120. private handleNetworkError(err: any) {
  121. if (err.status && err.status != 200) {
  122. let errMessage = ''
  123. switch (err.status) {
  124. case 400:
  125. errMessage = t('request.400')
  126. break
  127. case 401:
  128. errMessage = t('request.401')
  129. break
  130. case 403:
  131. errMessage = t('request.403')
  132. break
  133. case 404:
  134. errMessage = err.url + t('request.404')
  135. break
  136. case 405:
  137. errMessage = t('request.405')
  138. break
  139. case 408:
  140. errMessage = t('request.408')
  141. break
  142. case 409:
  143. errMessage = t('request.409')
  144. break
  145. case 500:
  146. errMessage = t('request.500')
  147. break
  148. case 501:
  149. errMessage = t('request.501')
  150. break
  151. case 502:
  152. errMessage = t('request.502')
  153. break
  154. case 503:
  155. errMessage = t('request.503')
  156. break
  157. case 504:
  158. errMessage = t('request.504')
  159. break
  160. case 505:
  161. errMessage = t('request.505')
  162. break
  163. }
  164. ElMessage({ message: errMessage, type: 'error' })
  165. }
  166. }
  167. }
  168. const request = new Http()
  169. export default request