Files

206 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 书籍章节 admin 接口
## 基本信息
- 模块book
- 资源:书籍章节
-admin
- 鉴权:`PrivateGroup`,需要 `JWT + Casbin`
- 审计:创建、更新、单删、批量删除启用 `OperationRecord`
- 前缀:`/book`
- 实体模型:`book.BookChapter`
- 搜索入参:`bookReq.BookChapterSearch`
- 详情响应:`bookRes.BookChapterResponse`
- 列表项:`bookRes.BookChapterListItem`
- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult`
- 删除策略:硬删
## CRUD
### 创建书籍章节
- Method`POST`
- Path`/book/createBookChapter`
- Handler`BookChapterApi.CreateBookChapter`
- Service`BookChapterService.CreateBookChapter`
- 审计:是
#### Request Body `book.BookChapter`
| 字段 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| bookId | uint | 是 | `> 0` | 所属书籍 ID |
| title | string | 是 | 非空,最长 `255` | 章节标题 |
| chapterNo | int | 是 | `> 0`;同一 `bookId` 下唯一 | 同书内章节顺序编号 |
| isReadable | bool | 否 | 默认 `false`;为 `true``totalLines > 0` | 是否对 app 端开放阅读 |
| contentFileUrl | string | 是 | 非空,最长 `500` | 章节内容文件 URL |
| totalLines | int | 否 | 默认 `0``>= 0` | 章节正文总行数 |
| isEnabled | bool | 否 | 默认 `true` | 章节是否启用 |
#### Response
- `response.Response{msg}`
#### 规则
- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`
- `bookId + chapterNo` 唯一。
- `isReadable=true` 时,`totalLines` 必须大于 `0`
### 删除书籍章节
- Method`DELETE`
- Path`/book/deleteBookChapter`
- Handler`BookChapterApi.DeleteBookChapter`
- Service`BookChapterService.DeleteBookChapter`
- 审计:是
#### Request Query
| 参数 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| id | int | 是 | `> 0` | 章节 ID |
#### Response
- `response.Response{msg}`
### 批量删除书籍章节
- Method`DELETE`
- Path`/book/deleteBookChapterByIds`
- Handler`BookChapterApi.DeleteBookChapterByIds`
- Service`BookChapterService.DeleteBookChapterByIds`
- 审计:是
#### Request Query
| 参数 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| ids | int[] | 二选一 | 非空,元素均 `> 0` | 章节 ID 数组 |
| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 章节 ID 数组,兼容数组写法 |
#### Response
- `response.Response{msg}`
#### 规则
- `ids``ids[]` 二选一。
### 更新书籍章节
- Method`PUT`
- Path`/book/updateBookChapter`
- Handler`BookChapterApi.UpdateBookChapter`
- Service`BookChapterService.UpdateBookChapter`
- 审计:是
#### Request Body `book.BookChapter`
| 字段 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| id | uint | 是 | `> 0` | 章节 ID |
| bookId | uint | 是 | `> 0` | 所属书籍 ID |
| title | string | 是 | 非空,最长 `255` | 章节标题 |
| chapterNo | int | 是 | `> 0`;同一 `bookId` 下唯一 | 同书内章节顺序编号 |
| isReadable | bool | 否 | 为 `true``totalLines > 0` | 是否对 app 端开放阅读 |
| contentFileUrl | string | 是 | 非空,最长 `500` | 章节内容文件 URL |
| totalLines | int | 否 | `>= 0` | 章节正文总行数 |
| isEnabled | bool | 否 | 布尔值 | 章节是否启用 |
#### Response
- `response.Response{msg}`
#### 规则
- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`
- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。
- `bookId + chapterNo` 唯一。
- `isReadable=true` 时,`totalLines` 必须大于 `0`
### 查询书籍章节详情
- Method`GET`
- Path`/book/findBookChapter`
- Handler`BookChapterApi.FindBookChapter`
- Service`BookChapterService.GetBookChapter`
- 审计:否
#### Request Query
| 参数 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| id | int | 是 | `> 0` | 章节 ID |
#### Response `bookRes.BookChapterResponse`
| 字段 | 类型 | 说明 |
|:---|:---|:---|
| bookChapter | object | 章节实体 |
| bookChapter.id | uint | 章节 ID |
| bookChapter.createdAt | string | 创建时间 |
| bookChapter.updatedAt | string | 更新时间 |
| bookChapter.bookId | uint | 所属书籍 ID |
| bookChapter.bookTitle | string | 书籍标题展示字段,来源于 `book.title AS book_title` |
| bookChapter.title | string | 章节标题 |
| bookChapter.chapterNo | int | 同书内章节顺序编号 |
| bookChapter.isReadable | bool | 是否对 app 端开放阅读 |
| bookChapter.contentFileUrl | string | 章节内容文件 URL |
| bookChapter.totalLines | int | 章节正文总行数 |
| bookChapter.isEnabled | bool | 章节是否启用 |
### 分页查询书籍章节列表
- Method`GET`
- Path`/book/getBookChapterList`
- Handler`BookChapterApi.GetBookChapterList`
- Service`BookChapterService.GetBookChapterInfoList`
- 审计:否
#### Request Query `bookReq.BookChapterSearch`
| 参数 | 类型 | 必填 | 规则 | 说明 |
|:---|:---|:---:|:---|:---|
| page | int | 否 | 默认 `1`,最小 `1` | 页码 |
| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 |
| keyword | string | 否 | 章节标题模糊查询 | 关键字 |
| bookId | uint | 否 | `> 0` | 所属书籍 ID |
| isReadable | bool | 否 | 布尔值 | 是否对 app 端开放阅读 |
| isEnabled | bool | 否 | 布尔值 | 章节是否启用 |
#### Response `response.PageResult`
| 字段 | 类型 | 说明 |
|:---|:---|:---|
| list | array | `bookRes.BookChapterListItem` 列表 |
| list[].id | uint | 章节 ID |
| list[].createdAt | string | 创建时间 |
| list[].updatedAt | string | 更新时间 |
| list[].bookId | uint | 所属书籍 ID |
| list[].bookTitle | string | 书籍标题展示字段,来源于 `book.title AS book_title` |
| list[].title | string | 章节标题 |
| list[].chapterNo | int | 同书内章节顺序编号 |
| list[].isReadable | bool | 是否对 app 端开放阅读 |
| list[].contentFileUrl | string | 章节内容文件 URL |
| list[].totalLines | int | 章节正文总行数 |
| list[].isEnabled | bool | 章节是否启用 |
| total | int64 | 总数 |
| page | int | 当前页 |
| pageSize | int | 每页数量 |
#### 规则
- 列表默认排序:`book_id asc, chapter_no asc`
- 列表通过 `book_chapter` 联表 `book` 补充 `bookTitle` 展示字段;写接口仍只接收 `bookId`
## 规则
- 章节使用硬删;删除后数据库不保留软删标记。
- `bookId + chapterNo` 是章节唯一约束;新增或更新时不能与同书已有章节冲突。
- `chapterNo` 必须大于 `0`
- `totalLines` 不能小于 `0``isReadable=true``totalLines` 必须大于 `0`
- 创建、更新复用实体 `book.BookChapter`;列表查询复用 `bookReq.BookChapterSearch`;详情返回 `bookRes.BookChapterResponse`
- `bookTitle` 为只读展示字段,禁止写入实体表结构,禁止作为创建或更新入参。