浏览代码

perf: easy to define fieldName of response data (#5442)

Netfan 2 月之前
父节点
当前提交
22e6f28464

+ 10 - 0
apps/web-antd/src/api/request.ts

@@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
 import { preferences } from '@vben/preferences';
 import {
   authenticateResponseInterceptor,
+  defaultResponseInterceptor,
   errorMessageResponseInterceptor,
   RequestClient,
 } from '@vben/request';
@@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
     },
   });
 
+  // 处理返回的响应数据格式
+  client.addResponseInterceptor(
+    defaultResponseInterceptor({
+      codeField: 'code',
+      dataField: 'data',
+      successCode: 0,
+    }),
+  );
+
   // token过期的处理
   client.addResponseInterceptor(
     authenticateResponseInterceptor({

+ 10 - 0
apps/web-ele/src/api/request.ts

@@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
 import { preferences } from '@vben/preferences';
 import {
   authenticateResponseInterceptor,
+  defaultResponseInterceptor,
   errorMessageResponseInterceptor,
   RequestClient,
 } from '@vben/request';
@@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
     },
   });
 
+  // 处理返回的响应数据格式
+  client.addResponseInterceptor(
+    defaultResponseInterceptor({
+      codeField: 'code',
+      dataField: 'data',
+      successCode: 0,
+    }),
+  );
+
   // token过期的处理
   client.addResponseInterceptor(
     authenticateResponseInterceptor({

+ 10 - 0
apps/web-naive/src/api/request.ts

@@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
 import { preferences } from '@vben/preferences';
 import {
   authenticateResponseInterceptor,
+  defaultResponseInterceptor,
   errorMessageResponseInterceptor,
   RequestClient,
 } from '@vben/request';
@@ -69,6 +70,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
     },
   });
 
+  // 处理返回的响应数据格式
+  client.addResponseInterceptor(
+    defaultResponseInterceptor({
+      codeField: 'code',
+      dataField: 'data',
+      successCode: 0,
+    }),
+  );
+
   // token过期的处理
   client.addResponseInterceptor(
     authenticateResponseInterceptor({

+ 39 - 0
packages/effects/request/src/request-client/preset-interceptors.ts

@@ -2,9 +2,48 @@ import type { RequestClient } from './request-client';
 import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types';
 
 import { $t } from '@vben/locales';
+import { isFunction } from '@vben/utils';
 
 import axios from 'axios';
 
+export const defaultResponseInterceptor = ({
+  codeField = 'code',
+  dataField = 'data',
+  successCode = 0,
+}: {
+  /** 响应数据中代表访问结果的字段名 */
+  codeField: string;
+  /** 响应数据中装载实际数据的字段名,或者提供一个函数从响应数据中解析需要返回的数据 */
+  dataField: ((response: any) => any) | string;
+  /** 当codeField所指定的字段值与successCode相同时,代表接口访问成功。如果提供一个函数,则返回true代表接口访问成功 */
+  successCode: ((code: any) => boolean) | number | string;
+}): ResponseInterceptorConfig => {
+  return {
+    fulfilled: (response) => {
+      const { config, data: responseData, status } = response;
+
+      if (config.responseReturn === 'raw') {
+        return response;
+      }
+      const code = responseData[codeField];
+      if (
+        status >= 200 && status < 400 && isFunction(successCode)
+          ? successCode(code)
+          : code === successCode
+      ) {
+        if (config.responseReturn === 'body') {
+          return responseData;
+        } else {
+          return isFunction(dataField)
+            ? dataField(responseData)
+            : responseData[dataField];
+        }
+      }
+      throw Object.assign({}, response, { response });
+    },
+  };
+};
+
 export const authenticateResponseInterceptor = ({
   client,
   doReAuthenticate,

+ 0 - 23
packages/effects/request/src/request-client/request-client.test.ts

@@ -48,29 +48,6 @@ describe('requestClient', () => {
     expect(response.data).toEqual(mockData);
   });
 
-  it('should return different response types', async () => {
-    const mockData = { code: 0, msg: 'ok', data: 'response' };
-    mock.onGet('/test/diff').reply(200, mockData);
-
-    const responseRaw = await requestClient.get('/test/diff', {
-      responseReturn: 'raw',
-    });
-    expect(responseRaw.status).toBe(200);
-    expect(responseRaw.data).toEqual(mockData);
-
-    const responseBody = await requestClient.get('/test/diff', {
-      responseReturn: 'body',
-    });
-    expect(responseBody.code).toEqual(mockData.code);
-    expect(responseBody.msg).toEqual(mockData.msg);
-    expect(responseBody.data).toEqual(mockData.data);
-
-    const responseData = await requestClient.get('/test/diff', {
-      responseReturn: 'data',
-    });
-    expect(responseData).toEqual(mockData.data);
-  });
-
   it('should handle network errors', async () => {
     mock.onGet('/test/error').networkError();
     try {

+ 1 - 23
packages/effects/request/src/request-client/request-client.ts

@@ -1,10 +1,6 @@
 import type { AxiosInstance, AxiosResponse } from 'axios';
 
-import type {
-  HttpResponse,
-  RequestClientConfig,
-  RequestClientOptions,
-} from './types';
+import type { RequestClientConfig, RequestClientOptions } from './types';
 
 import { bindMethods, merge } from '@vben/utils';
 
@@ -54,24 +50,6 @@ class RequestClient {
     this.addResponseInterceptor =
       interceptorManager.addResponseInterceptor.bind(interceptorManager);
 
-    // 添加基础的响应处理,根据设置决定返回响应的哪一部分
-    this.addResponseInterceptor<HttpResponse>({
-      fulfilled: (response) => {
-        const { config, data: responseData, status } = response;
-
-        if (config.responseReturn === 'raw') {
-          return response;
-        }
-
-        const { code, data } = responseData;
-
-        if (status >= 200 && status < 400 && code === 0) {
-          return config.responseReturn === 'body' ? responseData : data;
-        }
-        throw Object.assign({}, response, { response });
-      },
-    });
-
     // 实例化文件上传器
     const fileUploader = new FileUploader(this);
     this.upload = fileUploader.upload.bind(fileUploader);

+ 10 - 0
playground/src/api/request.ts

@@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
 import { preferences } from '@vben/preferences';
 import {
   authenticateResponseInterceptor,
+  defaultResponseInterceptor,
   errorMessageResponseInterceptor,
   RequestClient,
 } from '@vben/request';
@@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
     },
   });
 
+  // 处理返回的响应数据格式
+  client.addResponseInterceptor(
+    defaultResponseInterceptor({
+      codeField: 'code',
+      dataField: 'data',
+      successCode: 0,
+    }),
+  );
+
   // token过期的处理
   client.addResponseInterceptor(
     authenticateResponseInterceptor({