request.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * axios 实例(乾坤行为对齐 EOM:成功响应不回调门户 fetchNew)
  3. *
  4. * 说明:此前每次接口成功都调 parentWindow.fetchNew,
  5. * 进入 HR 后拉资源树会触发门户重新初始化菜单,侧栏闪一下又回到第一个系统。
  6. * EOM 无此逻辑,故去掉成功路径的 notifyParent。
  7. */
  8. import axios from 'axios';
  9. import JSONBIG from 'json-bigint';
  10. import { MessageBox } from 'element-ui';
  11. import { API_BASE_URL, TOKEN_HEADER_NAME } from '@/config/setting';
  12. import { getRouter, resetRouter } from '@/router';
  13. import { getToken, refreshToken, removeToken } from '@/utils/token-util';
  14. let loginExpiredDialogVisible = false;
  15. /** 跳转登录页,独立运行和 qiankun 嵌入运行分别处理。 */
  16. function redirectToLogin(from) {
  17. const isHome =
  18. !from || from === '/' || from === '/home' || from === '/home/index';
  19. removeToken();
  20. try {
  21. const store = require('@/store').default;
  22. store.commit('user/setMenus', null);
  23. store.commit('user/setAuthoritiesRouter', []);
  24. } catch (e) {
  25. /* ignore */
  26. }
  27. try {
  28. resetRouter();
  29. } catch (e) {
  30. /* ignore */
  31. }
  32. if (window.__POWERED_BY_QIANKUN__) {
  33. const query = isHome ? '' : `?from=${encodeURIComponent(from)}`;
  34. window.location.replace(`${window.location.origin}/login${query}`);
  35. return;
  36. }
  37. const router = getRouter();
  38. if (router?.currentRoute?.path !== '/login') {
  39. router
  40. .replace({
  41. path: '/login',
  42. query: isHome ? {} : { from },
  43. })
  44. .catch(() => {});
  45. }
  46. }
  47. function handleLoginExpired() {
  48. removeToken();
  49. if (loginExpiredDialogVisible) {
  50. return;
  51. }
  52. loginExpiredDialogVisible = true;
  53. const router = getRouter();
  54. const currentPath =
  55. router?.currentRoute?.fullPath || window.location.pathname;
  56. MessageBox.alert('登录状态已过期,请退出后重新登录', '系统提示', {
  57. confirmButtonText: '重新登录',
  58. closeOnClickModal: false,
  59. closeOnPressEscape: false,
  60. showClose: false,
  61. })
  62. .then(() => redirectToLogin(currentPath))
  63. .catch(() => redirectToLogin(currentPath))
  64. .finally(() => {
  65. loginExpiredDialogVisible = false;
  66. });
  67. }
  68. const request = axios.create({
  69. baseURL: API_BASE_URL,
  70. timeout: 30000,
  71. transformResponse: [
  72. (data) => {
  73. if (data instanceof Blob || typeof data !== 'string' || !data) {
  74. return data;
  75. }
  76. try {
  77. return JSONBIG({ storeAsString: true }).parse(data);
  78. } catch (error) {
  79. return data;
  80. }
  81. },
  82. ],
  83. });
  84. request.interceptors.request.use(
  85. (config) => {
  86. const token = getToken();
  87. if (token) {
  88. config.headers = config.headers || {};
  89. config.headers[TOKEN_HEADER_NAME] = token;
  90. }
  91. return config;
  92. },
  93. (error) => Promise.reject(error),
  94. );
  95. request.interceptors.response.use(
  96. (response) => {
  97. // 与 EOM 一致:不在成功响应里回调门户 fetchNew
  98. const token = response.headers?.[TOKEN_HEADER_NAME.toLowerCase()];
  99. if (token) {
  100. refreshToken(token);
  101. }
  102. return response;
  103. },
  104. (error) => {
  105. if (error.response?.status === 401) {
  106. handleLoginExpired();
  107. return Promise.reject(error);
  108. }
  109. const message =
  110. error.response?.data?.message ||
  111. (error.response?.status
  112. ? `服务调用失败(${error.response.status})`
  113. : '服务调用失败,请联系管理员!');
  114. error.message = message;
  115. return Promise.reject(error);
  116. },
  117. );
  118. export default request;