Browse Source

feat(request): 提取统一响应参数与返回状态码枚举

pull/8337/head
雪忆天堂 4 weeks ago
parent
commit
1def9d3f15
  1. 11
      apps/web-antd/src/api/request.ts
  2. 11
      apps/web-antdv-next/src/api/request.ts
  3. 11
      apps/web-ele/src/api/request.ts
  4. 11
      apps/web-naive/src/api/request.ts
  5. 11
      apps/web-tdesign/src/api/request.ts
  6. 3
      docs/src/en/guide/essentials/server.md
  7. 3
      docs/src/guide/essentials/server.md
  8. 61
      packages/constants/src/http.enum.ts
  9. 1
      packages/constants/src/index.ts
  10. 1
      packages/effects/request/package.json
  11. 40
      packages/effects/request/src/request-client/preset-interceptors.ts
  12. 11
      playground/src/api/request.ts
  13. 3
      pnpm-lock.yaml

11
apps/web-antd/src/api/request.ts

@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

11
apps/web-antdv-next/src/api/request.ts

@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

11
apps/web-ele/src/api/request.ts

@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
ElMessage.error(errorMessage || msg); ElMessage.error(errorMessage || msg);
}), }),

11
apps/web-naive/src/api/request.ts

@ -71,13 +71,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -96,7 +90,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

11
apps/web-tdesign/src/api/request.ts

@ -71,13 +71,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -96,7 +90,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

3
docs/src/en/guide/essentials/server.md

@ -261,7 +261,8 @@ function createRequestClient(baseURL: string) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

3
docs/src/guide/essentials/server.md

@ -292,7 +292,8 @@ function createRequestClient(baseURL: string) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

61
packages/constants/src/http.enum.ts

@ -0,0 +1,61 @@
/** 返回状态码 */
export enum HttpResultEnum {
// 操作成功
SUCCESS = 0,
// 对象创建成功
CREATED = 201,
// 请求已经被接受
ACCEPTED = 202,
// 操作已经执行成功,但是没有返回数据
NO_CONTENT = 204,
// 资源已被移除
MOVED_PERM = 301,
// 重定向
SEE_OTHER = 303,
// 资源没有被修改
NOT_MODIFIED = 304,
// 参数列表错误(缺少,格式不匹配)
BAD_REQUEST = 400,
// 未授权
UNAUTHORIZED = 401,
// 访问受限,授权过期
FORBIDDEN = 403,
// 资源,服务未找到
NOT_FOUND = 404,
// 不允许的http方法
BAD_METHOD = 405,
// 请求超时
REQUEST_TIMEOUT = 408,
// 资源冲突,或者资源被锁
CONFLICT = 409,
// 不支持的数据,媒体类型
UNSUPPORTED_TYPE = 415,
// 系统内部错误
ERROR = 500,
// 接口未实现
NOT_IMPLEMENTED = 501,
// 系统警告消息
WARN = 601,
}
/**
* @description: request method
*/
export enum RequestEnum {
GET = 'GET',
POST = 'POST',
PUT = 'PUT',
DELETE = 'DELETE',
}
/**
* @description: contentType
*/
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',
// form-data qs
FORM_URLENCODED = 'application/x-www-form-urlencoded;charset=UTF-8',
// form-data upload
FORM_DATA = 'multipart/form-data;charset=UTF-8',
}

1
packages/constants/src/index.ts

@ -1,2 +1,3 @@
export * from './core'; export * from './core';
export * from './http.enum';
export * from '@vben-core/shared/constants'; export * from '@vben-core/shared/constants';

1
packages/effects/request/package.json

