# 上传一个章节

按全书章节序号创建或覆盖标题、正文与卷关联。

`PUT /api/v2/content`

不带查询参数：

```json
{
  "novelId": 10,
  "volumeId": 20,
  "order": 1,
  "title": "第一章 出发",
  "content": "第一段。\n\n第二段。"
}
```

| 请求键 | 类型 | 必填 | 默认/约束 |
| --- | --- | --- | --- |
| `novelId` | integer | 是 | 已存在的小说 ID。 |
| `volumeId` | integer / null | 否 | 数据库卷 ID，必须属于这部小说；省略/null 表示未分卷，覆盖时也会清除旧关联。 |
| `order` | integer | 是 | 从 1 开始的**全书章节序号**，跨卷不重置，可以不连续。 |
| `title` | string | 是 | 去除首尾空白后不能为空。 |
| `content` | string | 是 | 纯文本，保留原始换行和空白，不允许全为空白。 |

以 `(novelId, order)` 新增或覆盖，覆盖时保留章节 ID，替换标题、正文和卷关联。
无论新增还是覆盖均返回 `200`。小说/卷不存在或卷属于其他小说返回 400。
`POST /api/v2/content` 不支持，单章上传使用 PUT；批量上传使用 `POST /api/v2/upload`。

PUT 和 GET 单条响应：

```json
{
  "id": 30,
  "novelId": 10,
  "volumeId": 20,
  "order": 1,
  "title": "第一章 出发",
  "content": "第一段。\n\n第二段。",
  "updatedAt": "2026-10-29T04:00:00Z"
}
```

`id` 是章节 ID，`updatedAt` 为服务端更新时间，其他键定义与请求字段相同。
未分卷时 `volumeId` 为 null。GET 列表为这些对象组成的数组。
