From 1def9d3f157a6b2bcab4a0360349ae24e68e387c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=9B=AA=E5=BF=86=E5=A4=A9=E5=A0=82?= <1455668754@qq.com> Date: Mon, 31 Aug 2026 16:31:56 +0800 Subject: [PATCH] =?UTF-8?q?feat(request):=20=E6=8F=90=E5=8F=96=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E5=93=8D=E5=BA=94=E5=8F=82=E6=95=B0=E4=B8=8E=E8=BF=94?= =?UTF-8?q?=E5=9B=9E=E7=8A=B6=E6=80=81=E7=A0=81=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-antd/src/api/request.ts | 11 +--- apps/web-antdv-next/src/api/request.ts | 11 +--- apps/web-ele/src/api/request.ts | 11 +--- apps/web-naive/src/api/request.ts | 11 +--- apps/web-tdesign/src/api/request.ts | 11 +--- docs/src/en/guide/essentials/server.md | 3 +- docs/src/guide/essentials/server.md | 3 +- packages/constants/src/http.enum.ts | 61 +++++++++++++++++++ packages/constants/src/index.ts | 1 + packages/effects/request/package.json | 1 + .../src/request-client/preset-interceptors.ts | 40 +++++++----- playground/src/api/request.ts | 11 +--- pnpm-lock.yaml | 3 + 13 files changed, 114 insertions(+), 64 deletions(-) create mode 100644 packages/constants/src/http.enum.ts diff --git a/apps/web-antd/src/api/request.ts b/apps/web-antd/src/api/request.ts index 288dddd09..987aed55c 100644 --- a/apps/web-antd/src/api/request.ts +++ b/apps/web-antd/src/api/request.ts @@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/apps/web-antdv-next/src/api/request.ts b/apps/web-antdv-next/src/api/request.ts index d97a2163b..4b3599ce6 100644 --- a/apps/web-antdv-next/src/api/request.ts +++ b/apps/web-antdv-next/src/api/request.ts @@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/apps/web-ele/src/api/request.ts b/apps/web-ele/src/api/request.ts index 203b35bf7..23760fe4f 100644 --- a/apps/web-ele/src/api/request.ts +++ b/apps/web-ele/src/api/request.ts @@ -72,13 +72,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -97,7 +91,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 ElMessage.error(errorMessage || msg); }), diff --git a/apps/web-naive/src/api/request.ts b/apps/web-naive/src/api/request.ts index f8fbacc0b..5a154f224 100644 --- a/apps/web-naive/src/api/request.ts +++ b/apps/web-naive/src/api/request.ts @@ -71,13 +71,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -96,7 +90,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/apps/web-tdesign/src/api/request.ts b/apps/web-tdesign/src/api/request.ts index 86b181d33..473e849b6 100644 --- a/apps/web-tdesign/src/api/request.ts +++ b/apps/web-tdesign/src/api/request.ts @@ -71,13 +71,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -96,7 +90,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/docs/src/en/guide/essentials/server.md b/docs/src/en/guide/essentials/server.md index 770a0e453..ae68af36c 100644 --- a/docs/src/en/guide/essentials/server.md +++ b/docs/src/en/guide/essentials/server.md @@ -261,7 +261,8 @@ function createRequestClient(baseURL: string) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/docs/src/guide/essentials/server.md b/docs/src/guide/essentials/server.md index 304c500ee..253419473 100644 --- a/docs/src/guide/essentials/server.md +++ b/docs/src/guide/essentials/server.md @@ -292,7 +292,8 @@ function createRequestClient(baseURL: string) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/packages/constants/src/http.enum.ts b/packages/constants/src/http.enum.ts new file mode 100644 index 000000000..ccee40d37 --- /dev/null +++ b/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', +} diff --git a/packages/constants/src/index.ts b/packages/constants/src/index.ts index 6502c6db9..f8b58e6d3 100644 --- a/packages/constants/src/index.ts +++ b/packages/constants/src/index.ts @@ -1,2 +1,3 @@ export * from './core'; +export * from './http.enum'; export * from '@vben-core/shared/constants'; diff --git a/packages/effects/request/package.json b/packages/effects/request/package.json index a8c3147f1..f7ba3cb37 100644 --- a/packages/effects/request/package.json +++ b/packages/effects/request/package.json @@ -20,6 +20,7 @@ } }, "dependencies": { + "@vben/constants": "workspace:*", "@vben/locales": "workspace:*", "@vben/utils": "workspace:*", "axios": "catalog:", diff --git a/packages/effects/request/src/request-client/preset-interceptors.ts b/packages/effects/request/src/request-client/preset-interceptors.ts index c7bec3711..356a6dcd3 100644 --- a/packages/effects/request/src/request-client/preset-interceptors.ts +++ b/packages/effects/request/src/request-client/preset-interceptors.ts @@ -1,6 +1,7 @@ import type { RequestClient } from './request-client'; import type { MakeErrorMessageFn, ResponseInterceptorConfig } from './types'; +import { HttpResultEnum } from '@vben/constants'; import { $t } from '@vben/locales'; import { isFunction } from '@vben/utils'; @@ -9,15 +10,25 @@ import axios from 'axios'; export const defaultResponseInterceptor = ({ codeField = 'code', dataField = 'data', - successCode = 0, + successCode = HttpResultEnum.SUCCESS, }: { /** 响应数据中代表访问结果的字段名 */ - codeField: string; + codeField?: string; /** 响应数据中装载实际数据的字段名,或者提供一个函数从响应数据中解析需要返回的数据 */ - dataField: ((response: any) => any) | string; + dataField?: ((response: any) => any) | string; /** 当codeField所指定的字段值与successCode相同时,代表接口访问成功。如果提供一个函数,则返回true代表接口访问成功 */ - successCode: ((code: any) => boolean) | number | string; + successCode?: ((code: any) => boolean) | number | string; }): ResponseInterceptorConfig => { + // 初始化字段 + if (!codeField) { + codeField = 'code'; + } + if (!dataField) { + dataField = 'data'; + } + if (!successCode) { + successCode = HttpResultEnum.SUCCESS; + } return { fulfilled: (response) => { const { config, data: responseData, status } = response; @@ -61,7 +72,8 @@ export const authenticateResponseInterceptor = ({ rejected: async (error) => { const { config, response } = error; // 如果不是 401 错误,直接抛出异常 - if (response?.status !== 401) { + const status = response?.data?.code || response?.status; + if (status !== HttpResultEnum.UNAUTHORIZED) { throw error; } // 判断是否启用了 refreshToken 功能 @@ -131,29 +143,29 @@ export const errorMessageResponseInterceptor = ( } let errorMessage: string; - const status = error?.response?.status; + const status = error?.response?.data?.code || error?.response?.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'); break; } - case 401: { + case HttpResultEnum.UNAUTHORIZED: { errorMessage = $t('ui.fallback.http.unauthorized'); break; } - case 403: { + case HttpResultEnum.FORBIDDEN: { errorMessage = $t('ui.fallback.http.forbidden'); break; } - case 404: { + case HttpResultEnum.NOT_FOUND: { errorMessage = $t('ui.fallback.http.notFound'); break; } - case 408: { - errorMessage = $t('ui.fallback.http.requestTimeout'); - break; - } default: { errorMessage = $t('ui.fallback.http.internalServerError'); } diff --git a/playground/src/api/request.ts b/playground/src/api/request.ts index 3aebcce67..3038c6ecc 100644 --- a/playground/src/api/request.ts +++ b/playground/src/api/request.ts @@ -86,13 +86,7 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { }); // 处理返回的响应数据格式 - client.addResponseInterceptor( - defaultResponseInterceptor({ - codeField: 'code', - dataField: 'data', - successCode: 0, - }), - ); + client.addResponseInterceptor(defaultResponseInterceptor({})); // token过期的处理 client.addResponseInterceptor( @@ -111,7 +105,8 @@ function createRequestClient(baseURL: string, options?: RequestClientOptions) { // 这里可以根据业务进行定制,你可以拿到 error 内的信息进行定制化处理,根据不同的 code 做不同的提示,而不是直接使用 message.error 提示 msg // 当前mock接口返回的错误字段是 error 或者 message const responseData = error?.response?.data ?? {}; - const errorMessage = responseData?.error ?? responseData?.message ?? ''; + const errorMessage = + responseData?.error ?? responseData?.message ?? responseData?.msg ?? ''; // 如果没有错误信息,则会根据状态码进行提示 message.error(errorMessage || msg); }), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9100b2249..1ef0dbaaf 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1901,6 +1901,9 @@ importers: packages/effects/request: dependencies: + '@vben/constants': + specifier: workspace:* + version: link:../../constants '@vben/locales': specifier: workspace:* version: link:../../locales