docs(api): 补充分类与剧单管理接口文档

This commit is contained in:
Zhou Weidong authored and trae-solo-agent committed 2026-10-22 22:17:58 +08:00
1 parent a3ff636e45
commit 45e3d84f59
1 file changed
+188
+188
View File
@@ -1074,6 +1074,194 @@ GET /app/notices?pageIndex=1&pageSize=20
**筛选与错误码**:`title` 必填(1–128);`content` 最长 2000;公告不存在 → `200002 公告不存在`;
`status` 只接受 0/1,其他值 → `400`。
### 2.13 运营分类管理(已实现)
> 「分类」是运营自定义的分组,与短剧**类型**(`/admin/drama-categories`,写 `drama_category`)是两套独立概念。
> 分类存在 `drama_classification`,通过 `drama_classification_drama` 关联任意多部短剧。
> 后台页面:菜单 **分类管理**(`/content/category-dramas` → `CategoryDramaView.vue`)。
**接口清单**(前缀 `/admin/drama-classifications`)
| 方法 | 路径 | 权限点 | 说明 |
| --- | --- | --- | --- |
| GET | `/admin/drama-classifications` | `drama:list` | 分类列表(带关联短剧数量) |
| POST | `/admin/drama-classifications` | `drama:create` | 新建分类,返回新分类 id |
| PUT | `/admin/drama-classifications/{id}` | `drama:update` | 编辑分类 |
| DELETE | `/admin/drama-classifications/{id}` | `drama:delete` | 删除分类(级联删关联,短剧本身保留) |
| GET | `/admin/drama-classifications/{id}/dramas` | `drama:list` | 分类下已关联的短剧(分页) |
| GET | `/admin/drama-classifications/{id}/dramas/candidates` | `drama:list` | 尚未关联到该分类的短剧(分页,供多选) |
| POST | `/admin/drama-classifications/{id}/dramas` | `drama:update` | 批量关联短剧,返回实际新增数量 |
| DELETE | `/admin/drama-classifications/{id}/dramas/{dramaId}` | `drama:update` | 从分类移出短剧(幂等) |
**列表响应**
```json
{
"code": 0,
"message": "ok",
"data": [
{
"id": "2112807182243336193",
"name": "本周必看",
"sort": 1,
"status": 1,
"dramaCount": 12,
"updatedAt": "2026-10-22T19:41:02"
}
]
}
```
排序规则固定为 `sort asc, id desc`;`dramaCount` 是关联表按分类聚合的实时数量。
时间字段为 `LocalDateTime` 的 ISO 字符串(`yyyy-MM-ddTHH:mm:ss`,秒级),前端按需替换 `T` 为空格。
**新建 / 编辑请求体**
```json
{ "name": "本周必看", "sort": 1, "status": 1 }
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `name` | 是 | 去首尾空格后保存,全局唯一;`@NotBlank` 提示「请填写分类名称」 |
| `sort` | 否 | 新建不传时取 `现有条数 + 1`;编辑不传(null)时保持原值 |
| `status` | 否 | `1` 启用 / `0` 停用;新建默认 `1`,编辑不传保持原值 |
**关联短剧**
```json
POST /admin/drama-classifications/2112807182243336193/dramas
{ "dramaIds": ["2112807182243336194", "2112807182243336195"] }
```
返回 `data` 为实际新增条数(整数)。已关联的、以及不存在的 `dramaId` 会被静默跳过,不报错;
全部跳过时返回 `0`。`dramaIds` 为空数组 → `400 请选择短剧`。
**短剧列表项(`GET /{id}/dramas` 与 `/dramas/candidates` 共用)**
```json
{
"total": 12,
"list": [
{
"id": "2112807182243336194",
"title": "闪婚后首富老公竟是我老板",
"cover": "https://.../cover.jpg",
"status": "published",
"totalEpisodes": 80,
"sort": 100,
"updatedAt": "2026-10-22T18:00:00"
}
]
}
```
- 查询参数:`keyword`(按 `title` 模糊匹配,可空)、`pageIndex`(默认 1)、`pageSize`(默认 10,上限 100)
- 排序:`sort desc, id desc`
- `status` 取值:`draft` 草稿 / `reviewing` 审核中 / `approved` 待发布 / `published` 已上线 / `offline` 已下线
- `cover` 取自短剧 `cover_url`
**错误码**
| 场景 | 返回 |
| --- | --- |
| 分类名称重复(新建或改名撞已有) | `200001 分类名称已存在` |
| 分类 id 不存在(编辑/删除/查询/关联/移出) | `200002 分类不存在` |
| `name` 为空 | `400 请填写分类名称` |
| `dramaIds` 为空 | `400 请选择短剧` |
> 所有写操作带 `@OperationLog(module = "内容管理")` 操作日志。ID 下发口径见 **§0**。
### 2.14 剧单管理(已实现)
> 剧单使用**自己的一套分类**(`drama_playlist_category`),与「分类管理」和「类型」都没有关系。
> **没有「剧单」这一层实体**:分类直接挂短剧,关联表 `drama_playlist_category_drama(category_id, drama_id)`。
> 后台页面:菜单 **剧单管理**(`/content/drama-playlists` → `DramaPlaylistView.vue`)。
**接口清单**(前缀 `/admin/drama-playlist-categories`)
| 方法 | 路径 | 权限点 | 说明 |
| --- | --- | --- | --- |
| GET | `/admin/drama-playlist-categories` | `drama:list` | 剧单分类列表(带短剧数量) |
| POST | `/admin/drama-playlist-categories` | `drama:create` | 新建剧单分类,返回新分类 id |
| PUT | `/admin/drama-playlist-categories/{id}` | `drama:update` | 编辑剧单分类 |
| DELETE | `/admin/drama-playlist-categories/{id}` | `drama:delete` | 删除剧单分类(级联删关联,短剧本身保留) |
| GET | `/admin/drama-playlist-categories/{id}/dramas` | `drama:list` | 分类下已关联的短剧(分页) |
| GET | `/admin/drama-playlist-categories/{id}/dramas/candidates` | `drama:list` | 尚未关联到该分类的短剧(分页,供多选) |
| POST | `/admin/drama-playlist-categories/{id}/dramas` | `drama:update` | 批量把短剧加入分类,返回实际新增数量 |
| DELETE | `/admin/drama-playlist-categories/{id}/dramas/{dramaId}` | `drama:update` | 从分类移出短剧(幂等) |
**列表响应**
```json
{
"code": 0,
"message": "ok",
"data": [
{
"id": "2112807182243336196",
"name": "高甜先婚后爱",
"description": "站内投放位使用,按周更新",
"sort": 1,
"status": 1,
"dramaCount": 8
}
]
}
```
排序规则 `sort asc, id desc`;`dramaCount` 为该分类下已关联短剧数量。
**新建 / 编辑请求体**
```json
{
"name": "高甜先婚后爱",
"description": "站内投放位使用,按周更新",
"sort": 1,
"status": 1
}
```
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `name` | 是 | 去首尾空格后保存,全局唯一;`@NotBlank` 提示「请填写剧单分类名称」 |
| `description` | 否 | 最长 255 字符(超长 → `400 描述最多 255 个字符`);新建不传存空串,编辑不传保持原值 |
| `sort` | 否 | 新建不传取 `现有条数 + 1`;编辑不传保持原值 |
| `status` | 否 | `1` 启用 / `0` 停用;新建默认 `1` |
**关联短剧**
```json
POST /admin/drama-playlist-categories/2112807182243336196/dramas
{ "dramaIds": ["2112807182243336194"] }
```
返回实际新增条数;已关联或不存在的短剧自动跳过;`dramaIds` 为空 → `400 请选择短剧`。
`GET /{id}/dramas` 与 `GET /{id}/dramas/candidates` 的查询参数和响应结构与 **§2.13** 完全一致
(`keyword` / `pageIndex` / `pageSize`,响应 `{ total, list }`,列表项含
`id` / `title` / `cover` / `status` / `totalEpisodes` / `sort` / `updatedAt`)。
**错误码**
| 场景 | 返回 |
| --- | --- |
| 剧单分类名称重复 | `200001 剧单分类名称已存在` |
| 剧单分类 id 不存在 | `200002 剧单分类不存在` |
| `name` 为空 | `400 请填写剧单分类名称` |
| `description` 超过 255 | `400 描述最多 255 个字符` |
| `dramaIds` 为空 | `400 请选择短剧` |
**与「分类管理」的差异**
| 项 | 运营分类(2.13) | 剧单分类(2.14) |
| --- | --- | --- |
| 数据表 | `drama_classification` + `drama_classification_drama` | `drama_playlist_category` + `drama_playlist_category_drama` |
| 描述字段 | 无 | 有(`description`,≤255) |
| 列表返回 | 含 `updatedAt` | 含 `description`,不含 `updatedAt` |
| 菜单 | 分类管理(`/content/category-dramas`) | 剧单管理(`/content/drama-playlists`) |
| 用途 | 内容侧分组 | 运营侧投放/剧单位分组 |
## 3. 契约与实现状态对照
> 最后更新:2026-10-16(`develop` 分支)。未完成项汇总见仓库根 `README.md`「尚未完成」。