request.ts 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  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 { message } from '#/naive';
  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 (preferences.app.loginExpiredMode === 'modal') {
  29. accessStore.setLoginExpired(true);
  30. } else {
  31. await authStore.logout();
  32. }
  33. }
  34. /**
  35. * 刷新token逻辑
  36. */
  37. async function doRefreshToken() {
  38. const accessStore = useAccessStore();
  39. const resp = await refreshTokenApi();
  40. const newToken = resp.data;
  41. accessStore.setAccessToken(newToken);
  42. return newToken;
  43. }
  44. function formatToken(token: null | string) {
  45. return token ? `Bearer ${token}` : null;
  46. }
  47. // 请求头处理
  48. client.addRequestInterceptor({
  49. fulfilled: async (config) => {
  50. const accessStore = useAccessStore();
  51. config.headers.Authorization = formatToken(accessStore.accessToken);
  52. config.headers['Accept-Language'] = preferences.app.locale;
  53. return config;
  54. },
  55. });
  56. // response数据解构
  57. client.addResponseInterceptor({
  58. fulfilled: (response) => {
  59. const { data: responseData, status } = response;
  60. const { code, data, message: msg } = responseData;
  61. if (status >= 200 && status < 400 && code === 0) {
  62. return data;
  63. }
  64. throw new Error(`Error ${status}: ${msg}`);
  65. },
  66. });
  67. // token过期的处理
  68. client.addResponseInterceptor(
  69. authenticateResponseInterceptor({
  70. client,
  71. doReAuthenticate,
  72. doRefreshToken,
  73. enableRefreshToken: preferences.app.enableRefreshToken,
  74. formatToken,
  75. }),
  76. );
  77. // 通用的错误处理,如果没有进入上面的错误处理逻辑,就会进入这里
  78. client.addResponseInterceptor(
  79. errorMessageResponseInterceptor((msg: string) => message.error(msg)),
  80. );
  81. return client;
  82. }
  83. export const requestClient = createRequestClient(apiURL);
  84. export const baseRequestClient = new RequestClient({ baseURL: apiURL });