# 古典文学网 · 后端 API 接口文档

> 配套课程：《Python Web 全栈开发》—— 课程二《Flask 后端开发》/ 课程三《Vue 3 前端开发》
> 对接方式：前后端分离，前端（Vue）通过 HTTP 调用后端（Flask）接口，数据格式 JSON。
> 版本：v1.0 ｜ 最后更新：2026-10-12

---

## 一、通用约定

### 1.1 基础地址

| 环境 | BaseURL |
|---|---|
| 本地开发 | `http://127.0.0.1:5000/api` |
| 生产环境 | `https://你的域名/api` |

### 1.2 请求头

| 请求头 | 说明 |
|---|---|
| `Content-Type` | `application/json`（上传文件接口为 `multipart/form-data`） |
| `Authorization` | 需要登录的接口必须携带：`Bearer <token>` |

### 1.3 统一响应格式

所有接口返回结构一致，前端只需写一套拦截逻辑：

```json
{
  "code": 200,
  "msg": "success",
  "data": {}
}
```

| 字段 | 类型 | 说明 |
|---|---|---|
| code | int | 业务状态码，见下表 |
| msg | string | 提示信息，失败时可直接展示给用户 |
| data | object / array / null | 业务数据 |

### 1.4 业务状态码

| code | 含义 | 前端处理建议 |
|---|---|---|
| 200 | 成功 | 正常取 `data` |
| 400 | 参数错误 | 提示 `msg` |
| 401 | 未登录 / Token 失效 | 清除本地 token → 跳转登录页 |
| 403 | 无权限 | 提示无权操作 |
| 404 | 资源不存在 | 提示不存在 |
| 500 | 服务器内部错误 | 提示"服务异常，请稍后再试" |

> **HTTP 状态码统一返回 200**，业务成败看 `code` 字段——这是国内项目最常见的做法，前端拦截器实现更简单。

### 1.5 分页约定

**请求参数**：`page`（页码，从 1 开始）、`page_size`（每页条数，默认 10）
**响应 data 结构**：

```json
{
  "list": [],
  "total": 128,
  "page": 1,
  "page_size": 10
}
```

### 1.6 认证方式

采用 **JWT（JSON Web Token）**：

1. 登录成功后，后端返回 `token`；
2. 前端把 `token` 存进 Pinia + `localStorage`；
3. 此后每个需要登录的请求，在请求头带上 `Authorization: Bearer <token>`；
4. 后端用装饰器 `@login_required` 解析并校验 token，取出当前用户 `user_id`。

### 1.7 接口总览

| 模块 | 方法 | 路径 | 说明 | 需登录 |
|---|---|---|---|---|
| 用户 | POST | `/api/user/register` | 注册 | 否 |
| 用户 | POST | `/api/user/login` | 登录 | 否 |
| 用户 | GET | `/api/user/profile` | 获取个人信息 | 是 |
| 用户 | PUT | `/api/user/profile` | 修改个人信息 | 是 |
| 用户 | POST | `/api/user/avatar` | 上传头像 | 是 |
| 用户 | POST | `/api/user/logout` | 退出登录 | 是 |
| 首页 | GET | `/api/banner/list` | 轮播图列表 | 否 |
| 首页 | GET | `/api/category/list` | 分类列表 | 否 |
| 首页 | GET | `/api/article/recommend` | 文学推荐 | 否 |
| 作品 | GET | `/api/article/list` | 作品列表（分页/筛选/搜索） | 否 |
| 作品 | GET | `/api/article/detail/<id>` | 作品详情 | 否 |
| 作品 | POST | `/api/article/like` | 点赞作品 | 是 |
| 书评 | GET | `/api/comment/list` | 书评列表 | 否 |
| 书评 | POST | `/api/comment/add` | 发表书评 | 是 |
| 书评 | POST | `/api/comment/like` | 点赞书评 | 是 |
| 书评 | DELETE | `/api/comment/<id>` | 删除自己的书评 | 是 |
| 收藏 | POST | `/api/favorite/toggle` | 收藏 / 取消收藏 | 是 |
| 收藏 | GET | `/api/favorite/list` | 我的收藏 | 是 |

---

## 二、用户模块

### 2.1 注册

`POST /api/user/register`

**请求体**

```json
{
  "username": "zhangsan",
  "password": "123456",
  "nickname": "张三",
  "email": "zhangsan@example.com"
}
```

| 字段 | 必填 | 校验规则 |
|---|---|---|
| username | 是 | 3–20 位，字母/数字/下划线，唯一 |
| password | 是 | 6–20 位 |
| nickname | 否 | 不填则默认取 username |
| email | 否 | 邮箱格式，唯一 |

