alova.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import type { uniappRequestAdapter } from '@alova/adapter-uniapp'
  2. import type { IResponse } from './types'
  3. import AdapterUniapp from '@alova/adapter-uniapp'
  4. import { createAlova } from 'alova'
  5. import { createServerTokenAuthentication } from 'alova/client'
  6. import VueHook from 'alova/vue'
  7. import { toast } from '@/utils/toast'
  8. import { ContentTypeEnum, ResultEnum, ShowMessage } from './enum'
  9. // 配置动态Tag
  10. export const API_DOMAINS = {
  11. DEFAULT: import.meta.env.VITE_SERVER_BASEURL,
  12. SECONDARY: import.meta.env.VITE_API_SECONDARY_URL,
  13. }
  14. /**
  15. * 创建请求实例
  16. */
  17. const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
  18. typeof VueHook,
  19. typeof uniappRequestAdapter
  20. >({
  21. refreshTokenOnError: {
  22. isExpired: (error) => {
  23. return error.response?.status === ResultEnum.Unauthorized
  24. },
  25. handler: async () => {
  26. try {
  27. // await authLogin();
  28. }
  29. catch (error) {
  30. // 切换到登录页
  31. await uni.reLaunch({ url: '/pages/common/login/index' })
  32. throw error
  33. }
  34. },
  35. },
  36. })
  37. /**
  38. * alova 请求实例
  39. */
  40. const alovaInstance = createAlova({
  41. baseURL: import.meta.env.VITE_API_BASE_URL,
  42. ...AdapterUniapp(),
  43. timeout: 5000,
  44. statesHook: VueHook,
  45. beforeRequest: onAuthRequired((method) => {
  46. // 设置默认 Content-Type
  47. method.config.headers = {
  48. ContentType: ContentTypeEnum.JSON,
  49. Accept: 'application/json, text/plain, */*',
  50. ...method.config.headers,
  51. }
  52. const { config } = method
  53. const ignoreAuth = !config.meta?.ignoreAuth
  54. console.log('ignoreAuth===>', ignoreAuth)
  55. // 处理认证信息 自行处理认证问题
  56. if (ignoreAuth) {
  57. const token = 'getToken()'
  58. if (!token) {
  59. throw new Error('[请求错误]:未登录')
  60. }
  61. // method.config.headers.token = token;
  62. }
  63. // 处理动态域名
  64. if (config.meta?.domain) {
  65. method.baseURL = config.meta.domain
  66. console.log('当前域名', method.baseURL)
  67. }
  68. }),
  69. responded: onResponseRefreshToken((response, method) => {
  70. const { config } = method
  71. const { requestType } = config
  72. const {
  73. statusCode,
  74. data: rawData,
  75. errMsg,
  76. } = response as UniNamespace.RequestSuccessCallbackResult
  77. // 处理特殊请求类型(上传/下载)
  78. if (requestType === 'upload' || requestType === 'download') {
  79. return response
  80. }
  81. // 处理 HTTP 状态码错误
  82. if (statusCode !== 200) {
  83. const errorMessage = ShowMessage(statusCode) || `HTTP请求错误[${statusCode}]`
  84. console.error('errorMessage===>', errorMessage)
  85. toast.error(errorMessage)
  86. throw new Error(`${errorMessage}:${errMsg}`)
  87. }
  88. // 处理业务逻辑错误
  89. const { code, message, data } = rawData as IResponse
  90. if (code !== ResultEnum.Success) {
  91. if (config.meta?.toast !== false) {
  92. toast.warning(message)
  93. }
  94. throw new Error(`请求错误[${code}]:${message}`)
  95. }
  96. // 处理成功响应,返回业务数据
  97. return data
  98. }),
  99. })
  100. export const http = alovaInstance