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 { preferences } from '@vben/preferences';
|
||||||
import {
|
import {
|
||||||
authenticateResponseInterceptor,
|
authenticateResponseInterceptor,
|
||||||
|
defaultResponseInterceptor,
|
||||||
errorMessageResponseInterceptor,
|
errorMessageResponseInterceptor,
|
||||||
RequestClient,
|
RequestClient,
|
||||||
} from '@vben/request';
|
} from '@vben/request';
|
||||||
@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理返回的响应数据格式
|
||||||
|
client.addResponseInterceptor(
|
||||||
|
defaultResponseInterceptor({
|
||||||
|
codeField: 'code',
|
||||||
|
dataField: 'data',
|
||||||
|
successCode: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// token过期的处理
|
// token过期的处理
|
||||||
client.addResponseInterceptor(
|
client.addResponseInterceptor(
|
||||||
authenticateResponseInterceptor({
|
authenticateResponseInterceptor({
|
||||||
|
@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
|
|||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import {
|
import {
|
||||||
authenticateResponseInterceptor,
|
authenticateResponseInterceptor,
|
||||||
|
defaultResponseInterceptor,
|
||||||
errorMessageResponseInterceptor,
|
errorMessageResponseInterceptor,
|
||||||
RequestClient,
|
RequestClient,
|
||||||
} from '@vben/request';
|
} from '@vben/request';
|
||||||
@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理返回的响应数据格式
|
||||||
|
client.addResponseInterceptor(
|
||||||
|
defaultResponseInterceptor({
|
||||||
|
codeField: 'code',
|
||||||
|
dataField: 'data',
|
||||||
|
successCode: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// token过期的处理
|
// token过期的处理
|
||||||
client.addResponseInterceptor(
|
client.addResponseInterceptor(
|
||||||
authenticateResponseInterceptor({
|
authenticateResponseInterceptor({
|
||||||
|
@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
|
|||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import {
|
import {
|
||||||
authenticateResponseInterceptor,
|
authenticateResponseInterceptor,
|
||||||
|
defaultResponseInterceptor,
|
||||||
errorMessageResponseInterceptor,
|
errorMessageResponseInterceptor,
|
||||||
RequestClient,
|
RequestClient,
|
||||||
} from '@vben/request';
|
} from '@vben/request';
|
||||||
@ -69,6 +70,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理返回的响应数据格式
|
||||||
|
client.addResponseInterceptor(
|
||||||
|
defaultResponseInterceptor({
|
||||||
|
codeField: 'code',
|
||||||
|
dataField: 'data',
|
||||||
|
successCode: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// token过期的处理
|
// token过期的处理
|
||||||
client.addResponseInterceptor(
|
client.addResponseInterceptor(
|
||||||
authenticateResponseInterceptor({
|
authenticateResponseInterceptor({
|
||||||
|
@ -2,9 +2,48 @@ import type { RequestClient } from './request-client';
|
|||||||
import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types';
|
import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types';
|
||||||
|
|
||||||
import { $t } from '@vben/locales';
|
import { $t } from '@vben/locales';
|
||||||
|
import { isFunction } from '@vben/utils';
|
||||||
|
|
||||||
import axios from 'axios';
|
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 = ({
|
export const authenticateResponseInterceptor = ({
|
||||||
client,
|
client,
|
||||||
doReAuthenticate,
|
doReAuthenticate,
|
||||||
|
@ -48,29 +48,6 @@ describe('requestClient', () => {
|
|||||||
expect(response.data).toEqual(mockData);
|
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 () => {
|
it('should handle network errors', async () => {
|
||||||
mock.onGet('/test/error').networkError();
|
mock.onGet('/test/error').networkError();
|
||||||
try {
|
try {
|
||||||
|
@ -1,10 +1,6 @@
|
|||||||
import type { AxiosInstance, AxiosResponse } from 'axios';
|
import type { AxiosInstance, AxiosResponse } from 'axios';
|
||||||
|
|
||||||
import type {
|
import type { RequestClientConfig, RequestClientOptions } from './types';
|
||||||
HttpResponse,
|
|
||||||
RequestClientConfig,
|
|
||||||
RequestClientOptions,
|
|
||||||
} from './types';
|
|
||||||
|
|
||||||
import { bindMethods, merge } from '@vben/utils';
|
import { bindMethods, merge } from '@vben/utils';
|
||||||
|
|
||||||
@ -54,24 +50,6 @@ class RequestClient {
|
|||||||
this.addResponseInterceptor =
|
this.addResponseInterceptor =
|
||||||
interceptorManager.addResponseInterceptor.bind(interceptorManager);
|
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);
|
const fileUploader = new FileUploader(this);
|
||||||
this.upload = fileUploader.upload.bind(fileUploader);
|
this.upload = fileUploader.upload.bind(fileUploader);
|
||||||
|
@ -7,6 +7,7 @@ import { useAppConfig } from '@vben/hooks';
|
|||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import {
|
import {
|
||||||
authenticateResponseInterceptor,
|
authenticateResponseInterceptor,
|
||||||
|
defaultResponseInterceptor,
|
||||||
errorMessageResponseInterceptor,
|
errorMessageResponseInterceptor,
|
||||||
RequestClient,
|
RequestClient,
|
||||||
} from '@vben/request';
|
} from '@vben/request';
|
||||||
@ -70,6 +71,15 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 处理返回的响应数据格式
|
||||||
|
client.addResponseInterceptor(
|
||||||
|
defaultResponseInterceptor({
|
||||||
|
codeField: 'code',
|
||||||
|
dataField: 'data',
|
||||||
|
successCode: 0,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
// token过期的处理
|
// token过期的处理
|
||||||
client.addResponseInterceptor(
|
client.addResponseInterceptor(
|
||||||
authenticateResponseInterceptor({
|
authenticateResponseInterceptor({
|
||||||
|
Loading…
Reference in New Issue
Block a user