**成功响应**

```json
{ "code": 200, "msg": "注册成功", "data": { "user_id": 3 } }
```

**失败响应**

```json
{ "code": 400, "msg": "用户名已存在", "data": null }
```

---

### 2.2 登录

`POST /api/user/login`

**请求体**

```json
{ "username": "zhangsan", "password": "123456" }
```

**成功响应**

```json
{
  "code": 200,
  "msg": "登录成功",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9....",
    "user": { "id": 3, "username": "zhangsan", "nickname": "张三", "avatar": "/static/upload/avatar/3.png" }
  }
}
```

**失败响应**

```json
{ "code": 400, "msg": "用户名或密码错误", "data": null }
```

> 安全提示：无论用户名不存在还是密码错误，都统一提示"用户名或密码错误"，避免暴露账号是否存在。

---

### 2.3 获取个人信息

`GET /api/user/profile` ｜ **需登录**

**成功响应**

```json
{
  "code": 200,
  "msg": "success",
  "data": {
    "id": 3,
    "username": "zhangsan",
    "nickname": "张三",
    "email": "zhangsan@example.com",
    "avatar": "/static/upload/avatar/3.png",
    "intro": "爱读唐诗",
    "gender": 1,
    "created_at": "2026-10-12 10:30:00",
    "stat": { "comment_count": 5, "favorite_count": 12 }
  }
}
```

---

### 2.4 修改个人信息

`PUT /api/user/profile` ｜ **需登录**

**请求体**（只传要改的字段）

```json
{ "nickname": "张三丰", "intro": "爱读唐诗宋词", "gender": 1 }
```

**成功响应**

```json
{ "code": 200, "msg": "修改成功", "data": null }
```

---

### 2.5 上传头像

`POST /api/user/avatar` ｜ **需登录** ｜ `multipart/form-data`

| 参数 | 类型 | 说明 |
|---|---|---|
| file | file | 图片文件，限 jpg/png/gif，≤ 2MB |

**成功响应**

```json
{ "code": 200, "msg": "上传成功", "data": { "avatar": "/static/upload/avatar/3_20261012.png" } }
```

**失败响应**

```json
{ "code": 400, "msg": "只允许上传 jpg/png/gif 图片", "data": null }
```

---

### 2.6 退出登录

`POST /api/user/logout` ｜ **需登录**

> JWT 是无状态的，"退出"由前端清除本地 token 完成。此接口用于记录日志 / 预留黑名单。

```json
{ "code": 200, "msg": "已退出", "data": null }
```

---

## 三、首页模块

### 3.1 轮播图列表

`GET /api/banner/list`

```json
{
  "code": 200, "msg": "success",
  "data": [
    { "id": 1, "title": "品读古典文学，涵养中国心灵", "image": "/static/images/banner1.jpg", "link": "/article/list?category_id=1" }
  ]
}
```

### 3.2 分类列表

`GET /api/category/list`

```json
{
  "code": 200, "msg": "success",
  "data": [
    { "id": 1, "name": "唐诗", "description": "唐代诗歌，格律严谨、气象恢宏" },
    { "id": 2, "name": "宋词", "description": "宋代词作，婉约与豪放并存" }
  ]
}
```

### 3.3 文学推荐（首页推荐位）

`GET /api/article/recommend?limit=6`

```json
{
  "code": 200, "msg": "success",
  "data": [
    { "id": 3, "title": "念奴娇·赤壁怀古", "author": "苏轼", "dynasty": "宋",
      "category_name": "宋词", "cover": "/static/images/a3.jpg",
      "summary": "大江东去，浪淘尽，千古风流人物。", "views": 412, "likes": 58 }
  ]
}
```

---

## 四、作品模块

### 4.1 作品列表

`GET /api/article/list`

**查询参数**

| 参数 | 必填 | 说明 |
|---|---|---|
| page / page_size | 否 | 分页，默认 1 / 10 |
| category_id | 否 | 按分类筛选 |
| keyword | 否 | 按标题 / 摘要模糊搜索 |
| dynasty | 否 | 按朝代筛选 |
| order_by | 否 | `latest`（默认）/ `hot`（按浏览量）/ `likes` |

**成功响应**

```json
{
  "code": 200, "msg": "success",
  "data": {
    "list": [
      { "id": 1, "title": "静夜思", "author": "李白", "dynasty": "唐",
        "category_name": "唐诗", "cover": "", "summary": "床前明月光……",
        "views": 328, "likes": 42, "created_at": "2026-10-12 10:00:00" }
    ],
    "total": 6, "page": 1, "page_size": 10
  }
}
```

