# 获取全书目录

一次获取全部卷与章节目录，不分页、不包含正文。

`GET /api/v2/toc?novelId=10`

只读接口，要求相同的 Bearer Token，无请求体。只接受一个必填查询键：

| 查询键 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `novelId` | integer | 是 | 已存在的小说 ID，正的 32 位整数。 |

不接受 `limit`、`offset`、`order`、`volumeId` 或其他查询键，重复参数也返回 400。
不支持写入，其他请求方法返回 `405` 和 `Allow: GET`。

成功返回 `200`，一次返回完整目录，**不分页、不查询或返回章节正文**：

```json
{
  "novelId": 10,
  "volumes": [
    {
      "id": 20,
      "novelId": 10,
      "order": 1,
      "title": "第一卷 启程",
      "createdAt": "2026-10-29T04:00:00Z",
      "updatedAt": "2026-10-29T04:00:00Z"
    }
  ],
  "chapters": [
    {
      "id": 30,
      "novelId": 10,
      "volumeId": null,
      "order": 1,
      "title": "序章",
      "updatedAt": "2026-10-29T04:00:00Z"
    },
    {
      "id": 31,
      "novelId": 10,
      "volumeId": 20,
      "order": 2,
      "title": "第一章 出发",
      "updatedAt": "2026-10-29T04:00:00Z"
    }
  ]
}
```

- `novelId`：当前小说 ID。
- `volumes`：完整卷列表，结构与第 6 节相同，按卷 `order` 升序，包括没有章节的空卷。
- `chapters`：完整章节摘要列表，按**全书章节 `order`** 升序，不因分卷重置序号。
- 章节摘要只包含 `id`、`novelId`、`volumeId`、`order`、`title`、`updatedAt`；字段含义与第 7.2 节相同，没有 `content` 键。
- 客户端通过 `chapters[].volumeId` 与 `volumes[].id` 关联；null 为未分卷章节，不能因分组丢弃。
- 卷与章节来自同一条 SQL 查询的快照，避免并发上传期间返回不一致的分卷关系。

小说存在但没有卷或章节时，对应数组为 `[]`，不会返回 null；完全空书返回
`{"novelId":10,"volumes":[],"chapters":[]}`。小说不存在返回 `404`。
实际阅读时再用 `GET /api/v2/content?novelId=10&order=2` 按需读取章节正文。
