docs(tabs): 更新标签页视图组件设计与交互细节

- 采用固定内边距策略,解决标签页悬停时的布局抖动问题
- 统一关闭按钮尺寸为14x14px,提升视觉一致性
- 优化活动标签和悬停状态的层级管理,确保视觉层次正确
- 增强视觉反馈,添加内嵌阴影效果改善用户体验
- 添加平滑颜色过渡动画(0.2秒),提升交互流畅度
- 支持玻璃拟态设计系统,实现现代化视觉风格
- 完善工具箱图标支持,确保标签页工具功能准确显示
This commit is contained in:
eafonyang
2026-07-15 09:58:56 +08:00
parent 003b44e2bd
commit f48f1cce70
27 changed files with 670 additions and 212 deletions
@@ -0,0 +1,57 @@
---
kind: error_handling
name: 前后端错误处理约定:统一响应体 + HTTP 状态码 + 拦截器
category: error_handling
scope:
- '**'
source_files:
- backend/src/utils/response.js
- backend/src/middleware/auth.js
- backend/src/middleware/bodyLimit.js
- backend/src/app.js
- frontend/src/utils/request.js
- backend/src/routes/auth.js
- backend/src/routes/blacklist.js
- backend/src/routes/models.js
---
## 1. 系统/方法概述
- 后端采用「业务错误走 JSON 响应体、网络/鉴权错误走 HTTP 状态码」的双轨模式,没有统一的 Error 类或全局错误中间件。
- 前端通过 axios 请求拦截器集中处理 401/403 与业务 code=0 的错误提示和跳转。
## 2. 关键文件与位置
- 后端统一响应封装:`backend/src/utils/response.js`
- 认证与权限中间件(HTTP 错误):`backend/src/middleware/auth.js``backend/src/middleware/bodyLimit.js`
- 应用入口(无全局错误捕获):`backend/src/app.js`
- 前端请求与错误拦截:`frontend/src/utils/request.js`
- 典型路由示例(混用两种错误形式):`backend/src/routes/auth.js``backend/src/routes/blacklist.js``backend/src/routes/models.js`
## 3. 架构与约定
### 3.1 后端 — 两类错误出口
- 业务错误:通过 `ApiResponse.error(msg, code)` 返回 `{ code, msg, data }`,HTTP 状态码默认 200。调用方按 `code === 0` 判定失败。
- 网络/鉴权错误:直接 `res.status(4xx).json({ detail })`,如 401 未登录/凭证无效、403 无权限、413 上传过大等。
- 异常兜底:未在路由中 try/catch 的未捕获异常会由 Express 默认处理器输出堆栈;`app.js` 仅在启动阶段对数据库同步做 try/catch 并记录日志,不改变进程退出行为。
- 自定义错误类型:未发现专用 Error 子类,常见做法是 `throw new Error(...)` 或在外部服务调用失败时抛错让上层 catch。
### 3.2 前端 — 统一拦截与用户反馈
- 请求拦截:自动注入 Authorization 头,非登录接口携带 token。
- 响应拦截:
- 业务错误:当 `response.data.code === 0` 时,除非 `skipErrorToast` 标记,否则弹出 ElMessage 并 reject Promise,同时把原始响应挂载到 `err.responseData` 供上层读取。
- 401:清除本地认证信息,根据 `error.response.data.detail` 提示,若不在 `/login` 则重定向至登录页并带 redirect 参数。
- 403:提示“无权限”后 reject。
- 其他网络错误:打印 console 并 ElMessage.error 提示。
- 组件层:需要自行 `.catch` 处理业务错误分支逻辑(例如弹窗内显示具体错误详情)。
## 4. 开发者应遵循的规则
- 后端路由/服务层
- 校验失败、业务异常优先使用 `ApiResponse.error(msg, code)` 返回,保持 200 状态码,由前端统一提示。
- 仅对网络层/协议层问题使用 `res.status(4xx).json({ detail })`,如鉴权失败、资源不存在、参数超限等。
- 对外部依赖(数据库、Squiglink 等)调用需包裹 try/catch,将底层错误转换为 `ApiResponse.error` 或合适的 HTTP 错误。
- 避免在路由中直接 throw 未捕获异常;如需抛出,应在外层统一捕获并转为标准响应。
- 前端 API 调用
- 依赖 `request.js` 的响应拦截进行通用错误提示;对不需要全局 toast 的场景,设置 `config.skipErrorToast = true` 并在调用处自行提示。
- 通过 `err.responseData` 获取后端返回的完整业务错误对象,用于展示更详细的错误信息。
- 不要重复实现 401/403 的重定向与提示逻辑,统一交由拦截器处理。
- 一致性建议
- 逐步收敛 `res.json(ApiResponse.error(...))``res.status(4xx).json({ detail })` 的使用边界,减少同一接口混合两种返回形式的情况。
- 考虑引入全局错误中间件,将未捕获异常统一记录并返回友好响应,提升可观测性与健壮性。