# 错误码体系 v2 全量上线(#1391)

**日期**: 2026-04-25
**影响范围**: 全部服务 `Result.code` 字段
**关联 PR**: #1392 / #1393 / #1394 / #1395 / #1396 / #1397 / #1398
**工单**: [#1391](https://git.1814.love:8443/wx/HL/issues/1391)

---

## 🚨 前端接入提示

### ✅ 好消息:401/403/404 保留,现有拦截器零改动
- HTTP 认证相关错误码(401 未授权 / 403 无权限 / 404 未找到)**完全保留**
- 前端 axios 拦截器 / 跳登录页逻辑 **无需任何改动**
- 400 参数校验 / 500 系统错误 **保留原语义**

### 🆕 业务错误码升级为 **6 位数字**,前端可选接入
- 所有业务模块的 `Result.code` 字段不再是 400/500 通用码,变为 **6 位数字业务码**
- 如 `400101 = 产品不存在`、`500311 = 订单当前状态不允许取消`、`510411 = 合同签约失败` 等
- **message 字段保留原业务提示中文**,所有已有 `uni.showToast(res.data.message)` 代码继续生效

---

## 📋 6 位码段位表

| 段位前缀 | 模块 | 示例 |
|---------|------|------|
| `100xxx` | common 通用 | `100501` 流控拦截 / `100502` 幂等拦截 / `100901` Feign 空数据 |
| `110xxx` | auth 认证授权 | `110001` 未认证(预留) |
| `200xxx-299xxx` | user 用户 | `230301` 短信频率限制 / `230302` 短信日发送上限 / `260204` 状态列无权管理 |
| `300xxx-399xxx` | resource 资源 | `300106` 景点无权操作 / `310xxx` 酒店 / `340xxx` 用车 / `380001` 备品审批进行中不可删 |
| `400xxx-499xxx` | product 产品 | `400101` 产品不存在 / `410xxx` 价格 / `430xxx` 行程 / `460xxx` 高德地图 |
| `500xxx-509xxx` | order 订单核心 | `500xxx` 订单 CRUD / `500311` 状态不允许取消 |
| `510xxx-549xxx` | order 扩展 | `510xxx` 合同 / `520xxx` 支付 / `530xxx` 退款 / `540xxx` 保险 / `549xxx` 投诉 |
| `550xxx-599xxx` | order 子域 | `550xxx` 行程 / `560xxx` 团报 / `580xxx` 到达/工单 / `590xxx` 加价折扣 / `593xxx` 发票 |
| `600xxx-699xxx` | mp 小程序 BFF | `610xxx` 天气 |
| `900xxx-999xxx` | system 系统级 | `900001` 限流 / `900002` 熔断 |

---

## 🎯 前端可选接入(3 种粒度)

**大多数场景**:继续用 `message` 弹 toast,无需关心 code。

**需要差异化处理的场景**,可按以下 3 种粒度分支:

### Level 1 粒度:HTTP 类(优先)
```js
if (res.data.code === 401) // 跳登录
if (res.data.code === 403) // 无权限提示
if (res.data.code === 404) // 404 页
// 已有代码完全兼容,继续用即可
```

### Level 2 粒度:按段位分支(业务大类)
```js
const code = res.data.code;
if (code >= 400000 && code <= 499999) {
  // 产品相关错误,可选跳商品首页
} else if (code >= 500000 && code <= 599999) {
  // 订单相关错误
}
```

### Level 3 粒度:按具体 code 分支(细粒度 UX)
```js
if (res.data.code === 400301) {
  // 产品下架,跳首页
  uni.reLaunch({ url: '/pages/index/index' });
} else if (res.data.code === 510411) {
  // 合同签约失败,重试按钮
}
```

**接入优先级建议**:Level 1 必做(已有)→ Level 3 按 UX 需求逐个接入(非强制)。

---

## 🔧 技术变更细节

### 1. Feign 链路透传修复
**修复前**:下游服务抛 `BusinessException(400301, "产品下架")`,Feign 调用方 `getCheckedData()` 会吞码降级为 500。
**修复后**:上游 code 完整透传,前端能看到真实业务码。

### 2. 所有 admin/mp 接口的 Result.code 升级
- 之前:`{code: 400, message: "产品不存在"}` / `{code: 500, message: "订单状态不允许取消"}`
- 现在:`{code: 400101, message: "产品不存在,ID=xxx"}` / `{code: 500311, message: "当前状态不允许取消,状态=PAID"}`

### 3. message 字段保留关键子串
迁移采用 MessageFormat 占位符,所有原 message 关键中文子串保留(如"产品不存在"/"审批进行中"等),前端若用 `message.includes(xxx)` 判断仍可工作。

---

## 🧪 新 code 速查接口

各服务启动时自动注册所有错误码到中央 `ErrorCodeRegistry`,如需完整码表可通过以下方式查询:

1. **后端日志**:每个服务启动日志含 `ErrorCodeRegistry scan complete, totalCodes=X, segments=Y`
2. **容量告警**:任何段位使用率 ≥ 80% 自动 WARN 日志
3. **未来扩展**:计划提供 `/internal/errorcode/catalog` 接口导出 yaml 码表

---

## ⚠️ 3 日反馈窗口

如前端需要按具体 code 做差异化处理(Level 3),请在 **2026-04-28 前** 反馈:
- 哪个业务 code 需要特殊 UI 行为(跳页/重试/不展示等)
- 是否需要前端配置化 code-action 映射

超过 3 日无反馈视为按 Level 1 + message 继续使用,不阻塞迭代。
