From b8894ea2dce4acd17bddf7a19c84e2ee936a3d70 Mon Sep 17 00:00:00 2001 From: jinhhanhan <1683105490@qq.com> Date: Mon, 20 Jul 2026 18:00:04 +0800 Subject: [PATCH] =?UTF-8?q?chore=EF=BC=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common/js/http-error.js | 101 ++ diy-category-item-branch.vue | 2522 ++++++++++++++++++++++++++++++++++ 2 files changed, 2623 insertions(+) create mode 100644 common/js/http-error.js create mode 100644 diy-category-item-branch.vue diff --git a/common/js/http-error.js b/common/js/http-error.js new file mode 100644 index 0000000..64506a2 --- /dev/null +++ b/common/js/http-error.js @@ -0,0 +1,101 @@ +/** + * 通用网络/接口错误分类器 + * + * 适用场景: + * - uniapp 各端统一错误分类(diy.js / 商品 / 订单 / 自定义页面等) + * - 任意传入 {statusCode, errMsg, message} 形式错误对象的位置 + * + * 设计要点: + * 1) 与 Vue / $lang 解耦:不调用任何 i18n 函数,只返回分类结果 + 原始错误字段 + * 调用方拿到 type 后,自行决定使用 $lang('http.timeout') / $lang('http.serverError') + * 或其它命名空间的文案,完全保持各模块原有的 key 命名习惯 + * 2) 通用网络/接口错误统一映射到 common.http.* 命名空间: + * - http.networkError: 通用网络异常(兜底) + * - http.timeout: 请求超时 + * - http.serverError: 服务器错误(5xx) + * - http.notFound: 接口不存在(404) + * - http.auth: 无访问权限(401/403) + * - http.unknown: 其他非 2xx + * 3) 兼容多种错误对象形态: + * - uniapp request: { statusCode, errMsg, data } + * - axios: { response: { status }, message } + * - fetch / 原生: { message, name } + * + * @param {Object|string} err 错误对象或后端业务消息字符串 + * @returns {{ type: string, statusCode?: number, errMsg?: string, raw?: any }} + * - type 取值: + * 'business' - 后端返回的业务消息字符串(已透传到 raw) + * 'empty' - 错误对象为空 + * 'notFound' - HTTP 404 + * 'server' - HTTP 5xx + * 'auth' - HTTP 401 / 403 + * 'request' - 其它非 2xx 状态码 + * 'timeout' - errMsg 含 timeout + * 'network' - errMsg 含 connect / network / fail + * 'unknown' - 无法分类 + * - statusCode: 若有则原样返回 + * - errMsg: 归一后的原始消息 + * - raw: 原始输入,方便调用方进一步处理 + */ +export function classifyHttpError(err) { + // 1) 无错误对象 + if (!err) { + return { type: 'empty', raw: err }; + } + + // 2) 后端直接返回的业务消息(字符串) + if (typeof err === 'string') { + return { type: 'business', raw: err }; + } + + // 3) 字段归一(兼容 uni / axios / 原生 Error) + const statusCode = err.statusCode + ?? err.response?.status + ?? err.status; + const errMsg = err.errMsg || err.message || ''; + + if (statusCode) { + if (statusCode === 404) return { type: 'notFound', statusCode, errMsg, raw: err }; + if (statusCode >= 500) return { type: 'server', statusCode, errMsg, raw: err }; + if (statusCode === 401 || statusCode === 403) return { type: 'auth', statusCode, errMsg, raw: err }; + return { type: 'request', statusCode, errMsg, raw: err }; + } + + if (/timeout/i.test(errMsg)) { + return { type: 'timeout', errMsg, raw: err }; + } + if (/(connect|network|fail)/i.test(errMsg)) { + return { type: 'network', errMsg, raw: err }; + } + + return { type: 'unknown', errMsg, raw: err }; +} + +/** + * 根据 classifyHttpError 的结果,映射到 common.http.* 命名空间的 i18n key + * + * 通用网络/接口错误统一走 http.*,调用方通过 $lang(key) 解析文案。 + * 原 diy.errTimeout 这类 key 已合并到 http.*,保持项目国际化更专业。 + * + * @param {string} type classifyHttpError 返回的 type + * @returns {string|null} 对应的 http.* key;type='business' 时返回 null(透传 raw) + */ +export function httpErrorKey(type) { + switch (type) { + case 'empty': return 'http.networkError'; + case 'business': return null; // 透传,不用 key + case 'notFound': return 'http.notFound'; + case 'server': return 'http.serverError'; + case 'auth': return 'http.auth'; + case 'request': return 'http.unknown'; + case 'timeout': return 'http.timeout'; + case 'network': return 'http.networkError'; + case 'unknown': + default: return 'http.networkError'; + } +} + +export default { + classifyHttpError, + httpErrorKey, +}; \ No newline at end of file diff --git a/diy-category-item-branch.vue b/diy-category-item-branch.vue new file mode 100644 index 0000000..14d4690 --- /dev/null +++ b/diy-category-item-branch.vue @@ -0,0 +1,2522 @@ + + + + +