# API 响应格式说明

## 统一响应格式

所有 API 接口现在都返回统一的格式：

```json
{
  "code": 0,
  "message": "Success",
  "data": {}
}
```

## 字段说明

### code (Number)
- **0**: 成功
- **400**: 请求参数错误
- **401**: 未授权/Token 无效
- **403**: 禁止访问
- **404**: 资源不找到
- **409**: 冲突（如重复数据）
- **500**: 服务器内部错误

### message (String)
- 操作结果的描述信息
- 成功时通常为 "Success" 或具体的成功消息
- 失败时为错误描述

### data (Object | Array | null)
- 成功时包含返回的数据
- 失败时为 null

## 响应示例

### 成功响应

#### 1. 登录成功
```json
{
  "code": 0,
  "message": "Login successful",
  "data": {
    "user": {
      "id": "uuid",
      "nickname": "用户昵称",
      "avatar": "https://...",
      "language": "zh",
      "balance": 0.00
    },
    "token": "Bearer eyJhbGc...",
    "refreshToken": "eyJhbGc..."
  }
}
```

#### 2. 获取列表
```json
{
  "code": 0,
  "message": "Success",
  "data": {
    "items": [
      { "id": 1, "name": "Item 1" },
      { "id": 2, "name": "Item 2" }
    ],
    "pagination": {
      "total": 100,
      "page": 1,
      "limit": 10,
      "totalPages": 10
    }
  }
}
```

#### 3. 创建资源
```json
{
  "code": 0,
  "message": "Created successfully",
  "data": {
    "id": "uuid",
    "name": "New Item",
    "createdAt": "2025-12-05T12:00:00Z"
  }
}
```

#### 4. 删除资源
```json
{
  "code": 0,
  "message": "Deleted successfully",
  "data": null
}
```

### 错误响应

#### 1. 参数验证错误 (400)
```json
{
  "code": 400,
  "message": "Invalid input data",
  "data": null,
  "errors": [
    {
      "field": "email",
      "message": "Email is required"
    }
  ]
}
```

#### 2. 未授权 (401)
```json
{
  "code": 401,
  "message": "Invalid or expired token",
  "data": null
}
```

#### 3. 禁止访问 (403)
```json
{
  "code": 403,
  "message": "Insufficient permissions",
  "data": null
}
```

#### 4. 资源不存在 (404)
```json
{
  "code": 404,
  "message": "Resource not found",
  "data": null
}
```

#### 5. 服务器错误 (500)
```json
{
  "code": 500,
  "message": "Internal server error",
  "data": null
}
```

## 实现方式

### 方式 1: 使用响应工具函数

```javascript
const { sendSuccess, sendError, sendPaginated } = require('../utils/response');

// 成功响应
sendSuccess(res, data, 'Operation successful');

// 错误响应
sendError(res, 'Error message', 400, 400);

// 分页响应
sendPaginated(res, items, total, page, limit, 'Success');
```

### 方式 2: 自动转换（推荐）

系统已配置响应格式化中间件，会自动转换所有响应：

```javascript
// 旧格式（会自动转换）
res.json({
  success: true,
  data: { ... }
});

// 自动转换为
{
  code: 0,
  message: "Success",
  data: { ... }
}
```

## 前端使用

### 判断请求是否成功

```javascript
const response = await api.login(code);

// 方式 1: 判断 code
if (response.code === 0) {
  // 成功
  console.log(response.data);
} else {
  // 失败
  console.error(response.message);
}

// 方式 2: 兼容旧格式
const isSuccess = (response.code === 0) || (response.success === true);
if (isSuccess) {
  // 成功
}
```

### 错误处理

```javascript
try {
  const response = await api.someRequest();
  
  if (response.code !== 0) {
    // 显示错误消息
    uni.showToast({
      title: response.message,
      icon: 'none'
    });
    return;
  }
  
  // 处理成功数据
  const data = response.data;
  
} catch (error) {
  console.error('Request failed:', error);
}
```

## 迁移指南

### 从旧格式迁移

如果你的代码使用旧格式 `{ success: true, data: {} }`：

#### 1. 更新判断逻辑

```javascript
// 旧代码
if (data.success) {
  // ...
}

// 新代码
if (data.code === 0) {
  // ...
}

// 或兼容两种格式
if (data.code === 0 || data.success === true) {
  // ...
}
```

#### 2. 更新错误处理

```javascript
// 旧代码
if (!data.success) {
  console.error(data.error.message);
}

// 新代码
if (data.code !== 0) {
  console.error(data.message);
}
```

#### 3. 更新数据访问

```javascript
// 数据访问方式不变
const user = data.data.user;
const items = data.data.items;
```

## 注意事项

1. **code 为 0 表示成功**，其他值表示失败
2. **message** 字段始终存在，包含操作结果描述
3. **data** 字段在失败时为 null
4. 开发环境下，错误响应可能包含额外的 **error** 字段用于调试
5. HTTP 状态码与 code 字段可能不同，建议以 code 字段为准

## 相关文件

- `backend/src/middleware/responseFormatter.js` - 响应格式化中间件
- `backend/src/utils/response.js` - 响应工具函数
- `backend/src/middleware/errorHandler.js` - 错误处理中间件

## 测试

### 测试成功响应

```bash
curl http://localhost:3000/api/v1/categories

# 期望输出
{
  "code": 0,
  "message": "Success",
  "data": [...]
}
```

### 测试错误响应

```bash
curl http://localhost:3000/api/v1/services/invalid-id

# 期望输出
{
  "code": 404,
  "message": "Service not found",
  "data": null
}
```

## 常见问题

### Q: 为什么要统一响应格式？
A: 统一的响应格式让前端更容易处理 API 响应，减少判断逻辑，提高代码可维护性。

### Q: code 和 HTTP 状态码有什么区别？
A: HTTP 状态码是传输层的状态，code 是业务层的状态。建议前端主要使用 code 判断业务成功与否。

### Q: 如何处理分页数据？
A: 分页数据包含在 data 对象中，包括 items 数组和 pagination 对象。

### Q: 旧代码会自动转换吗？
A: 是的，响应格式化中间件会自动转换旧格式到新格式，无需修改现有控制器代码。

### Q: 如何在开发环境查看详细错误？
A: 开发环境下，错误响应会包含额外的 error 对象，包含详细的错误信息和堆栈跟踪。