@ -20,6 +20,7 @@
} }
}, },
"dependencies": { "dependencies": {
"@vben/constants": "workspace:*",
"@vben/locales": "workspace:*", "@vben/locales": "workspace:*",
"@vben/utils": "workspace:*", "@vben/utils": "workspace:*",
"axios": "catalog:", "axios": "catalog:",

40
packages/effects/request/src/request-client/preset-interceptors.ts

@ -1,6 +1,7 @@
import type { RequestClient } from './request-client'; import type { RequestClient } from './request-client';
import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types'; import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types';
import { HttpResultEnum } from '@vben/constants';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { isFunction } from '@vben/utils'; import { isFunction } from '@vben/utils';
@ -9,15 +10,25 @@ import axios from 'axios';
export const defaultResponseInterceptor = ({ export const defaultResponseInterceptor = ({
codeField = 'code', codeField = 'code',
dataField = 'data', dataField = 'data',
successCode = 0, successCode = HttpResultEnum.SUCCESS,
}: { }: {
/** 响应数据中代表访问结果的字段名 */ /** 响应数据中代表访问结果的字段名 */
codeField: string; codeField?: string;
/** 响应数据中装载实际数据的字段名,或者提供一个函数从响应数据中解析需要返回的数据 */ /** 响应数据中装载实际数据的字段名,或者提供一个函数从响应数据中解析需要返回的数据 */
dataField: ((response: any) => any) | string; dataField?: ((response: any) => any) | string;
/** 当codeField所指定的字段值与successCode相同时,代表接口访问成功。如果提供一个函数,则返回true代表接口访问成功 */ /** 当codeField所指定的字段值与successCode相同时,代表接口访问成功。如果提供一个函数,则返回true代表接口访问成功 */
successCode: ((code: any) => boolean) | number | string; successCode?: ((code: any) => boolean) | number | string;
}): ResponseInterceptorConfig => { }): ResponseInterceptorConfig => {
// 初始化字段
if (!codeField) {
codeField = 'code';
}
if (!dataField) {
dataField = 'data';
}
if (!successCode) {
successCode = HttpResultEnum.SUCCESS;
}
return { return {
fulfilled: (response) => { fulfilled: (response) => {
const { config, data: responseData, status } = response; const { config, data: responseData, status } = response;
@ -61,7 +72,8 @@ export const authenticateResponseInterceptor = ({
rejected: async (error) => { rejected: async (error) => {
const { config, response } = error; const { config, response } = error;
// 如果不是 401 错误,直接抛出异常 // 如果不是 401 错误,直接抛出异常
if (response?.status !== 401) { const status = response?.data?.code || response?.status;
if (status !== HttpResultEnum.UNAUTHORIZED) {
throw error; throw error;
} }
// 判断是否启用了 refreshToken 功能 // 判断是否启用了 refreshToken 功能
@ -131,29 +143,29 @@ export const errorMessageResponseInterceptor = (
} }
let errorMessage: string; let errorMessage: string;
const status = error?.response?.status; const status = error?.response?.data?.code || error?.response?.status;
switch (status) { switch (status) {
case 400: { case HttpResultEnum.REQUEST_TIMEOUT: {
errorMessage = $t('ui.fallback.http.requestTimeout');
break;
}
case HttpResultEnum.BAD_REQUEST: {
errorMessage = $t('ui.fallback.http.badRequest'); errorMessage = $t('ui.fallback.http.badRequest');
break; break;
} }
case 401: { case HttpResultEnum.UNAUTHORIZED: {
errorMessage = $t('ui.fallback.http.unauthorized'); errorMessage = $t('ui.fallback.http.unauthorized');
break; break;
} }
case 403: { case HttpResultEnum.FORBIDDEN: {
errorMessage = $t('ui.fallback.http.forbidden'); errorMessage = $t('ui.fallback.http.forbidden');
break; break;
} }
case 404: { case HttpResultEnum.NOT_FOUND: {
errorMessage = $t('ui.fallback.http.notFound'); errorMessage = $t('ui.fallback.http.notFound');
break; break;
} }
case 408: {
errorMessage = $t('ui.fallback.http.requestTimeout');
break;
}
default: { default: {
errorMessage = $t('ui.fallback.http.internalServerError'); errorMessage = $t('ui.fallback.http.internalServerError');
} }

11
playground/src/api/request.ts

@ -86,13 +86,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
}); });
// 处理返回的响应数据格式 // 处理返回的响应数据格式
client.addResponseInterceptor( client.addResponseInterceptor(defaultResponseInterceptor({}));
defaultResponseInterceptor({
codeField: 'code',
dataField: 'data',
successCode: 0,
}),
);
// token过期的处理 // token过期的处理
client.addResponseInterceptor( client.addResponseInterceptor(
@ -111,7 +105,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) {
// 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg
// 当前mock接口返回的错误字段是 error 或者 message // 当前mock接口返回的错误字段是 error 或者 message
const responseData = error?.response?.data ?? {}; const responseData = error?.response?.data ?? {};
const errorMessage = responseData?.error ?? responseData?.message ?? ''; const errorMessage =
responseData?.error ?? responseData?.message ?? responseData?.msg ?? '';
// 如果没有错误信息,则会根据状态码进行提示 // 如果没有错误信息,则会根据状态码进行提示
message.error(errorMessage || msg); message.error(errorMessage || msg);
}), }),

3
pnpm-lock.yaml

@ -1901,6 +1901,9 @@ importers:
packages/effects/request: packages/effects/request:
dependencies: dependencies:
'@vben/constants':
specifier: workspace:*
version: link:../../constants
'@vben/locales': '@vben/locales':
specifier: workspace:* specifier: workspace:*
version: link:../../locales version: link:../../locales

Loading…
Cancel
Save