perf: easy to define fieldName of response data (#5442)
This commit is contained in:
parent
5611f6c7f5
commit
22e6f28464
@ -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({
|
||||
|
@ -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({
|
||||
|
@ -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({
|
||||
|
@ -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,
|
||||
|
@ -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,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);
|
||||
|
@ -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({
|
||||
|
Loading…
Reference in New Issue
Block a user