diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts index 49429d4971f..288dddd09db 100644 --- a/apps/web-antd/src/api/request.ts +++ b/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({ diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts index 21223a4bca3..203b35bf704 100644 --- a/apps/web-ele/src/api/request.ts +++ b/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({ diff --git a/apps/web-naive/src/api/request.ts b/apps/web-naive/src/api/request.ts index b09c3396027..f8fbacc0bc5 100644 --- a/apps/web-naive/src/api/request.ts +++ b/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({ diff --git a/packages/effects/request/src/request-client/preset-interceptors.ts b/packages/effects/request/src/request-client/preset-interceptors.ts index 2049eeaa1fd..4f327dd0412 100644 --- a/packages/effects/request/src/request-client/preset-interceptors.ts +++ b/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, diff --git a/packages/effects/request/src/request-client/request-client.test.ts b/packages/effects/request/src/request-client/request-client.test.ts index fa7b9a86d92..2d94525e252 100644 --- a/packages/effects/request/src/request-client/request-client.test.ts +++ b/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 { diff --git a/packages/effects/request/src/request-client/request-client.ts b/packages/effects/request/src/request-client/request-client.ts index 6a4630c0e80..56412dd8495 100644 --- a/packages/effects/request/src/request-client/request-client.ts +++ b/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({ - 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); diff --git a/playground/src/api/request.ts b/playground/src/api/request.ts index 49429d4971f..288dddd09db 100644 --- a/playground/src/api/request.ts +++ b/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({