request.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /**
  2. * 该文件可自行根据业务逻辑进行调整
  3. */
  4. import { useAppConfig } from '@vben/hooks';
  5. import { preferences } from '@vben/preferences';
  6. import {
  7. authenticateResponseInterceptor,
  8. errorMessageResponseInterceptor,
  9. RequestClient,
  10. } from '@vben/request';
  11. import { useAccessStore } from '@vben/stores';
  12. import { ElMessage } from 'element-plus';
  13. import { useAuthStore } from '#/store';
  14. import { refreshTokenApi } from './core';
  15. const { apiURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
  16. function createRequestClient(baseURL: string) {
  17. const client = new RequestClient({
  18. baseURL,
  19. });
  20. /**
  21. * 重新认证逻辑
  22. */
  23. async function doReAuthenticate() {
  24. console.warn('Access token or refresh token is invalid or expired. ');
  25. const accessStore = useAccessStore();
  26. const authStore = useAuthStore();
  27. accessStore.setAccessToken(null);
  28. if (
  29. preferences.app.loginExpiredMode === 'modal' &&
  30. accessStore.isAccessChecked
  31. ) {
  32. accessStore.setLoginExpired(true);
  33. } else {
  34. await authStore.logout();
  35. }
  36. }
  37. /**
  38. * 刷新token逻辑
  39. */
  40. async function doRefreshToken() {
  41. const accessStore = useAccessStore();
  42. const resp = await refreshTokenApi();
  43. const newToken = resp.data;
  44. accessStore.setAccessToken(newToken);
  45. return newToken;
  46. }
  47. function formatToken(token: null | string) {
  48. return token ? `Bearer ${token}` : null;
  49. }
  50. // 请求头处理
  51. client.addRequestInterceptor({
  52. fulfilled: async (config) => {
  53. const accessStore = useAccessStore();
  54. config.headers.Authorization = formatToken(accessStore.accessToken);
  55. config.headers['Accept-Language'] = preferences.app.locale;
  56. return config;
  57. },
  58. });
  59. // response数据解构
  60. client.addResponseInterceptor({
  61. fulfilled: (response) => {
  62. const { data: responseData, status } = response;
  63. const { code, data, message: msg } = responseData;
  64. if (status >= 200 && status < 400 && code === 0) {
  65. return data;
  66. }
  67. throw new Error(`Error ${status}: ${msg}`);
  68. },
  69. });
  70. // token过期的处理
  71. client.addResponseInterceptor(
  72. authenticateResponseInterceptor({
  73. client,
  74. doReAuthenticate,
  75. doRefreshToken,
  76. enableRefreshToken: preferences.app.enableRefreshToken,
  77. formatToken,
  78. }),
  79. );
  80. // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
  81. client.addResponseInterceptor(
  82. errorMessageResponseInterceptor((msg: string) => ElMessage.error(msg)),
  83. );
  84. return client;
  85. }
  86. export const requestClient = createRequestClient(apiURL);
  87. export const baseRequestClient = new RequestClient({ baseURL: apiURL });