From 136cbb1e3bc056c88cfa21fca612d3ab72b4d119 Mon Sep 17 00:00:00 2001
From: Captain <49203535+MssText@users.noreply.github.com>
Date: 星期六, 19 三月 2022 00:07:34 +0800
Subject: [PATCH] feat: add request retry (#1553)

---
 src/utils/http/axios/index.ts |   57 +++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/src/utils/http/axios/index.ts b/src/utils/http/axios/index.ts
index f204185..8c5c00e 100644
--- a/src/utils/http/axios/index.ts
+++ b/src/utils/http/axios/index.ts
@@ -2,6 +2,7 @@
 // The axios configuration can be changed according to the project, just change the file, other files can be left unchanged
 
 import type { AxiosResponse } from 'axios';
+import { clone } from 'lodash-es';
 import type { RequestOptions, Result } from '/#/axios';
 import type { AxiosTransform, CreateAxiosOptions } from './axiosTransform';
 import { VAxios } from './Axios';
@@ -15,6 +16,8 @@
 import { useErrorLogStoreWithOut } from '/@/store/modules/errorLog';
 import { useI18n } from '/@/hooks/web/useI18n';
 import { joinTimestamp, formatRequestDate } from './helper';
+import { useUserStoreWithOut } from '/@/store/modules/user';
+import { AxiosRetry } from '/@/utils/http/axios/axiosRetry';
 
 const globSetting = useGlobSetting();
 const urlPrefix = globSetting.urlPrefix;
@@ -61,6 +64,10 @@
     switch (code) {
       case ResultEnum.TIMEOUT:
         timeoutMsg = t('sys.api.timeoutMessage');
+        const userStore = useUserStoreWithOut();
+        userStore.setToken(undefined);
+        userStore.logout(true);
+        break;
       default:
         if (message) {
           timeoutMsg = message;
@@ -80,7 +87,7 @@
 
   // 璇锋眰涔嬪墠澶勭悊config
   beforeRequestHook: (config, options) => {
-    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true } = options;
+    const { apiUrl, joinPrefix, joinParamsToUrl, formatDate, joinTime = true, urlPrefix } = options;
 
     if (joinPrefix) {
       config.url = `${urlPrefix}${config.url}`;
@@ -90,6 +97,8 @@
       config.url = `${apiUrl}${config.url}`;
     }
     const params = config.params || {};
+    const data = config.data || false;
+    formatDate && data && !isString(data) && formatRequestDate(data);
     if (config.method?.toUpperCase() === RequestEnum.GET) {
       if (!isString(params)) {
         // 缁� get 璇锋眰鍔犱笂鏃堕棿鎴冲弬鏁帮紝閬垮厤浠庣紦瀛樹腑鎷挎暟鎹��
@@ -102,10 +111,19 @@
     } else {
       if (!isString(params)) {
         formatDate && formatRequestDate(params);
-        config.data = params;
-        config.params = undefined;
+        if (Reflect.has(config, 'data') && config.data && Object.keys(config.data).length > 0) {
+          config.data = data;
+          config.params = params;
+        } else {
+          // 闈濭ET璇锋眰濡傛灉娌℃湁鎻愪緵data锛屽垯灏唒arams瑙嗕负data
+          config.data = params;
+          config.params = undefined;
+        }
         if (joinParamsToUrl) {
-          config.url = setObjToUrlParams(config.url as string, config.data);
+          config.url = setObjToUrlParams(
+            config.url as string,
+            Object.assign({}, config.params, config.data),
+          );
         }
       } else {
         // 鍏煎restful椋庢牸
@@ -124,7 +142,7 @@
     const token = getToken();
     if (token && (config as Recordable)?.requestOptions?.withToken !== false) {
       // jwt token
-      config.headers.Authorization = options.authenticationScheme
+      (config as Recordable).headers.Authorization = options.authenticationScheme
         ? `${options.authenticationScheme} ${token}`
         : token;
     }
@@ -141,7 +159,7 @@
   /**
    * @description: 鍝嶅簲閿欒澶勭悊
    */
-  responseInterceptorsCatch: (error: any) => {
+  responseInterceptorsCatch: (axiosInstance: AxiosResponse, error: any) => {
     const { t } = useI18n();
     const errorLogStore = useErrorLogStoreWithOut();
     errorLogStore.addAjaxErrorInfo(error);
@@ -168,10 +186,18 @@
         return Promise.reject(error);
       }
     } catch (error) {
-      throw new Error(error);
+      throw new Error(error as unknown as string);
     }
 
     checkStatus(error?.response?.status, msg, errorMessageMode);
+
+    // 娣诲姞鑷姩閲嶈瘯鏈哄埗 淇濋櫓璧疯 鍙拡瀵笹ET璇锋眰
+    const retryRequest = new AxiosRetry();
+    const { isOpenRetry } = config.requestOptions.retryRequest;
+    config.method?.toUpperCase() === RequestEnum.GET &&
+      isOpenRetry &&
+      // @ts-ignore
+      retryRequest.retry(axiosInstance, error);
     return Promise.reject(error);
   },
 };
@@ -187,13 +213,12 @@
         timeout: 10 * 1000,
         // 鍩虹鎺ュ彛鍦板潃
         // baseURL: globSetting.apiUrl,
-        // 鎺ュ彛鍙兘浼氭湁閫氱敤鐨勫湴鍧�閮ㄥ垎锛屽彲浠ョ粺涓�鎶藉彇鍑烘潵
-        urlPrefix: urlPrefix,
+
         headers: { 'Content-Type': ContentTypeEnum.JSON },
         // 濡傛灉鏄痜orm-data鏍煎紡
         // headers: { 'Content-Type': ContentTypeEnum.FORM_URLENCODED },
         // 鏁版嵁澶勭悊鏂瑰紡
-        transform,
+        transform: clone(transform),
         // 閰嶇疆椤癸紝涓嬮潰鐨勯�夐」閮藉彲浠ュ湪鐙珛鐨勬帴鍙h姹備腑瑕嗙洊
         requestOptions: {
           // 榛樿灏唒refix 娣诲姞鍒皍rl
@@ -210,16 +235,23 @@
           errorMessageMode: 'message',
           // 鎺ュ彛鍦板潃
           apiUrl: globSetting.apiUrl,
+          // 鎺ュ彛鎷兼帴鍦板潃
+          urlPrefix: urlPrefix,
           //  鏄惁鍔犲叆鏃堕棿鎴�
           joinTime: true,
           // 蹇界暐閲嶅璇锋眰
           ignoreCancelToken: true,
           // 鏄惁鎼哄甫token
           withToken: true,
+          retryRequest: {
+            isOpenRetry: true,
+            count: 5,
+            waitTime: 100,
+          },
         },
       },
-      opt || {}
-    )
+      opt || {},
+    ),
   );
 }
 export const defHttp = createAxios();
@@ -228,5 +260,6 @@
 // export const otherHttp = createAxios({
 //   requestOptions: {
 //     apiUrl: 'xxx',
+//     urlPrefix: 'xxx',
 //   },
 // });

--
Gitblit v1.8.0