### 4.2 作品详情

`GET /api/article/detail/<id>`

> 说明：每次访问浏览量 `views + 1`（后端做，前端不用管）。

```json
{
  "code": 200, "msg": "success",
  "data": {
    "id": 1, "title": "静夜思", "author": "李白", "dynasty": "唐",
    "category_name": "唐诗", "content": "床前明月光……",
    "views": 329, "likes": 42, "is_favorite": true, "is_liked": false,
    "comment_count": 2
  }
}
```

### 4.3 点赞作品

`POST /api/article/like` ｜ **需登录**

**请求体**

```json
{ "article_id": 1 }
```

**成功响应**（同一用户重复点赞 = 取消点赞）

```json
{ "code": 200, "msg": "操作成功", "data": { "liked": true, "likes": 43 } }
```

---

## 五、书评模块

### 5.1 书评列表

`GET /api/comment/list?article_id=1&page=1&page_size=10`

```json
{
  "code": 200, "msg": "success",
  "data": {
    "list": [
      { "id": 1, "content": "短短二十字，写尽思乡之情。", "likes": 5,
        "user": { "id": 1, "nickname": "管理员", "avatar": "/static/upload/avatar/1.png" },
        "created_at": "2026-10-12 10:05:00",
        "children": [
          { "id": 4, "content": "同感！", "user": { "id": 2, "nickname": "青莲居士" }, "created_at": "2026-10-12 10:08:00" }
        ]
      }
    ],
    "total": 2, "page": 1, "page_size": 10
  }
}
```

### 5.2 发表书评

`POST /api/comment/add` ｜ **需登录**

**请求体**

```json
{ "article_id": 1, "content": "好诗！", "parent_id": null }
```

> `parent_id` 不为空时即为"回复某条书评"。

```json
{ "code": 200, "msg": "发表成功", "data": { "comment_id": 9 } }
```

### 5.3 点赞书评

`POST /api/comment/like` ｜ **需登录**

```json
{ "comment_id": 1 }
```

```json
{ "code": 200, "msg": "操作成功", "data": { "liked": true, "likes": 6 } }
```

### 5.4 删除书评

`DELETE /api/comment/<id>` ｜ **需登录**

> 只能删自己的书评，否则返回 `{"code":403,"msg":"无权删除他人书评"}`。

```json
{ "code": 200, "msg": "删除成功", "data": null }
```

---

## 六、收藏模块

### 6.1 收藏 / 取消收藏

`POST /api/favorite/toggle` ｜ **需登录**

```json
{ "article_id": 3 }
```

```json
{ "code": 200, "msg": "操作成功", "data": { "favorited": true } }
```

### 6.2 我的收藏

`GET /api/favorite/list?page=1&page_size=10` ｜ **需登录**

```json
{
  "code": 200, "msg": "success",
  "data": {
    "list": [
      { "article_id": 3, "title": "念奴娇·赤壁怀古", "author": "苏轼", "category_name": "宋词", "created_at": "2026-10-12 11:00:00" }
    ],
    "total": 1, "page": 1, "page_size": 10
  }
}
```

---

## 七、错误响应示例

| 场景 | 响应 |
|---|---|
| 未带 token 访问需登录接口 | `{"code":401,"msg":"请先登录","data":null}` |
| token 过期 | `{"code":401,"msg":"登录已过期，请重新登录","data":null}` |
| 缺少必填参数 | `{"code":400,"msg":"缺少参数：article_id","data":null}` |
| 访问不存在的作品 | `{"code":404,"msg":"作品不存在","data":null}` |
| 后端异常 | `{"code":500,"msg":"服务器内部错误","data":null}` |

---

## 八、接口设计规范（供课程二"后端 API 设计规范"一节讲解）

1. **用名词复数表示资源**：`/api/article/list`，不要写 `/api/getArticle`。
2. **用 HTTP 方法表达动作**：GET 查、POST 增、PUT 改、DELETE 删。
3. **统一响应包装**：所有接口 `{code, msg, data}`，前端一套拦截器搞定。
4. **统一错误处理**：后端用全局异常处理器捕获，绝不把堆栈抛给前端。
5. **分页 / 排序 / 筛选走查询参数**，不要塞进路径。
6. **鉴权信息放请求头**，不要放 URL（URL 会被日志记录）。
7. **参数校验前置**：进入业务逻辑前先校验，错误统一返回 400 + 可读提示。
8. **不返回敏感字段**：`password` 永远不出现在响应里。
