diff --git a/server/.ai-specs/coding-specs/module-admin-crud-default.md b/server/.ai-specs/coding-specs/module-admin-crud-default.md index 76b3c98..687dd0d 100644 --- a/server/.ai-specs/coding-specs/module-admin-crud-default.md +++ b/server/.ai-specs/coding-specs/module-admin-crud-default.md @@ -35,6 +35,7 @@ - 新增业务 `admin` 模块时,如无明确例外,先提供这 6 个接口,再叠加业务特有接口。 - 路由统一放在 `router/`,接口统一放在 `api/v1/`,业务统一放在 `service/`,模型统一放在 `model/`。 - 新增业务路由后,必须同步在 `initialize/router_biz.go` 注册。 +- 新增或修改 `.ai-specs/doc-api/<端>/.md` 时,必须遵循 `.ai-specs/sys-specs/doc-api-doc-spec.md`。 - 单个业务模块包含多个独立资源或多张业务表时,`api/v1/`、`service/`、`router/` 必须按资源拆分文件;禁止把多个资源的 CRUD 长期堆在同一个大文件。 - 单个业务模块包含多个独立资源或多张业务表时,`.ai-specs/doc-api/<端>/.md` 必须按资源拆分文档;禁止把多个资源的接口 contract 长期堆在同一个 doc-api 大文档。 - 每个资源文件只承载该资源的 `API`、`Service` 或 `Router` 方法;跨资源复用逻辑只能放在明确命名的 `common.go`、`helper.go` 等公共文件,且公共文件禁止承载具体资源 CRUD 主流程。 diff --git a/server/.ai-specs/doc-api/admin/book.md b/server/.ai-specs/doc-api/admin/book.md index 7a806fe..391959e 100644 --- a/server/.ai-specs/doc-api/admin/book.md +++ b/server/.ai-specs/doc-api/admin/book.md @@ -1,29 +1,243 @@ -# 书籍信息 admin 接口 +# 书籍信息 admin 接口 ## 基本信息 - 模块:book -- 资源:书籍 +- 资源:书籍信息 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.Book` +- 搜索入参:`bookReq.BookSearch` +- 详情响应:`bookRes.BookResponse` +- 列表项:`book.Book` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBook` | `CreateBook` | `CreateBook` | -| 单删 | `DELETE` | `/book/deleteBook` | `DeleteBook` | `DeleteBook` | -| 批量删除 | `DELETE` | `/book/deleteBookByIds` | `DeleteBookByIds` | `DeleteBookByIds` | -| 更新 | `PUT` | `/book/updateBook` | `UpdateBook` | `UpdateBook` | -| 详情 | `GET` | `/book/findBook` | `FindBook` | `GetBook` | -| 分页列表 | `GET` | `/book/getBookList` | `GetBookList` | `GetBookInfoList` | +### 创建书籍信息 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBook` +- Handler:`BookApi.CreateBook` +- Service:`BookService.CreateBook` +- 审计:是 -- 创建、更新:`body` 使用 `book.Book`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookResponse`。 +#### Request Body `book.Book` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| title | string | 是 | 非空,最大 `255` | 书名主标题 | +| subtitle | string | 否 | 最大 `255` | 书籍副标题 | +| bookType | string | 是 | 非空,值必须存在于系统字典 `book_type` | 书籍类型字典值 | +| eraTag | string | 否 | `book_era_tag`:`unknown/ancient/han/tang/song/yuan/ming/qing/modern/contemporary`;默认 `unknown` | 时代标签字典值 | +| coverUrl | string | 否 | 最大 `500` | 封面图片 URL | +| publisher | string | 否 | 最大 `128` | 出版社名称 | +| publishedAt | string | 否 | 日期类型 | 出版日期 | +| intro | string | 否 | 文本 | 书籍简介 | +| hotScore | int64 | 否 | `>= 0`;默认 `0` | 热度聚合值 | +| rating | float64 | 否 | `0 <= rating <= 10`;默认 `0.0` | 书籍评分 | +| commentCount | int64 | 否 | `>= 0`;默认 `0` | 点评数聚合值 | +| wordCount | int64 | 否 | `>= 0`;默认 `0` | 书籍总字数 | +| completionStatus | string | 否 | `book_completion_status`:`completed/serializing`;默认 `serializing` | 书籍完结状态 | +| publishStatus | string | 否 | `book_publish_status`:`draft/off_shelf/on_shelf`;默认 `draft` | 书籍上下架状态 | +| seriesId | uint | 否 | 可为空;存在时应为有效系列 ID | 所属系列 ID | +| seriesSort | int | 否 | `>= 0`;默认 `0` | 同系列内展示排序 | +| rawTxtUrl | string | 否 | 最大 `500` | 原始 txt 文件 URL | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `bookType` 是动态值域字典,业务侧只校验值存在性,不参与状态流转。 + +### 删除书籍信息 + +- Method:`DELETE` +- Path:`/book/deleteBook` +- Handler:`BookApi.DeleteBook` +- Service:`BookService.DeleteBook` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 书籍 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除书籍信息 + +- Method:`DELETE` +- Path:`/book/deleteBookByIds` +- Handler:`BookApi.DeleteBookByIds` +- Service:`BookService.DeleteBookByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 书籍 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 书籍 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新书籍信息 + +- Method:`PUT` +- Path:`/book/updateBook` +- Handler:`BookApi.UpdateBook` +- Service:`BookService.UpdateBook` +- 审计:是 + +#### Request Body `book.Book` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 书籍 ID | +| title | string | 是 | 非空,最大 `255` | 书名主标题 | +| subtitle | string | 否 | 最大 `255` | 书籍副标题 | +| bookType | string | 是 | 非空,值必须存在于系统字典 `book_type` | 书籍类型字典值 | +| eraTag | string | 否 | `book_era_tag`:`unknown/ancient/han/tang/song/yuan/ming/qing/modern/contemporary` | 时代标签字典值 | +| coverUrl | string | 否 | 最大 `500` | 封面图片 URL | +| publisher | string | 否 | 最大 `128` | 出版社名称 | +| publishedAt | string | 否 | 日期类型 | 出版日期 | +| intro | string | 否 | 文本 | 书籍简介 | +| hotScore | int64 | 否 | `>= 0` | 热度聚合值 | +| rating | float64 | 否 | `0 <= rating <= 10` | 书籍评分 | +| commentCount | int64 | 否 | `>= 0` | 点评数聚合值 | +| wordCount | int64 | 否 | `>= 0` | 书籍总字数 | +| completionStatus | string | 否 | `book_completion_status`:`completed/serializing` | 书籍完结状态 | +| publishStatus | string | 否 | `book_publish_status`:`draft/off_shelf/on_shelf` | 书籍上下架状态 | +| seriesId | uint | 否 | 可为空;存在时应为有效系列 ID | 所属系列 ID | +| seriesSort | int | 否 | `>= 0` | 同系列内展示排序 | +| rawTxtUrl | string | 否 | 最大 `500` | 原始 txt 文件 URL | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新使用实体 `Save`,前端应传完整可编辑实体,避免字段被零值覆盖。 +- `bookType` 是动态值域字典,业务侧只校验值存在性,不参与状态流转。 + +### 查询书籍信息详情 + +- Method:`GET` +- Path:`/book/findBook` +- Handler:`BookApi.FindBook` +- Service:`BookService.GetBook` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 书籍 ID | + +#### Response `bookRes.BookResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| book | object | 书籍实体 | +| book.id | uint | 主键 ID | +| book.createdAt | string | 创建时间 | +| book.updatedAt | string | 更新时间 | +| book.title | string | 书名主标题 | +| book.subtitle | string | 书籍副标题 | +| book.bookType | string | 书籍类型字典值,对应 `book_type` | +| book.eraTag | string | 时代标签字典值,对应 `book_era_tag` | +| book.coverUrl | string | 封面图片 URL | +| book.publisher | string | 出版社名称 | +| book.publishedAt | string | 出版日期 | +| book.intro | string | 书籍简介 | +| book.hotScore | int64 | 热度聚合值 | +| book.rating | float64 | 书籍评分,范围 `0-10` | +| book.commentCount | int64 | 点评数聚合值 | +| book.wordCount | int64 | 书籍总字数 | +| book.completionStatus | string | 书籍完结状态字典值,对应 `book_completion_status` | +| book.publishStatus | string | 书籍上下架状态字典值,对应 `book_publish_status` | +| book.seriesId | uint | 所属系列 ID | +| book.seriesSort | int | 同系列内展示排序 | +| book.rawTxtUrl | string | 原始 txt 文件 URL | + +### 分页查询书籍信息列表 + +- Method:`GET` +- Path:`/book/getBookList` +- Handler:`BookApi.GetBookList` +- Service:`BookService.GetBookInfoList` +- 审计:否 + +#### Request Query `bookReq.BookSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| keyword | string | 否 | 模糊匹配 `title` 或 `subtitle` | 关键字 | +| title | string | 否 | 模糊匹配 `title` | 书名主标题 | +| bookType | string | 否 | 值必须存在于系统字典 `book_type` | 书籍类型 | +| eraTag | string | 否 | `book_era_tag`:`unknown/ancient/han/tang/song/yuan/ming/qing/modern/contemporary` | 时代标签 | +| completionStatus | string | 否 | `book_completion_status`:`completed/serializing` | 完结状态 | +| publishStatus | string | 否 | `book_publish_status`:`draft/off_shelf/on_shelf` | 上下架状态 | +| seriesId | uint | 否 | `> 0` | 系列 ID | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.Book` 列表 | +| list[].id | uint | 主键 ID | +| list[].createdAt | string | 创建时间 | +| list[].updatedAt | string | 更新时间 | +| list[].title | string | 书名主标题 | +| list[].subtitle | string | 书籍副标题 | +| list[].bookType | string | 书籍类型字典值,对应 `book_type` | +| list[].eraTag | string | 时代标签字典值,对应 `book_era_tag` | +| list[].coverUrl | string | 封面图片 URL | +| list[].publisher | string | 出版社名称 | +| list[].publishedAt | string | 出版日期 | +| list[].intro | string | 书籍简介 | +| list[].hotScore | int64 | 热度聚合值 | +| list[].rating | float64 | 书籍评分,范围 `0-10` | +| list[].commentCount | int64 | 点评数聚合值 | +| list[].wordCount | int64 | 书籍总字数 | +| list[].completionStatus | string | 书籍完结状态字典值,对应 `book_completion_status` | +| list[].publishStatus | string | 书籍上下架状态字典值,对应 `book_publish_status` | +| list[].seriesId | uint | 所属系列 ID | +| list[].seriesSort | int | 同系列内展示排序 | +| list[].rawTxtUrl | string | 原始 txt 文件 URL | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 + +## 规则 + +- admin 端书籍信息 CRUD 统一挂载到 `PrivateGroup`,需要 `JWT + Casbin`。 +- 写操作启用 `OperationRecord`;读操作不启用操作审计。 +- 删除策略为硬删,实体使用 `book.HardDeleteModel`,不维护 `deleted_at`。 +- `eraTag/completionStatus/publishStatus` 必须符合对应固定值域字典。 +- `hotScore/commentCount/wordCount/seriesSort` 不能小于 `0`;`rating` 范围为 `0-10`。 +- `seriesId` 可为空;非空时表示书籍挂载到对应系列,展示排序使用 `seriesSort`。 diff --git a/server/.ai-specs/doc-api/admin/book_author.md b/server/.ai-specs/doc-api/admin/book_author.md index 817ea74..c926f9b 100644 --- a/server/.ai-specs/doc-api/admin/book_author.md +++ b/server/.ai-specs/doc-api/admin/book_author.md @@ -1,29 +1,194 @@ -# 书籍作者 admin 接口 +# 书籍作者 admin 接口 ## 基本信息 - 模块:book -- 资源:作者 +- 资源:书籍作者 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookAuthor` +- 搜索入参:`bookReq.BookAuthorSearch` +- 详情响应:`bookRes.BookAuthorResponse` +- 列表项:`bookRes.BookAuthorListItem` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookAuthor` | `CreateBookAuthor` | `CreateBookAuthor` | -| 单删 | `DELETE` | `/book/deleteBookAuthor` | `DeleteBookAuthor` | `DeleteBookAuthor` | -| 批量删除 | `DELETE` | `/book/deleteBookAuthorByIds` | `DeleteBookAuthorByIds` | `DeleteBookAuthorByIds` | -| 更新 | `PUT` | `/book/updateBookAuthor` | `UpdateBookAuthor` | `UpdateBookAuthor` | -| 详情 | `GET` | `/book/findBookAuthor` | `FindBookAuthor` | `GetBookAuthor` | -| 分页列表 | `GET` | `/book/getBookAuthorList` | `GetBookAuthorList` | `GetBookAuthorInfoList` | +### 创建书籍作者 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookAuthor` +- Handler:`BookAuthorApi.CreateBookAuthor` +- Service:`BookAuthorService.CreateBookAuthor` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookAuthor`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookAuthorSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookAuthorResponse`。 +#### Request Body `book.BookAuthor` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| name | string | 是 | 非空,最大 `128` 字符,唯一 | 作者名称 | +| authorStatus | string | 否 | `common_enabled_status`:`enabled`/`disabled`;默认 `enabled` | 作者启用状态 | +| intro | string | 否 | 可为空 | 作者简介 | +| coverUrl | string | 否 | 可为空,最大 `500` 字符 | 作者头像或封面 URL | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `name` 必须唯一,对应唯一索引 `uk_book_author_name`。 +- `authorStatus` 为空时按数据库默认值 `enabled` 落库;传值时必须符合 `common_enabled_status`。 + +### 删除书籍作者 + +- Method:`DELETE` +- Path:`/book/deleteBookAuthor` +- Handler:`BookAuthorApi.DeleteBookAuthor` +- Service:`BookAuthorService.DeleteBookAuthor` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 作者 ID | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 删除策略为硬删。 + +### 批量删除书籍作者 + +- Method:`DELETE` +- Path:`/book/deleteBookAuthorByIds` +- Handler:`BookAuthorApi.DeleteBookAuthorByIds` +- Service:`BookAuthorService.DeleteBookAuthorByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 作者 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 作者 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 +- 删除策略为硬删。 + +### 更新书籍作者 + +- Method:`PUT` +- Path:`/book/updateBookAuthor` +- Handler:`BookAuthorApi.UpdateBookAuthor` +- Service:`BookAuthorService.UpdateBookAuthor` +- 审计:是 + +#### Request Body `book.BookAuthor` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 作者 ID | +| name | string | 是 | 非空,最大 `128` 字符,唯一 | 作者名称 | +| authorStatus | string | 否 | `common_enabled_status`:`enabled`/`disabled` | 作者启用状态 | +| intro | string | 否 | 可为空 | 作者简介 | +| coverUrl | string | 否 | 可为空,最大 `500` 字符 | 作者头像或封面 URL | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。 +- `name` 必须唯一,对应唯一索引 `uk_book_author_name`。 +- `authorStatus` 为空时会按空值保存;传值时必须符合 `common_enabled_status`。 + +### 查询书籍作者详情 + +- Method:`GET` +- Path:`/book/findBookAuthor` +- Handler:`BookAuthorApi.FindBookAuthor` +- Service:`BookAuthorService.GetBookAuthor` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 作者 ID | + +#### Response `bookRes.BookAuthorResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookAuthor | object | 作者实体 | +| bookAuthor.id | uint | 作者 ID | +| bookAuthor.createdAt | time | 创建时间 | +| bookAuthor.updatedAt | time | 更新时间 | +| bookAuthor.name | string | 作者名称 | +| bookAuthor.authorStatus | string | 作者启用状态,见 `common_enabled_status` | +| bookAuthor.intro | string | 作者简介 | +| bookAuthor.coverUrl | string | 作者头像或封面 URL | + +### 分页查询书籍作者列表 + +- Method:`GET` +- Path:`/book/getBookAuthorList` +- Handler:`BookAuthorApi.GetBookAuthorList` +- Service:`BookAuthorService.GetBookAuthorInfoList` +- 审计:否 + +#### Request Query `bookReq.BookAuthorSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| keyword | string | 否 | 模糊匹配 `name` | 通用关键字 | +| name | string | 否 | 模糊匹配 `name` | 作者名称 | +| authorStatus | string | 否 | `common_enabled_status`:`enabled`/`disabled` | 作者启用状态 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `bookRes.BookAuthorListItem` 列表 | +| list[].id | uint | 作者 ID | +| list[].createdAt | time | 创建时间 | +| list[].updatedAt | time | 更新时间 | +| list[].name | string | 作者名称 | +| list[].authorStatus | string | 作者启用状态,见 `common_enabled_status` | +| list[].intro | string | 作者简介 | +| list[].coverUrl | string | 作者头像或封面 URL | +| list[].authorName | string | 作者名称展示字段,来源于 `book_author.name AS author_name` | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 +- `keyword` 与 `name` 同时传入时,会叠加为两个 `name LIKE` 条件。 + +## 规则 + +- admin 端书籍作者 CRUD 挂载到 `PrivateGroup`,需要 `JWT + Casbin`。 +- 写操作挂载 `middleware.OperationRecord()`;读操作不挂操作审计。 +- `authorStatus` 固定值域来自 `common_enabled_status`:`enabled`、`disabled`。 +- 表结构、字段长度、唯一约束和索引以 `.ai-specs/doc-sql/book_author.sql` 为准。 diff --git a/server/.ai-specs/doc-api/admin/book_author_relation.md b/server/.ai-specs/doc-api/admin/book_author_relation.md index d741a93..1eb1f26 100644 --- a/server/.ai-specs/doc-api/admin/book_author_relation.md +++ b/server/.ai-specs/doc-api/admin/book_author_relation.md @@ -1,29 +1,180 @@ -# 书籍作者关系 admin 接口 +# 书籍作者关系 admin 接口 ## 基本信息 - 模块:book - 资源:书籍作者关系 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookAuthorRelation` +- 搜索入参:`bookReq.BookAuthorRelationSearch` +- 详情响应:`bookRes.BookAuthorRelationResponse` +- 列表项:`bookRes.BookAuthorRelationListItem` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookAuthorRelation` | `CreateBookAuthorRelation` | `CreateBookAuthorRelation` | -| 单删 | `DELETE` | `/book/deleteBookAuthorRelation` | `DeleteBookAuthorRelation` | `DeleteBookAuthorRelation` | -| 批量删除 | `DELETE` | `/book/deleteBookAuthorRelationByIds` | `DeleteBookAuthorRelationByIds` | `DeleteBookAuthorRelationByIds` | -| 更新 | `PUT` | `/book/updateBookAuthorRelation` | `UpdateBookAuthorRelation` | `UpdateBookAuthorRelation` | -| 详情 | `GET` | `/book/findBookAuthorRelation` | `FindBookAuthorRelation` | `GetBookAuthorRelation` | -| 分页列表 | `GET` | `/book/getBookAuthorRelationList` | `GetBookAuthorRelationList` | `GetBookAuthorRelationInfoList` | +### 创建书籍作者关系 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookAuthorRelation` +- Handler:`BookAuthorRelationApi.CreateBookAuthorRelation` +- Service:`BookAuthorRelationService.CreateBookAuthorRelation` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookAuthorRelation`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookAuthorRelationSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookAuthorRelationResponse`。 +#### Request Body `book.BookAuthorRelation` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| bookId | uint | 是 | `> 0` | 关联书籍 ID | +| authorId | uint | 是 | `> 0` | 关联作者 ID | +| authorSort | int | 否 | 未传或为 `0` 时默认 `1`;最终值必须 `> 0` | 展示顺序 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传 `id/createdAt/updatedAt`。 +- 创建前必须校验 `bookId + authorId` 未被占用。 + +### 删除书籍作者关系 + +- Method:`DELETE` +- Path:`/book/deleteBookAuthorRelation` +- Handler:`BookAuthorRelationApi.DeleteBookAuthorRelation` +- Service:`BookAuthorRelationService.DeleteBookAuthorRelation` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 关系 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除书籍作者关系 + +- Method:`DELETE` +- Path:`/book/deleteBookAuthorRelationByIds` +- Handler:`BookAuthorRelationApi.DeleteBookAuthorRelationByIds` +- Service:`BookAuthorRelationService.DeleteBookAuthorRelationByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 关系 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 关系 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新书籍作者关系 + +- Method:`PUT` +- Path:`/book/updateBookAuthorRelation` +- Handler:`BookAuthorRelationApi.UpdateBookAuthorRelation` +- Service:`BookAuthorRelationService.UpdateBookAuthorRelation` +- 审计:是 + +#### Request Body `book.BookAuthorRelation` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 关系 ID | +| bookId | uint | 是 | `> 0` | 关联书籍 ID | +| authorId | uint | 是 | `> 0` | 关联作者 ID | +| authorSort | int | 是 | `> 0` | 展示顺序 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传 `createdAt/updatedAt`。 +- 更新前必须校验 `bookId + authorId` 未被其他记录占用。 +- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。 + +### 查询书籍作者关系详情 + +- Method:`GET` +- Path:`/book/findBookAuthorRelation` +- Handler:`BookAuthorRelationApi.FindBookAuthorRelation` +- Service:`BookAuthorRelationService.GetBookAuthorRelation` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 关系 ID | + +#### Response `bookRes.BookAuthorRelationResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookAuthorRelation | object | 关系实体 | +| bookAuthorRelation.id | uint | 关系 ID | +| bookAuthorRelation.bookId | uint | 书籍 ID | +| bookAuthorRelation.authorId | uint | 作者 ID | +| bookAuthorRelation.authorSort | int | 作者展示顺序 | +| bookAuthorRelation.createdAt | string | 创建时间 | +| bookAuthorRelation.updatedAt | string | 更新时间 | + +### 分页查询书籍作者关系列表 + +- Method:`GET` +- Path:`/book/getBookAuthorRelationList` +- Handler:`BookAuthorRelationApi.GetBookAuthorRelationList` +- Service:`BookAuthorRelationService.GetBookAuthorRelationInfoList` +- 审计:否 + +#### Request Query `bookReq.BookAuthorRelationSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| bookId | uint | 否 | `> 0` | 按书籍 ID 精确筛选 | +| authorId | uint | 否 | `> 0` | 按作者 ID 精确筛选 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `bookRes.BookAuthorRelationListItem` 列表 | +| list[].id | uint | 关系 ID | +| list[].bookId | uint | 书籍 ID | +| list[].authorId | uint | 作者 ID | +| list[].authorSort | int | 作者展示顺序 | +| list[].authorName | string | 作者名称展示字段 | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`bookId asc, authorSort asc, id desc`。 + +## 规则 + +- 默认鉴权为 `PrivateGroup`,需要 `JWT + Casbin`。 +- `bookId + authorId` 唯一,对应数据库唯一索引 `uk_book_author_relation_book_id_author_id`。 +- `authorSort` 必须大于 `0`。 +- 创建时 `authorSort` 未传或为 `0` 时默认 `1`。 +- 删除策略为硬删。 diff --git a/server/.ai-specs/doc-api/admin/book_chapter.md b/server/.ai-specs/doc-api/admin/book_chapter.md index 1d5fdd8..74f3e2d 100644 --- a/server/.ai-specs/doc-api/admin/book_chapter.md +++ b/server/.ai-specs/doc-api/admin/book_chapter.md @@ -1,29 +1,201 @@ -# 书籍章节 admin 接口 +# 书籍章节 admin 接口 ## 基本信息 - 模块:book -- 资源:章节 +- 资源:书籍章节 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookChapter` +- 搜索入参:`bookReq.BookChapterSearch` +- 详情响应:`bookRes.BookChapterResponse` +- 列表项:`book.BookChapter` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookChapter` | `CreateBookChapter` | `CreateBookChapter` | -| 单删 | `DELETE` | `/book/deleteBookChapter` | `DeleteBookChapter` | `DeleteBookChapter` | -| 批量删除 | `DELETE` | `/book/deleteBookChapterByIds` | `DeleteBookChapterByIds` | `DeleteBookChapterByIds` | -| 更新 | `PUT` | `/book/updateBookChapter` | `UpdateBookChapter` | `UpdateBookChapter` | -| 详情 | `GET` | `/book/findBookChapter` | `FindBookChapter` | `GetBookChapter` | -| 分页列表 | `GET` | `/book/getBookChapterList` | `GetBookChapterList` | `GetBookChapterInfoList` | +### 创建书籍章节 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookChapter` +- Handler:`BookChapterApi.CreateBookChapter` +- Service:`BookChapterService.CreateBookChapter` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookChapter`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookChapterSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookChapterResponse`。 +#### 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.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 | `book.BookChapter` 列表 | +| list[].id | uint | 章节 ID | +| list[].createdAt | string | 创建时间 | +| list[].updatedAt | string | 更新时间 | +| list[].bookId | uint | 所属书籍 ID | +| 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`。 + +## 规则 + +- 章节使用硬删;删除后数据库不保留软删标记。 +- `bookId + chapterNo` 是章节唯一约束;新增或更新时不能与同书已有章节冲突。 +- `chapterNo` 必须大于 `0`。 +- `totalLines` 不能小于 `0`;`isReadable=true` 时 `totalLines` 必须大于 `0`。 +- 创建、更新复用实体 `book.BookChapter`;列表查询复用 `bookReq.BookChapterSearch`;详情返回 `bookRes.BookChapterResponse`。 diff --git a/server/.ai-specs/doc-api/admin/book_comment.md b/server/.ai-specs/doc-api/admin/book_comment.md index c290381..3915b85 100644 --- a/server/.ai-specs/doc-api/admin/book_comment.md +++ b/server/.ai-specs/doc-api/admin/book_comment.md @@ -1,29 +1,199 @@ -# 书籍评论 admin 接口 +# 书籍评论 admin 接口 ## 基本信息 - 模块:book -- 资源:评论 +- 资源:书籍评论 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookComment` +- 搜索入参:`bookReq.BookCommentSearch` +- 详情响应:`bookRes.BookCommentResponse` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookComment` | `CreateBookComment` | `CreateBookComment` | -| 单删 | `DELETE` | `/book/deleteBookComment` | `DeleteBookComment` | `DeleteBookComment` | -| 批量删除 | `DELETE` | `/book/deleteBookCommentByIds` | `DeleteBookCommentByIds` | `DeleteBookCommentByIds` | -| 更新 | `PUT` | `/book/updateBookComment` | `UpdateBookComment` | `UpdateBookComment` | -| 详情 | `GET` | `/book/findBookComment` | `FindBookComment` | `GetBookComment` | -| 分页列表 | `GET` | `/book/getBookCommentList` | `GetBookCommentList` | `GetBookCommentInfoList` | +### 创建书籍评论 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookComment` +- Handler:`BookCommentApi.CreateBookComment` +- Service:`BookCommentService.CreateBookComment` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookComment`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookCommentSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookCommentResponse`。 +#### Request Body `book.BookComment` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| memberUserId | uint | 是 | 数据库非空 | 评论用户的会员 ID | +| bookId | uint | 是 | 数据库非空 | 所属书籍 ID | +| chapterId | uint | 否 | 默认 `0`;`>= 0` | 评论目标章节 ID,`0` 表示整本书 | +| lineIndex | int | 否 | 默认 `0`;`>= 0`;整书评论时必须为 `0` | 评论目标文本行下标,`0` 表示整章或整本书 | +| content | string | 是 | 数据库非空 | 评论正文内容 | +| likeCount | int64 | 否 | 默认 `0`;`>= 0` | 评论点赞聚合值 | +| commentStatus | string | 否 | 默认 `normal`;仅允许 `normal/hidden` | 评论状态字典值,对应 `book_comment_status` | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `chapterId=0` 表示整书评论,此时 `lineIndex` 必须为 `0`。 +- `chapterId>0` 时允许 `lineIndex>=0`,其中 `lineIndex=0` 表示整章评论。 + +### 删除书籍评论 + +- Method:`DELETE` +- Path:`/book/deleteBookComment` +- Handler:`BookCommentApi.DeleteBookComment` +- Service:`BookCommentService.DeleteBookComment` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 评论 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除书籍评论 + +- Method:`DELETE` +- Path:`/book/deleteBookCommentByIds` +- Handler:`BookCommentApi.DeleteBookCommentByIds` +- Service:`BookCommentService.DeleteBookCommentByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均为主键 ID | 评论 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均为主键 ID | 评论 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新书籍评论 + +- Method:`PUT` +- Path:`/book/updateBookComment` +- Handler:`BookCommentApi.UpdateBookComment` +- Service:`BookCommentService.UpdateBookComment` +- 审计:是 + +#### Request Body `book.BookComment` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 评论 ID | +| memberUserId | uint | 是 | 数据库非空 | 评论用户的会员 ID | +| bookId | uint | 是 | 数据库非空 | 所属书籍 ID | +| chapterId | uint | 否 | 默认 `0`;`>= 0` | 评论目标章节 ID,`0` 表示整本书 | +| lineIndex | int | 否 | 默认 `0`;`>= 0`;整书评论时必须为 `0` | 评论目标文本行下标,`0` 表示整章或整本书 | +| content | string | 是 | 数据库非空 | 评论正文内容 | +| likeCount | int64 | 否 | 默认 `0`;`>= 0` | 评论点赞聚合值 | +| commentStatus | string | 否 | 默认 `normal`;仅允许 `normal/hidden` | 评论状态字典值,对应 `book_comment_status` | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。 +- `chapterId=0` 表示整书评论,此时 `lineIndex` 必须为 `0`。 +- `chapterId>0` 时允许 `lineIndex>=0`,其中 `lineIndex=0` 表示整章评论。 + +### 查询书籍评论详情 + +- Method:`GET` +- Path:`/book/findBookComment` +- Handler:`BookCommentApi.FindBookComment` +- Service:`BookCommentService.GetBookComment` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 评论 ID | + +#### Response `bookRes.BookCommentResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookComment | object | 评论实体 | +| bookComment.id | uint | 评论 ID | +| bookComment.createdAt | time | 创建时间 | +| bookComment.updatedAt | time | 更新时间 | +| bookComment.memberUserId | uint | 评论用户的会员 ID | +| bookComment.bookId | uint | 所属书籍 ID | +| bookComment.chapterId | uint | 评论目标章节 ID,`0` 表示整本书 | +| bookComment.lineIndex | int | 评论目标文本行下标,`0` 表示整章或整本书 | +| bookComment.content | string | 评论正文内容 | +| bookComment.likeCount | int64 | 评论点赞聚合值 | +| bookComment.commentStatus | string | 评论状态字典值,对应 `book_comment_status` | + +### 分页查询书籍评论列表 + +- Method:`GET` +- Path:`/book/getBookCommentList` +- Handler:`BookCommentApi.GetBookCommentList` +- Service:`BookCommentService.GetBookCommentInfoList` +- 审计:否 + +#### Request Query `bookReq.BookCommentSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| memberUserId | uint | 否 | 精确匹配 | 评论用户的会员 ID | +| bookId | uint | 否 | 精确匹配 | 所属书籍 ID | +| chapterId | uint | 否 | 精确匹配 | 评论目标章节 ID,`0` 表示整本书 | +| commentStatus | string | 否 | 仅允许 `normal/hidden` | 评论状态字典值,对应 `book_comment_status` | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.BookComment` 列表 | +| list[].id | uint | 评论 ID | +| list[].createdAt | time | 创建时间 | +| list[].updatedAt | time | 更新时间 | +| list[].memberUserId | uint | 评论用户的会员 ID | +| list[].bookId | uint | 所属书籍 ID | +| list[].chapterId | uint | 评论目标章节 ID,`0` 表示整本书 | +| list[].lineIndex | int | 评论目标文本行下标,`0` 表示整章或整本书 | +| list[].content | string | 评论正文内容 | +| list[].likeCount | int64 | 评论点赞聚合值 | +| list[].commentStatus | string | 评论状态字典值,对应 `book_comment_status` | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 + +## 规则 + +- `commentStatus` 必须符合 `book_comment_status`:`normal` 正常,`hidden` 隐藏。 +- `lineIndex/likeCount` 不能小于 `0`。 +- 整书评论 `chapterId=0` 时 `lineIndex` 必须为 `0`。 +- 删除策略为硬删。 diff --git a/server/.ai-specs/doc-api/admin/book_comment_like_record.md b/server/.ai-specs/doc-api/admin/book_comment_like_record.md index ccd10dc..9f6ea94 100644 --- a/server/.ai-specs/doc-api/admin/book_comment_like_record.md +++ b/server/.ai-specs/doc-api/admin/book_comment_like_record.md @@ -1,29 +1,180 @@ -# 评论点赞记录 admin 接口 +# 评论点赞记录 admin 接口 ## 基本信息 - 模块:book - 资源:评论点赞记录 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookCommentLikeRecord` +- 搜索入参:`bookReq.BookCommentLikeRecordSearch` +- 详情响应:`bookRes.BookCommentLikeRecordResponse` +- 列表项:`book.BookCommentLikeRecord` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookCommentLikeRecord` | `CreateBookCommentLikeRecord` | `CreateBookCommentLikeRecord` | -| 单删 | `DELETE` | `/book/deleteBookCommentLikeRecord` | `DeleteBookCommentLikeRecord` | `DeleteBookCommentLikeRecord` | -| 批量删除 | `DELETE` | `/book/deleteBookCommentLikeRecordByIds` | `DeleteBookCommentLikeRecordByIds` | `DeleteBookCommentLikeRecordByIds` | -| 更新 | `PUT` | `/book/updateBookCommentLikeRecord` | `UpdateBookCommentLikeRecord` | `UpdateBookCommentLikeRecord` | -| 详情 | `GET` | `/book/findBookCommentLikeRecord` | `FindBookCommentLikeRecord` | `GetBookCommentLikeRecord` | -| 分页列表 | `GET` | `/book/getBookCommentLikeRecordList` | `GetBookCommentLikeRecordList` | `GetBookCommentLikeRecordInfoList` | +### 创建评论点赞记录 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookCommentLikeRecord` +- Handler:`BookCommentLikeRecordApi.CreateBookCommentLikeRecord` +- Service:`BookCommentLikeRecordService.CreateBookCommentLikeRecord` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookCommentLikeRecord`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookCommentLikeRecordSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookCommentLikeRecordResponse`。 +#### Request Body `book.BookCommentLikeRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| commentId | uint | 是 | `> 0`;与 `memberUserId` 组成唯一约束 | 被点赞评论 ID | +| memberUserId | uint | 是 | `> 0`;与 `commentId` 组成唯一约束 | 点赞用户的会员 ID | +| likedAt | string | 否 | RFC3339 时间;不传使用数据库默认 `CURRENT_TIMESTAMP` | 点赞发生时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `commentId + memberUserId` 必须唯一;重复创建应返回失败,不得生成重复有效点赞关系。 + +### 删除评论点赞记录 + +- Method:`DELETE` +- Path:`/book/deleteBookCommentLikeRecord` +- Handler:`BookCommentLikeRecordApi.DeleteBookCommentLikeRecord` +- Service:`BookCommentLikeRecordService.DeleteBookCommentLikeRecord` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 点赞记录 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除评论点赞记录 + +- Method:`DELETE` +- Path:`/book/deleteBookCommentLikeRecordByIds` +- Handler:`BookCommentLikeRecordApi.DeleteBookCommentLikeRecordByIds` +- Service:`BookCommentLikeRecordService.DeleteBookCommentLikeRecordByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 点赞记录 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 点赞记录 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新评论点赞记录 + +- Method:`PUT` +- Path:`/book/updateBookCommentLikeRecord` +- Handler:`BookCommentLikeRecordApi.UpdateBookCommentLikeRecord` +- Service:`BookCommentLikeRecordService.UpdateBookCommentLikeRecord` +- 审计:是 + +#### Request Body `book.BookCommentLikeRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 点赞记录 ID | +| commentId | uint | 是 | `> 0`;与 `memberUserId` 组成唯一约束 | 被点赞评论 ID | +| memberUserId | uint | 是 | `> 0`;与 `commentId` 组成唯一约束 | 点赞用户的会员 ID | +| likedAt | string | 是 | RFC3339 时间;不能为空 | 点赞发生时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新为实体全量保存,前端必须传完整可编辑实体,避免字段被零值覆盖。 +- 更新后的 `commentId + memberUserId` 必须继续满足唯一约束。 + +### 查询评论点赞记录详情 + +- Method:`GET` +- Path:`/book/findBookCommentLikeRecord` +- Handler:`BookCommentLikeRecordApi.FindBookCommentLikeRecord` +- Service:`BookCommentLikeRecordService.GetBookCommentLikeRecord` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 点赞记录 ID | + +#### Response `bookRes.BookCommentLikeRecordResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookCommentLikeRecord | object | 点赞记录实体 | +| bookCommentLikeRecord.id | uint | 点赞记录 ID | +| bookCommentLikeRecord.createdAt | string | 创建时间 | +| bookCommentLikeRecord.updatedAt | string | 更新时间 | +| bookCommentLikeRecord.commentId | uint | 被点赞评论 ID | +| bookCommentLikeRecord.memberUserId | uint | 点赞用户的会员 ID | +| bookCommentLikeRecord.likedAt | string | 点赞发生时间 | + +### 分页查询评论点赞记录列表 + +- Method:`GET` +- Path:`/book/getBookCommentLikeRecordList` +- Handler:`BookCommentLikeRecordApi.GetBookCommentLikeRecordList` +- Service:`BookCommentLikeRecordService.GetBookCommentLikeRecordInfoList` +- 审计:否 + +#### Request Query `bookReq.BookCommentLikeRecordSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| commentId | uint | 否 | `> 0` | 按被点赞评论 ID 筛选 | +| memberUserId | uint | 否 | `> 0` | 按点赞用户的会员 ID 筛选 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.BookCommentLikeRecord` 列表 | +| list[].id | uint | 点赞记录 ID | +| list[].createdAt | string | 创建时间 | +| list[].updatedAt | string | 更新时间 | +| list[].commentId | uint | 被点赞评论 ID | +| list[].memberUserId | uint | 点赞用户的会员 ID | +| list[].likedAt | string | 点赞发生时间 | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 + +## 规则 + +- 该资源承载用户对评论的有效点赞关系,后台 CRUD 仅维护记录本身。 +- `commentId + memberUserId` 是幂等判断边界,必须保持唯一。 +- 删除策略为硬删;删除后该点赞关系不再存在。 +- 时间字段以接口实际 JSON 序列化格式为准,业务语义为 `liked_at`。 diff --git a/server/.ai-specs/doc-api/admin/book_favorite_record.md b/server/.ai-specs/doc-api/admin/book_favorite_record.md index 7e77d94..5ac0b2e 100644 --- a/server/.ai-specs/doc-api/admin/book_favorite_record.md +++ b/server/.ai-specs/doc-api/admin/book_favorite_record.md @@ -1,29 +1,180 @@ -# 书籍收藏记录 admin 接口 +# 书籍收藏记录 admin 接口 ## 基本信息 - 模块:book -- 资源:收藏记录 +- 资源:书籍收藏记录 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookFavoriteRecord` +- 搜索入参:`bookReq.BookFavoriteRecordSearch` +- 详情响应:`bookRes.BookFavoriteRecordResponse` +- 列表项:`book.BookFavoriteRecord` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookFavoriteRecord` | `CreateBookFavoriteRecord` | `CreateBookFavoriteRecord` | -| 单删 | `DELETE` | `/book/deleteBookFavoriteRecord` | `DeleteBookFavoriteRecord` | `DeleteBookFavoriteRecord` | -| 批量删除 | `DELETE` | `/book/deleteBookFavoriteRecordByIds` | `DeleteBookFavoriteRecordByIds` | `DeleteBookFavoriteRecordByIds` | -| 更新 | `PUT` | `/book/updateBookFavoriteRecord` | `UpdateBookFavoriteRecord` | `UpdateBookFavoriteRecord` | -| 详情 | `GET` | `/book/findBookFavoriteRecord` | `FindBookFavoriteRecord` | `GetBookFavoriteRecord` | -| 分页列表 | `GET` | `/book/getBookFavoriteRecordList` | `GetBookFavoriteRecordList` | `GetBookFavoriteRecordInfoList` | +### 创建书籍收藏记录 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookFavoriteRecord` +- Handler:`BookFavoriteRecordApi.CreateBookFavoriteRecord` +- Service:`BookFavoriteRecordService.CreateBookFavoriteRecord` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookFavoriteRecord`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookFavoriteRecordSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookFavoriteRecordResponse`。 +#### Request Body `book.BookFavoriteRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| memberUserId | uint | 是 | `> 0`;与 `bookId` 组成唯一约束 | 收藏用户的会员 ID | +| bookId | uint | 是 | `> 0`;与 `memberUserId` 组成唯一约束 | 收藏书籍 ID | +| favoritedAt | string | 否 | RFC3339 时间;不传使用数据库默认 `CURRENT_TIMESTAMP` | 收藏发生时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- 同一 `memberUserId + bookId` 只能存在一条收藏记录。 + +### 删除书籍收藏记录 + +- Method:`DELETE` +- Path:`/book/deleteBookFavoriteRecord` +- Handler:`BookFavoriteRecordApi.DeleteBookFavoriteRecord` +- Service:`BookFavoriteRecordService.DeleteBookFavoriteRecord` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 收藏记录 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除书籍收藏记录 + +- Method:`DELETE` +- Path:`/book/deleteBookFavoriteRecordByIds` +- Handler:`BookFavoriteRecordApi.DeleteBookFavoriteRecordByIds` +- Service:`BookFavoriteRecordService.DeleteBookFavoriteRecordByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 收藏记录 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 收藏记录 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新书籍收藏记录 + +- Method:`PUT` +- Path:`/book/updateBookFavoriteRecord` +- Handler:`BookFavoriteRecordApi.UpdateBookFavoriteRecord` +- Service:`BookFavoriteRecordService.UpdateBookFavoriteRecord` +- 审计:是 + +#### Request Body `book.BookFavoriteRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 收藏记录 ID | +| memberUserId | uint | 是 | `> 0`;与 `bookId` 组成唯一约束 | 收藏用户的会员 ID | +| bookId | uint | 是 | `> 0`;与 `memberUserId` 组成唯一约束 | 收藏书籍 ID | +| favoritedAt | string | 是 | RFC3339 时间 | 收藏发生时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。 +- 同一 `memberUserId + bookId` 只能存在一条收藏记录。 + +### 查询书籍收藏记录详情 + +- Method:`GET` +- Path:`/book/findBookFavoriteRecord` +- Handler:`BookFavoriteRecordApi.FindBookFavoriteRecord` +- Service:`BookFavoriteRecordService.GetBookFavoriteRecord` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 收藏记录 ID | + +#### Response `bookRes.BookFavoriteRecordResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookFavoriteRecord | object | 收藏记录实体 | +| bookFavoriteRecord.id | uint | 收藏记录 ID | +| bookFavoriteRecord.createdAt | string | 创建时间 | +| bookFavoriteRecord.updatedAt | string | 更新时间 | +| bookFavoriteRecord.memberUserId | uint | 收藏用户的会员 ID | +| bookFavoriteRecord.bookId | uint | 收藏书籍 ID | +| bookFavoriteRecord.favoritedAt | string | 收藏发生时间 | + +### 分页查询书籍收藏记录列表 + +- Method:`GET` +- Path:`/book/getBookFavoriteRecordList` +- Handler:`BookFavoriteRecordApi.GetBookFavoriteRecordList` +- Service:`BookFavoriteRecordService.GetBookFavoriteRecordInfoList` +- 审计:否 + +#### Request Query `bookReq.BookFavoriteRecordSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| memberUserId | uint | 否 | `> 0` | 按收藏用户的会员 ID 精确筛选 | +| bookId | uint | 否 | `> 0` | 按收藏书籍 ID 精确筛选 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.BookFavoriteRecord` 列表 | +| list[].id | uint | 收藏记录 ID | +| list[].createdAt | string | 创建时间 | +| list[].updatedAt | string | 更新时间 | +| list[].memberUserId | uint | 收藏用户的会员 ID | +| list[].bookId | uint | 收藏书籍 ID | +| list[].favoritedAt | string | 收藏发生时间 | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 + +## 规则 + +- admin 端书籍收藏记录接口统一挂载到 `PrivateGroup`,需要后台 `JWT + Casbin` 权限。 +- 写操作挂载 `middleware.OperationRecord()`;详情和分页列表不挂操作审计。 +- `memberUserId + bookId` 唯一约束由数据库索引 `uk_book_favorite_record_member_user_id_book_id` 保证。 +- 删除策略为硬删,实体使用 `HardDeleteModel`,不维护 `deletedAt`。 diff --git a/server/.ai-specs/doc-api/admin/book_read_record.md b/server/.ai-specs/doc-api/admin/book_read_record.md index f54c703..684c736 100644 --- a/server/.ai-specs/doc-api/admin/book_read_record.md +++ b/server/.ai-specs/doc-api/admin/book_read_record.md @@ -1,29 +1,199 @@ -# 书籍阅读记录 admin 接口 +# 书籍阅读记录 admin 接口 ## 基本信息 - 模块:book -- 资源:阅读记录 +- 资源:书籍阅读记录 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookReadRecord` +- 搜索入参:`bookReq.BookReadRecordSearch` +- 详情响应:`bookRes.BookReadRecordResponse` +- 列表项:`book.BookReadRecord` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookReadRecord` | `CreateBookReadRecord` | `CreateBookReadRecord` | -| 单删 | `DELETE` | `/book/deleteBookReadRecord` | `DeleteBookReadRecord` | `DeleteBookReadRecord` | -| 批量删除 | `DELETE` | `/book/deleteBookReadRecordByIds` | `DeleteBookReadRecordByIds` | `DeleteBookReadRecordByIds` | -| 更新 | `PUT` | `/book/updateBookReadRecord` | `UpdateBookReadRecord` | `UpdateBookReadRecord` | -| 详情 | `GET` | `/book/findBookReadRecord` | `FindBookReadRecord` | `GetBookReadRecord` | -| 分页列表 | `GET` | `/book/getBookReadRecordList` | `GetBookReadRecordList` | `GetBookReadRecordInfoList` | +### 创建书籍阅读记录 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookReadRecord` +- Handler:`BookReadRecordApi.CreateBookReadRecord` +- Service:`BookReadRecordService.CreateBookReadRecord` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookReadRecord`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookReadRecordSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookReadRecordResponse`。 +#### Request Body `book.BookReadRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| memberUserId | uint | 是 | `> 0` | 阅读用户的会员 ID | +| bookId | uint | 是 | `> 0` | 所属书籍 ID | +| bookTitleSnapshot | string | 是 | 非空,最大 `255` | 阅读书籍标题快照 | +| readProgress | float | 否 | 默认 `0.00`,范围 `0-100` | 阅读进度百分比 | +| chapterId | uint | 是 | `> 0` | 当前续读章节 ID | +| lineIndex | int | 是 | `> 0` | 当前续读文本行下标,正文首行为 `1` | +| lastReadAt | string | 否 | 不传使用数据库默认时间 | 最近一次阅读时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `memberUserId + bookId` 唯一,同一用户同一本书只保留一条最新阅读记录。 +- `readProgress/chapterId/lineIndex` 必须通过 Service 校验后写入。 + +### 删除书籍阅读记录 + +- Method:`DELETE` +- Path:`/book/deleteBookReadRecord` +- Handler:`BookReadRecordApi.DeleteBookReadRecord` +- Service:`BookReadRecordService.DeleteBookReadRecord` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 阅读记录 ID | + +#### Response + +- `response.Response{msg}` + +### 批量删除书籍阅读记录 + +- Method:`DELETE` +- Path:`/book/deleteBookReadRecordByIds` +- Handler:`BookReadRecordApi.DeleteBookReadRecordByIds` +- Service:`BookReadRecordService.DeleteBookReadRecordByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 阅读记录 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 阅读记录 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 + +### 更新书籍阅读记录 + +- Method:`PUT` +- Path:`/book/updateBookReadRecord` +- Handler:`BookReadRecordApi.UpdateBookReadRecord` +- Service:`BookReadRecordService.UpdateBookReadRecord` +- 审计:是 + +#### Request Body `book.BookReadRecord` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 阅读记录 ID | +| memberUserId | uint | 是 | `> 0` | 阅读用户的会员 ID | +| bookId | uint | 是 | `> 0` | 所属书籍 ID | +| bookTitleSnapshot | string | 是 | 非空,最大 `255` | 阅读书籍标题快照 | +| readProgress | float | 是 | 范围 `0-100` | 阅读进度百分比 | +| chapterId | uint | 是 | `> 0` | 当前续读章节 ID | +| lineIndex | int | 是 | `> 0` | 当前续读文本行下标,正文首行为 `1` | +| lastReadAt | string | 是 | 有效时间 | 最近一次阅读时间 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 更新为实体全量保存,前端应传完整可编辑实体,避免字段被零值覆盖。 +- `memberUserId + bookId` 唯一,同一用户同一本书不能更新成重复记录。 +- `readProgress/chapterId/lineIndex` 必须通过 Service 校验后写入。 + +### 查询书籍阅读记录详情 + +- Method:`GET` +- Path:`/book/findBookReadRecord` +- Handler:`BookReadRecordApi.FindBookReadRecord` +- Service:`BookReadRecordService.GetBookReadRecord` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 阅读记录 ID | + +#### Response `BookReadRecordResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookReadRecord | object | 阅读记录实体 | +| bookReadRecord.id | uint | 阅读记录 ID | +| bookReadRecord.createdAt | string | 创建时间 | +| bookReadRecord.updatedAt | string | 更新时间 | +| bookReadRecord.memberUserId | uint | 阅读用户的会员 ID | +| bookReadRecord.bookId | uint | 所属书籍 ID | +| bookReadRecord.bookTitleSnapshot | string | 阅读书籍标题快照 | +| bookReadRecord.readProgress | float | 阅读进度百分比 | +| bookReadRecord.chapterId | uint | 当前续读章节 ID | +| bookReadRecord.lineIndex | int | 当前续读文本行下标,正文首行为 `1` | +| bookReadRecord.lastReadAt | string | 最近一次阅读时间 | + +### 分页查询书籍阅读记录列表 + +- Method:`GET` +- Path:`/book/getBookReadRecordList` +- Handler:`BookReadRecordApi.GetBookReadRecordList` +- Service:`BookReadRecordService.GetBookReadRecordInfoList` +- 审计:否 + +#### Request Query `bookReq.BookReadRecordSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| memberUserId | uint | 否 | `> 0` | 按阅读用户的会员 ID 筛选 | +| bookId | uint | 否 | `> 0` | 按所属书籍 ID 筛选 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.BookReadRecord` 列表 | +| list[].id | uint | 阅读记录 ID | +| list[].createdAt | string | 创建时间 | +| list[].updatedAt | string | 更新时间 | +| list[].memberUserId | uint | 阅读用户的会员 ID | +| list[].bookId | uint | 所属书籍 ID | +| list[].bookTitleSnapshot | string | 阅读书籍标题快照 | +| list[].readProgress | float | 阅读进度百分比 | +| list[].chapterId | uint | 当前续读章节 ID | +| list[].lineIndex | int | 当前续读文本行下标,正文首行为 `1` | +| list[].lastReadAt | string | 最近一次阅读时间 | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`last_read_at desc, id desc`。 + +## 规则 + +- admin 端阅读记录 CRUD 默认挂载到 `PrivateGroup`,统一需要后台 `JWT + Casbin` 权限。 +- 写操作启用 `OperationRecord`;读操作不启用操作审计。 +- 删除策略为硬删,删除后不保留软删标记。 +- `memberUserId + bookId` 是业务唯一键。 +- `readProgress` 范围为 `0-100`;`chapterId` 必须大于 `0`;`lineIndex` 必须大于 `0`。 diff --git a/server/.ai-specs/doc-api/admin/book_series.md b/server/.ai-specs/doc-api/admin/book_series.md index 9a1ceb3..3151f69 100644 --- a/server/.ai-specs/doc-api/admin/book_series.md +++ b/server/.ai-specs/doc-api/admin/book_series.md @@ -1,29 +1,193 @@ -# 书籍系列 admin 接口 +# 书籍系列 admin 接口 ## 基本信息 - 模块:book -- 资源:系列 +- 资源:书籍系列 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:创建、更新、单删、批量删除写操作启用 `OperationRecord` -- 路由前缀:`/book` +- 鉴权:`PrivateGroup`,需要 `JWT + Casbin` +- 审计:创建、更新、单删、批量删除启用 `OperationRecord` +- 前缀:`/book` +- 实体模型:`book.BookSeries` +- 搜索入参:`bookReq.BookSeriesSearch` +- 详情响应:`bookRes.BookSeriesResponse` +- 列表项:`book.BookSeries` +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:硬删 -## 默认 CRUD +## CRUD -| 动作 | Method | 路径 | API 方法 | Service 方法 | -|:---|:---|:---|:---|:---| -| 创建 | `POST` | `/book/createBookSeries` | `CreateBookSeries` | `CreateBookSeries` | -| 单删 | `DELETE` | `/book/deleteBookSeries` | `DeleteBookSeries` | `DeleteBookSeries` | -| 批量删除 | `DELETE` | `/book/deleteBookSeriesByIds` | `DeleteBookSeriesByIds` | `DeleteBookSeriesByIds` | -| 更新 | `PUT` | `/book/updateBookSeries` | `UpdateBookSeries` | `UpdateBookSeries` | -| 详情 | `GET` | `/book/findBookSeries` | `FindBookSeries` | `GetBookSeries` | -| 分页列表 | `GET` | `/book/getBookSeriesList` | `GetBookSeriesList` | `GetBookSeriesInfoList` | +### 创建书籍系列 -## 参数与返回 +- Method:`POST` +- Path:`/book/createBookSeries` +- Handler:`BookSeriesApi.CreateBookSeries` +- Service:`BookSeriesService.CreateBookSeries` +- 审计:是 -- 创建、更新:`body` 使用 `book.BookSeries`。 -- 单删、详情:`query id`。 -- 批量删除:`query ids[]`。 -- 分页列表:`query` 使用 `bookReq.BookSeriesSearch`,返回 `response.PageResult`。 -- 详情返回:`bookRes.BookSeriesResponse`。 +#### Request Body `book.BookSeries` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| name | string | 是 | 非空,最大长度 `128` | 系列名称 | +| coverUrl | string | 否 | 最大长度 `500` | 系列封面图片 URL | +| intro | string | 否 | 文本 | 系列简介 | +| isEnabled | bool | 否 | 默认 `true` | 系列是否启用 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- `name` 写入 `book_series.name`,数据库要求非空。 +- `isEnabled` 未传时按数据库默认值 `true` 落库。 + +### 删除书籍系列 + +- Method:`DELETE` +- Path:`/book/deleteBookSeries` +- Handler:`BookSeriesApi.DeleteBookSeries` +- Service:`BookSeriesService.DeleteBookSeries` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 系列 ID | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 删除策略为硬删,删除后记录不再保留在 `book_series` 表。 + +### 批量删除书籍系列 + +- Method:`DELETE` +- Path:`/book/deleteBookSeriesByIds` +- Handler:`BookSeriesApi.DeleteBookSeriesByIds` +- Service:`BookSeriesService.DeleteBookSeriesByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 系列 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 系列 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 +- 删除策略为硬删,删除后记录不再保留在 `book_series` 表。 + +### 更新书籍系列 + +- Method:`PUT` +- Path:`/book/updateBookSeries` +- Handler:`BookSeriesApi.UpdateBookSeries` +- Service:`BookSeriesService.UpdateBookSeries` +- 审计:是 + +#### Request Body `book.BookSeries` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 系列 ID | +| name | string | 是 | 非空,最大长度 `128` | 系列名称 | +| coverUrl | string | 否 | 最大长度 `500` | 系列封面图片 URL | +| intro | string | 否 | 文本 | 系列简介 | +| isEnabled | bool | 否 | `true/false` | 系列是否启用 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- 当前 Service 使用实体 `Save`,前端应传完整可编辑实体,避免未传字段被零值覆盖。 +- `id` 不能为空;`name` 写入 `book_series.name`,数据库要求非空。 + +### 查询书籍系列详情 + +- Method:`GET` +- Path:`/book/findBookSeries` +- Handler:`BookSeriesApi.FindBookSeries` +- Service:`BookSeriesService.GetBookSeries` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 系列 ID | + +#### Response `bookRes.BookSeriesResponse` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| bookSeries | object | 书籍系列实体 | +| bookSeries.id | uint | 系列 ID | +| bookSeries.createdAt | time | 创建时间 | +| bookSeries.updatedAt | time | 更新时间 | +| bookSeries.name | string | 系列名称 | +| bookSeries.coverUrl | string | 系列封面图片 URL | +| bookSeries.intro | string | 系列简介 | +| bookSeries.isEnabled | bool | 系列是否启用 | + +### 分页查询书籍系列列表 + +- Method:`GET` +- Path:`/book/getBookSeriesList` +- Handler:`BookSeriesApi.GetBookSeriesList` +- Service:`BookSeriesService.GetBookSeriesInfoList` +- 审计:否 + +#### Request Query `bookReq.BookSeriesSearch` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| keyword | string | 否 | 模糊匹配 `name` | 关键字 | +| name | string | 否 | 模糊匹配 `name` | 系列名称 | +| isEnabled | bool | 否 | `true/false` | 系列是否启用 | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `book.BookSeries` 列表 | +| list[].id | uint | 系列 ID | +| list[].createdAt | time | 创建时间 | +| list[].updatedAt | time | 更新时间 | +| list[].name | string | 系列名称 | +| list[].coverUrl | string | 系列封面图片 URL | +| list[].intro | string | 系列简介 | +| list[].isEnabled | bool | 系列是否启用 | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:`id desc`。 +- `keyword` 与 `name` 同时传入时,两个条件按 `AND` 叠加过滤。 + +## 规则 + +- admin 端书籍系列 CRUD 挂载在 `PrivateGroup`,统一需要 `JWT + Casbin`。 +- 写操作挂载 `middleware.OperationRecord()`;读操作不挂操作审计。 +- `isEnabled` 当前按实体和 SQL 使用 `bool`:`true` 表示启用,`false` 表示禁用。 +- `book_series.name` 建普通索引,不定义唯一约束;接口不要求系列名称全局唯一。 +- `book_series` 为硬删表,当前接口不提供软删除恢复能力。 diff --git a/server/.ai-specs/doc-api/admin/sys_api.md b/server/.ai-specs/doc-api/admin/sys_api.md index 09e538a..52b67e7 100644 --- a/server/.ai-specs/doc-api/admin/sys_api.md +++ b/server/.ai-specs/doc-api/admin/sys_api.md @@ -5,35 +5,96 @@ - 模块:sys_api - 资源:API 管理 - 端:admin -- 鉴权:挂载 `PrivateGroup`,需要 `JWT + Casbin` -- 操作审计:`/api/enterSyncApi` 启用 `OperationRecord` -- 路由前缀:`/api` +- 鉴权:默认 `PrivateGroup`,需要 `JWT + Casbin`;`/api/freshCasbin` 挂 `PublicGroup` +- 审计:除 `getAllApis/getApiList/getApiRoles/freshCasbin` 外,其余接口启用 `OperationRecord` +- 前缀:`/api` +- 模型:`system.SysApi`、`system.SysIgnoreApi`;搜索:`systemReq.SearchApiParams`;角色绑定:`systemReq.SetApiAuthorities` +- 返回:统一 `response.Response` -## 同步接口 +## 接口 -| 动作 | Method | 路径 | API 方法 | Service 方法 | +| 动作 | Method | 路径 | 入参 | 返回重点 | |:---|:---|:---|:---|:---| -| 预览同步差异 | `GET` | `/api/syncApi` | `SyncApi` | `SyncApi` | -| 确认同步路由 | `POST` | `/api/enterSyncApi` | `EnterSyncApi` | `EnterSyncApi` / `SyncApiToDB` | -| 获取 API 关联角色 | `GET` | `/api/getApiRoles` | `GetApiRoles` | `GetAuthoritiesByApi` | -| 覆盖 API 关联角色 | `POST` | `/api/setApiRoles` | `SetApiRoles` | `SetApiAuthorities` | -| 刷新 Casbin 缓存 | `GET` | `/api/freshCasbin` | `FreshCasbin` | `FreshCasbin` | +| 创建 API | `POST` | `/api/createApi` | `system.SysApi` body | 操作结果 | +| 删除 API | `POST` | `/api/deleteApi` | `system.SysApi` body,仅需 `ID` | 操作结果 | +| 批量删除 API | `DELETE` | `/api/deleteApisByIds` | `request.IdsReq` body | 操作结果 | +| 更新 API | `POST` | `/api/updateApi` | `system.SysApi` body | 操作结果 | +| API 详情 | `POST` | `/api/getApiById` | `request.GetById` body | `api` | +| API 分页列表 | `POST` | `/api/getApiList` | `systemReq.SearchApiParams` body | `response.PageResult` | +| 全量 API 列表 | `POST` | `/api/getAllApis` | 无 | `apis` | +| API 分组 | `GET` | `/api/getApiGroups` | 无 | `groups/apiGroupMap` | +| 预览同步差异 | `GET` | `/api/syncApi` | 无 | `newApis/deleteApis/ignoreApis` | +| 忽略/取消忽略 API | `POST` | `/api/ignoreApi` | `system.SysIgnoreApi` body | 操作结果 | +| 确认同步路由 | `POST` | `/api/enterSyncApi` | 空 body 或 `systemRes.SysSyncApis` | 操作结果 | +| 获取 API 关联角色 | `GET` | `/api/getApiRoles` | `path/method` query | `uint[]` | +| 覆盖 API 关联角色 | `POST` | `/api/setApiRoles` | `systemReq.SetApiAuthorities` body | 操作结果 | +| 刷新 Casbin 缓存 | `GET` | `/api/freshCasbin` | 无 | 操作结果 | -## 参数与返回 +## 请求字段 -- `/api/syncApi`:无入参,返回 `newApis`、`deleteApis`、`ignoreApis`,只预览差异,不写库。 -- `/api/enterSyncApi`:允许空 body 或 `{}`,默认以当前 Gin 路由表 `global.GVA_ROUTERS` 为事实来源同步 `sys_apis`。 -- `/api/enterSyncApi`:兼容旧请求体 `systemRes.SysSyncApis`,传入 `newApis/deleteApis` 时按传入列表写入或删除。 -- `/api/getApiRoles`:query 传入 `path`、`method`,返回该 API 已关联的角色 ID 列表。 -- `/api/setApiRoles`:body 传入 `path`、`method`、`authorityIds`,全量覆盖该 API 的角色权限。 -- `/api/freshCasbin`:无入参,刷新 Casbin 缓存;该接口走公开路由但写入 `sys_ignore_apis`,不作为角色权限点维护。 -- 返回:统一使用 `response.Response`。 +### SysApi Body -## 同步规则 +| 字段 | 类型 | 必填 | 说明 | +|:---|:---|:---:|:---| +| ID | uint | 更新/删除必填 | API ID;来自 `global.GVA_MODEL` 的 JSON 字段 | +| path | string | 创建/更新必填 | API 路径 | +| description | string | 创建/更新必填 | API 中文描述 | +| apiGroup | string | 创建/更新必填 | API 分组 | +| method | string | 创建/更新必填 | HTTP Method | -- 新路由:`sys_apis` 中不存在同一 `path + method` 时自动新增。 -- 已有路由:保留原 `description`、`apiGroup` 等人工维护字段,不自动覆盖。 -- 忽略路由:存在于 `sys_ignore_apis` 的 `path + method` 不写入 `sys_apis`。 -- 失效路由:数据库中存在但当前 Gin 路由表不存在时,从 `sys_apis` 删除,并清理对应 Casbin 权限。 -- 默认管理员角色 `888` 必须具备 `/api/getApiRoles` 与 `/api/setApiRoles` 权限,避免出现“无权分配权限”的系统初始化死锁。 -- 公开接口、仅登录接口不应长期作为角色权限点维护;需要通过 `sys_ignore_apis` 排除。 +### SearchApiParams Body + +| 字段 | 类型 | 必填 | 说明 | +|:---|:---|:---:|:---| +| page/pageSize | int | 是 | 页码/每页数量 | +| path | string | 否 | API 路径筛选 | +| description | string | 否 | API 描述筛选 | +| apiGroup | string | 否 | API 分组筛选 | +| method | string | 否 | HTTP Method 筛选 | +| orderKey | string | 否 | 排序字段 | +| desc | bool | 否 | 是否倒序 | + +### SysIgnoreApi Body + +| 字段 | 类型 | 必填 | 说明 | +|:---|:---|:---:|:---| +| path | string | 是 | API 路径 | +| method | string | 是 | HTTP Method | +| flag | bool | 是 | `true` 写入忽略;`false` 取消忽略 | + +### 其他 Body/Query + +| 场景 | 字段 | 类型 | 必填 | 说明 | +|:---|:---|:---|:---:|:---| +| getApiById | id | int | 是 | API ID;此处使用 `request.GetById`,字段为小写 `id` | +| deleteApisByIds | ids | int[] | 是 | API ID 数组 | +| enterSyncApi | newApis | system.SysApi[] | 否 | 兼容旧请求体;传入时按列表新增 | +| enterSyncApi | deleteApis | system.SysApi[] | 否 | 兼容旧请求体;传入时按列表删除 | +| getApiRoles | path | string | 是 | API 路径 | +| getApiRoles | method | string | 是 | HTTP Method | +| setApiRoles | path | string | 是 | API 路径 | +| setApiRoles | method | string | 是 | HTTP Method | +| setApiRoles | authorityIds | uint[] | 是 | 全量覆盖后的角色 ID 列表 | + +## 响应字段 + +| 场景 | 字段 | 类型 | 说明 | +|:---|:---|:---|:---| +| getApiById | api | object | `system.SysApi` | +| getApiList | list/total/page/pageSize | mixed | 分页结果 | +| getAllApis | apis | array | `system.SysApi` 列表 | +| getApiGroups | groups | string[] | API 分组列表 | +| getApiGroups | apiGroupMap | object | 路径首段到 API 分组映射 | +| syncApi | newApis/deleteApis/ignoreApis | array | 待新增、待删除、已忽略 API | +| getApiRoles | data | uint[] | 角色 ID 列表 | + +## 规则 + +- `path + method` 唯一;创建重复 API 返回失败。 +- `/api/syncApi` 只预览差异,不写库。 +- `/api/enterSyncApi` 空 body 时以 `global.GVA_ROUTERS` 为事实来源同步 `sys_apis`。 +- 同步时新路由按 `path + method` 新增;已有路由保留人工维护的 `description/apiGroup`。 +- `sys_ignore_apis` 中的 `path + method` 不写入 `sys_apis`。 +- 当前路由表不存在的旧 API 从 `sys_apis` 删除,并清理对应 Casbin 权限。 +- `setApiRoles` 为全量覆盖,成功后刷新 Casbin 缓存。 +- 默认管理员角色 `888` 必须具备 `/api/getApiRoles` 与 `/api/setApiRoles` 权限。 diff --git a/server/.ai-specs/doc-dict/book_author_status.md b/server/.ai-specs/doc-dict/book_author_status.md deleted file mode 100644 index 81c6775..0000000 --- a/server/.ai-specs/doc-dict/book_author_status.md +++ /dev/null @@ -1,10 +0,0 @@ -# 作者状态 - -- 模块:book -- 字典编码:`book_author_status` -- 字典类型:`固定值域字典` - -| Label | Value | Sort | Status | Desc | -|:---|:---|:---|:---|:---| -| 启用 | `enabled` | 10 | true | 作者可正常展示,并可被书籍继续关联 | -| 禁用 | `disabled` | 20 | true | 作者不再对外展示,且不应再被新增书籍关联 | diff --git a/server/.ai-specs/doc-dict/common_enabled_status.md b/server/.ai-specs/doc-dict/common_enabled_status.md new file mode 100644 index 0000000..c252059 --- /dev/null +++ b/server/.ai-specs/doc-dict/common_enabled_status.md @@ -0,0 +1,10 @@ +# 通用启用状态 + +- 模块:common +- 字典编码:`common_enabled_status` +- 字典类型:`固定值域字典` + +| Label | Value | Sort | Status | Desc | +|:---|:---|:---|:---|:---| +| 启用 | `enabled` | 10 | true | 业务对象处于启用状态,可按对应业务规则正常使用 | +| 禁用 | `disabled` | 20 | true | 业务对象处于禁用状态,不应再被新增业务关系使用 | diff --git a/server/.ai-specs/doc-sql/book_author.sql b/server/.ai-specs/doc-sql/book_author.sql index f258c30..39d0152 100644 --- a/server/.ai-specs/doc-sql/book_author.sql +++ b/server/.ai-specs/doc-sql/book_author.sql @@ -7,7 +7,7 @@ -- 模型:model/book/book_author.go -- 迁移接入:initialize/gorm_biz.go -- 删除策略:硬删表 --- 状态字典:book_author_status +-- 启用状态字典:common_enabled_status -- 职责:承载书籍作者主体信息,用于作者资料展示、书籍作者关联和后台作者管理。 CREATE TABLE book_author ( @@ -25,7 +25,7 @@ COMMENT ON COLUMN book_author.id IS '主键'; COMMENT ON COLUMN book_author.created_at IS '创建时间'; COMMENT ON COLUMN book_author.updated_at IS '更新时间'; COMMENT ON COLUMN book_author.name IS '作者名称'; -COMMENT ON COLUMN book_author.author_status IS '作者状态字典值,对应 book_author_status'; +COMMENT ON COLUMN book_author.author_status IS '作者启用状态字典值,对应 common_enabled_status'; COMMENT ON COLUMN book_author.intro IS '作者简介'; COMMENT ON COLUMN book_author.cover_url IS '作者封面图片 URL'; diff --git a/server/.ai-specs/prd-draft/book.md b/server/.ai-specs/prd-draft/book.md index 778152c..1d3d09c 100644 --- a/server/.ai-specs/prd-draft/book.md +++ b/server/.ai-specs/prd-draft/book.md @@ -41,7 +41,7 @@ ### 书籍作者表 - 名称:作者名称 -- 状态:字典 `book_author_status` +- 状态:字典 `common_enabled_status` - 简介:作者简介 - 封面图片URL:作者封面地址 diff --git a/server/.ai-specs/sys-specs/doc-api-doc-spec.md b/server/.ai-specs/sys-specs/doc-api-doc-spec.md new file mode 100644 index 0000000..623a559 --- /dev/null +++ b/server/.ai-specs/sys-specs/doc-api-doc-spec.md @@ -0,0 +1,240 @@ +# doc-api 文档规范 + +## 适用范围 + +- 新增、重建、校准 `.ai-specs/doc-api/<端>/.md` 时必读。 +- 目标:即使目标 `doc-api` 为空,也能按本文稳定生成接口 contract 文档。 +- `doc-api` 只写端点、`Handler`、`Service`、鉴权、审计、请求、响应、规则;表结构看 `doc-sql`,值域看 `doc-dict`,代码落点看 `coding-specs`。 + +## 生成输入 + +按顺序读取,缺失则跳过并从下一项补齐: + +1. `AGENTS.md`:确认项目链路、文档索引、鉴权入口。 +2. `.ai-specs/coding-specs/module-admin-crud-default.md`:确认 admin 默认 CRUD、命名、Method、Service 映射。 +3. `.ai-specs/coding-specs/api-auth-control.md`:确认 `PublicGroup`、`PrivateGroup`、`JWT + Casbin` 规则。 +4. `.ai-specs/coding-specs/vo-model-request-response.md`:确认实体、request、response 落点。 +5. 对应 `.ai-specs/doc-sql/.sql`:确认字段、默认值、唯一约束、索引、删除策略、排序依据。 +6. 对应 `.ai-specs/doc-dict/*.md`:确认状态、类型、枚举值域。 +7. 源码:`router/`、`api/v1/`、`service/`、`model/`、`initialize/router_biz.go`。 + +## 文档结构 + +```md +# <资源中文名> <端> 接口 + +## 基本信息 + +- 模块: +- 资源:<资源中文名> +- 端: +- 鉴权: +- 审计:<启用 OperationRecord 的端点> +- 前缀:/ +- 实体模型: +- 搜索入参: +- 详情响应: +- 列表项: +- 返回:写操作 `response.Response{msg}`;详情 `response.Response{data}`;列表 `response.PageResult` +- 删除策略:<硬删/软删/不支持删除> + +## CRUD + +<按端点模板展开> + +## 规则 + +- <资源级通用规则> +``` + +## admin CRUD 模板 + +默认 admin CRUD 必须按以下 6 个端点展开;有明确例外时,在对应 `doc-api` 的 `## 规则` 写明。 + +### 创建 + +```md +### 创建<资源> + +- Method:`POST` +- Path:`//create` +- Handler:`Api.Create` +- Service:`Service.Create` +- 审计:是 + +#### Request Body `` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| | | <是/否> | <来自 doc-sql/doc-dict/代码校验> | <字段说明> | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 创建请求禁止传服务端生成字段:`id/createdAt/updatedAt`。 +- <唯一约束、默认值、引用校验等创建规则> +``` + +### 单删 + +```md +### 删除<资源> + +- Method:`DELETE` +- Path:`//delete` +- Handler:`Api.Delete` +- Service:`Service.Delete` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 主键 ID | + +#### Response + +- `response.Response{msg}` +``` + +### 批量删除 + +```md +### 批量删除<资源> + +- Method:`DELETE` +- Path:`//deleteByIds` +- Handler:`Api.DeleteByIds` +- Service:`Service.DeleteByIds` +- 审计:是 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| ids | int[] | 二选一 | 非空,元素均 `> 0` | 主键 ID 数组 | +| ids[] | int[] | 二选一 | 非空,元素均 `> 0` | 主键 ID 数组,兼容数组写法 | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- `ids` 与 `ids[]` 二选一。 +``` + +### 更新 + +```md +### 更新<资源> + +- Method:`PUT` +- Path:`//update` +- Handler:`Api.Update` +- Service:`Service.Update` +- 审计:是 + +#### Request Body `` + +| 字段 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | uint | 是 | `> 0` | 主键 ID | +| | | <是/否> | <来自 doc-sql/doc-dict/代码校验> | <字段说明> | + +#### Response + +- `response.Response{msg}` + +#### 规则 + +- 更新请求禁止传服务端维护字段:`createdAt/updatedAt`。 +- <全量保存/局部更新、唯一约束、引用校验等更新规则> +``` + +### 详情 + +```md +### 查询<资源>详情 + +- Method:`GET` +- Path:`//find` +- Handler:`Api.Find` +- Service:`Service.Get` +- 审计:否 + +#### Request Query + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| id | int | 是 | `> 0` | 主键 ID | + +#### Response `Response` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| | object | 详情实体 | +| .id | uint | 主键 ID | +| . | | <字段说明> | +``` + +### 分页列表 + +```md +### 分页查询<资源>列表 + +- Method:`GET` +- Path:`//getList` +- Handler:`Api.GetList` +- Service:`Service.GetInfoList` +- 审计:否 + +#### Request Query `Search` + +| 参数 | 类型 | 必填 | 规则 | 说明 | +|:---|:---|:---:|:---|:---| +| page | int | 否 | 默认 `1`,最小 `1` | 页码 | +| pageSize | int | 否 | 默认 `10`,最大 `100` | 每页数量 | +| | | 否 | <规则> | <筛选说明> | + +#### Response `response.PageResult` + +| 字段 | 类型 | 说明 | +|:---|:---|:---| +| list | array | `` 列表 | +| list[].id | uint | 主键 ID | +| list[]. | | <字段说明> | +| total | int64 | 总数 | +| page | int | 当前页 | +| pageSize | int | 每页数量 | + +#### 规则 + +- 列表默认排序:``。 +``` + +## 字段来源 + +- Body 字段:优先取 `request`;没有独立 `request` 时取实体可编辑字段。 +- Query 字段:取 `request/Search`、`common.GetById`、`common.IdsReq`。 +- Detail 响应:取 `response` 包装结构和实体 JSON 字段。 +- List 响应:取 `ListItem`、`Select/Scan` 字段、额外展示字段。 +- 字段规则:取 `doc-sql` 非空/默认值/唯一索引/check,叠加 `doc-dict` 值域和 `Service` 校验。 +- 字段名:使用实际 `json/form` 名称,禁止使用 Go 字段名替代。 +- 端点鉴权:默认继承 `## 基本信息`;只有端点鉴权不同才在端点内单独写。 +- 写操作响应:统一写 `response.Response{msg}`,不展开 `code/msg` 表格。 +- 请求/响应汇总:默认不写 `## 请求字段`、`## 响应字段`;字段以端点内 `Request/Response` 为准。 + +## 硬性要求 + +- `## CRUD` 必须展开端点,禁止只写 CRUD 总表。 +- 每个端点必须有自己的 `Request`、`Response`;无请求参数时保留 `Request` 小节并写 `- 无。`。 +- 端点特有规则按需写在端点下;通用规则写到文末 `## 规则`。 +- 请求字段表列固定为:字段/参数、类型、必填、规则、说明。 +- 详情/列表响应字段表列固定为:字段、类型、说明;写操作响应简写为 `response.Response{msg}`。 +- 关键响应字段必须展开,禁止写 `mixed`。 +- `ids` 与 `ids[]` 必须写清二选一。 +- 文档规则要求业务校验时,代码必须同步落到 `API` 或 `Service`。 diff --git a/server/.ai-specs/sys-specs/module-naming-spec.md b/server/.ai-specs/sys-specs/module-naming-spec.md index 04b7925..bae2e4f 100644 --- a/server/.ai-specs/sys-specs/module-naming-spec.md +++ b/server/.ai-specs/sys-specs/module-naming-spec.md @@ -16,5 +16,6 @@ | 中文 | 英文 | 说明 | |:---|:---|:---| +| 通用 | common | 跨业务复用的通用值域与模型 | | 书籍 | book | 书籍与章节相关业务模块 | | 设备 | device | 设备管理模块 | diff --git a/server/.ai-transition/database-upgrade-doc/v1.sql b/server/.ai-transition/database-upgrade-doc/v1.sql index 0e25e61..9b95196 100644 --- a/server/.ai-transition/database-upgrade-doc/v1.sql +++ b/server/.ai-transition/database-upgrade-doc/v1.sql @@ -28,9 +28,17 @@ WHERE NOT EXISTS ( -- book 业务字典初始化补齐 / sys_dictionaries, sys_dictionary_details / 2026-04-26 +DELETE FROM sys_dictionary_details d +USING sys_dictionaries dict +WHERE d.sys_dictionary_id = dict.id + AND dict.type = 'book_author_status'; + +DELETE FROM sys_dictionaries +WHERE type = 'book_author_status'; + WITH dict_seed(name, type, status, description) AS ( VALUES - ('作者状态', 'book_author_status', true, '作者状态字典'), + ('通用启用状态', 'common_enabled_status', true, '通用启用禁用状态字典'), ('书籍评论状态', 'book_comment_status', true, '书籍评论状态字典'), ('书籍完结状态', 'book_completion_status', true, '书籍完结状态字典'), ('书籍时代标签', 'book_era_tag', true, '书籍时代标签字典'), @@ -48,7 +56,7 @@ WHERE d.type = s.type; WITH dict_seed(name, type, status, description) AS ( VALUES - ('作者状态', 'book_author_status', true, '作者状态字典'), + ('通用启用状态', 'common_enabled_status', true, '通用启用禁用状态字典'), ('书籍评论状态', 'book_comment_status', true, '书籍评论状态字典'), ('书籍完结状态', 'book_completion_status', true, '书籍完结状态字典'), ('书籍时代标签', 'book_era_tag', true, '书籍时代标签字典'), @@ -64,8 +72,8 @@ WHERE NOT EXISTS ( WITH detail_seed(dict_type, label, value, sort, status) AS ( VALUES - ('book_author_status', '启用', 'enabled', 10, true), - ('book_author_status', '禁用', 'disabled', 20, true), + ('common_enabled_status', '启用', 'enabled', 10, true), + ('common_enabled_status', '禁用', 'disabled', 20, true), ('book_comment_status', '正常', 'normal', 10, true), ('book_comment_status', '隐藏', 'hidden', 20, true), ('book_completion_status', '完结', 'completed', 10, true), @@ -100,8 +108,8 @@ WHERE d.sys_dictionary_id = dict.id WITH detail_seed(dict_type, label, value, sort, status) AS ( VALUES - ('book_author_status', '启用', 'enabled', 10, true), - ('book_author_status', '禁用', 'disabled', 20, true), + ('common_enabled_status', '启用', 'enabled', 10, true), + ('common_enabled_status', '禁用', 'disabled', 20, true), ('book_comment_status', '正常', 'normal', 10, true), ('book_comment_status', '隐藏', 'hidden', 20, true), ('book_completion_status', '完结', 'completed', 10, true), diff --git a/server/AGENTS.md b/server/AGENTS.md index 97835a4..09ae27f 100644 --- a/server/AGENTS.md +++ b/server/AGENTS.md @@ -1,10 +1,10 @@ -# AI 开发入口 [!IMPORTANT] +# AI 开发入口 [!IMPORTANT] - **本文档要求**:本文档为项目级别规范和重要导航,必须严格参考 - **本文档要求**:本文档只允许在已有的结构上CURD,不允许增加其他标题区 - **本文档要求**:.ai-specs 目录下新增/删除任何文档的时候都应该 在本文档中修改 `## 项目文档` -- **文档要求**:规范型文档是给 AI 的顶层入口文档,不是“解释得更全”就更好,而是要 更短、更硬、更可判定 -- **文档要求**:如果我的`需求/要求`和`规范文档`冲突,你应该及时提醒我,让我决策是修正`需求/规范文档` +- **文档要求**:规范型文档是给 AI 的顶层入口文档,不是“解释得更全”就更好,而是要 更短、更硬、更可判定,推荐文档内容以“硬规则 + 模板”为主 +- **文档要求**:如果我的`需求/要求`和`规范文档`冲突,你应该及时提醒我,让我决策是否修正`需求/规范文档` - **代码优化**:先复用再新增,允许抽公共逻辑,但公共逻辑必须保证边界仍清晰。 - **代码优化**:优化代码时必须同时考虑冗余、孤岛代码、代码清晰度、复杂度、边界条件和兼容性,不能只追求功能跑通。不要修改ui/ux 视觉效果,除非明确要求。 - **代码默认遵循**:业务流程需要遵循 `主流做法` `工业级正规` @@ -12,7 +12,7 @@ ## 工具使用规则 -- **搜索范围限制**:Grep/Glob 严禁全盘搜索,绝对禁止扫描 `.gitignore` 忽略的目录,以避免性能卡顿。 +- **搜索范围限制**:Grep/Glob 严禁全盘搜索,绝对禁止扫描 `server\docs`、`.worktrees`、`web\node_modules`、`web\dist`、`server\log`、`server\uploads`、`rm_file` 等大目录,以避免性能卡顿。 - **读写**:所有文件读取/写入统一使用 UTF-8(建议无 BOM) - **读写**:PowerShell/脚本读取项目文件必须显式指定 `-Encoding utf8` - **画图**:优先使用 `Mermaid 图` 不能混入非 Mermaid 语法文本。 @@ -134,6 +134,7 @@ flowchart LR | `.ai-specs\sys-specs\business-table-spec.md` | 规定新增业务表的 SQL 设计、索引、约束、迁移和兼容要求 | 涉及新增/修改业务表、字段、索引、唯一约束、迁移注册时必读 | | `.ai-specs\sys-specs\business-dictionary-spec.md` | 规定新增业务字典的定义方式,以及代码枚举与字典值的一一对应关系 | 涉及新增业务状态、类型、级别、来源、模式、分类等值域时必读 | | `.ai-specs\sys-specs\module-naming-spec.md` | 规定业务模块中文名与英文名的统一登记方式 | 涉及新增/修改业务模块命名、中英文对照、目录命名时必读 | +| `.ai-specs\sys-specs\doc-api-doc-spec.md` | 规定 `doc-api` 从空文档生成接口 contract 的输入源、admin CRUD 模板、字段来源和硬性要求 | 涉及新增/修改 `.ai-specs\doc-api` 接口文档时必读 | | `.ai-specs\sys-specs\database-upgrade-doc-spec.md` | 规定 `.ai-transition\database-upgrade-doc` 数据库升级 SQL 的版本定位、写入时机和兼容 SQL 要求 | 涉及修改 `doc-sql` 并产生数据库结构变更、维护 `v1.sql`/`v2.sql` 等升级 SQL 时必读 | ### doc-api @@ -169,7 +170,7 @@ flowchart LR | 路径 | 用途 | 说明 | |:---|:---|:---| -| `.ai-specs\doc-dict\book_author_status.md` | 定义作者状态的标准值域 | 涉及作者状态的存储、校验、展示和接口出入参时必读 | +| `.ai-specs\doc-dict\common_enabled_status.md` | 定义通用启用/禁用状态的标准值域 | 涉及业务对象启用禁用状态的存储、校验、展示和接口出入参时必读 | | `.ai-specs\doc-dict\book_comment_status.md` | 定义书籍评论状态的标准值域 | 涉及评论状态存储、评论隐藏和评论出入参展示时必读 | | `.ai-specs\doc-dict\book_completion_status.md` | 定义书籍完结状态的标准值域 | 涉及书籍完结状态的存储、校验、展示和接口出入参时必读 | | `.ai-specs\doc-dict\book_era_tag.md` | 定义书籍时代标签的标准值域 | 涉及时代标签存储、筛选聚合和接口出入参时必读 | diff --git a/server/README.md b/server/README.md index 087e52b..052f3b5 100644 --- a/server/README.md +++ b/server/README.md @@ -5,9 +5,10 @@ go mod tidy go run main.go # 更新api文档 -swag init go install github.com/swaggo/swag/cmd/swag@latest +swag init + diff --git a/server/docs/docs.go b/server/docs/docs.go index e5fc176..a831308 100644 --- a/server/docs/docs.go +++ b/server/docs/docs.go @@ -1,11 +1,7 @@ -// Code generated by swaggo/swag. DO NOT EDIT. - +// Package docs Code generated by swaggo/swag. DO NOT EDIT package docs -import ( - "github.com/flipped-aurora/gin-vue-admin/server/global" - "github.com/swaggo/swag" -) +import "github.com/swaggo/swag" const docTemplate = `{ "schemes": {{ marshal .Schemes }}, @@ -426,6 +422,65 @@ const docTemplate = `{ } } }, + "/api/getApiRoles": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "获取拥有指定API权限的角色ID列表", + "parameters": [ + { + "type": "string", + "description": "API路径", + "name": "path", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "请求方法", + "name": "method", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/ignoreApi": { "post": { "security": [ @@ -465,6 +520,56 @@ const docTemplate = `{ } } }, + "/api/setApiRoles": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "全量覆盖某API关联的角色列表", + "parameters": [ + { + "description": "API路径、请求方法和角色ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetApiAuthorities" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/syncApi": { "get": { "security": [ @@ -883,6 +988,60 @@ const docTemplate = `{ } } }, + "/authority/getUsersByAuthority": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authority" + ], + "summary": "获取拥有指定角色的用户ID列表", + "parameters": [ + { + "type": "integer", + "description": "角色ID", + "name": "authorityId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/authority/setDataAuthority": { "post": { "security": [ @@ -933,6 +1092,56 @@ const docTemplate = `{ } } }, + "/authority/setRoleUsers": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authority" + ], + "summary": "全量覆盖某角色关联的用户列表", + "parameters": [ + { + "description": "角色ID和用户ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetRoleUsers" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/authority/updateAuthority": { "put": { "security": [ @@ -1362,92 +1571,6 @@ const docTemplate = `{ } } }, - "/autoCode/getColumn": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前表所有字段", - "responses": { - "200": { - "description": "获取当前表所有字段", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, - "/autoCode/getDB": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前所有数据库", - "responses": { - "200": { - "description": "获取当前所有数据库", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/autoCode/getMeta": { "post": { "security": [ @@ -1545,6 +1668,45 @@ const docTemplate = `{ } } }, + "/autoCode/getPluginList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "获取插件列表", + "responses": { + "200": { + "description": "获取插件列表成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/response.PluginInfo" + } + } + } + } + ] + } + } + } + } + }, "/autoCode/getSysHistory": { "post": { "security": [ @@ -1598,49 +1760,6 @@ const docTemplate = `{ } } }, - "/autoCode/getTables": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前数据库所有表", - "responses": { - "200": { - "description": "获取当前数据库所有表", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/autoCode/getTemplates": { "get": { "security": [ @@ -1727,6 +1846,49 @@ const docTemplate = `{ } } }, + "/autoCode/initDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "打包插件", + "responses": { + "200": { + "description": "打包插件成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/initMenu": { "post": { "security": [ @@ -1809,9 +1971,7 @@ const docTemplate = `{ "properties": { "data": { "type": "array", - "items": { - "type": "object" - } + "items": {} }, "msg": { "type": "string" @@ -1930,6 +2090,58 @@ const docTemplate = `{ } } }, + "/autoCode/removePlugin": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "删除插件", + "parameters": [ + { + "type": "string", + "description": "插件名称", + "name": "pluginName", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "插件类型", + "name": "pluginType", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "删除插件成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/rollback": { "post": { "security": [ @@ -2067,6 +2279,319 @@ const docTemplate = `{ } } }, + "/book/createBook": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Book" + ], + "summary": "创建书籍信息", + "parameters": [ + { + "description": "书籍信息", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/book.Book" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/deleteBook": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "删除书籍信息", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/deleteBookByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "批量删除书籍信息", + "parameters": [ + { + "type": "array", + "items": { + "type": "integer" + }, + "collectionFormat": "csv", + "description": "主键ID数组", + "name": "ids", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/findBook": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "查询书籍详情", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.BookResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/getBookList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "分页获取书籍列表", + "parameters": [ + { + "type": "string", + "name": "bookType", + "in": "query" + }, + { + "type": "string", + "name": "completionStatus", + "in": "query" + }, + { + "type": "string", + "name": "eraTag", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "publishStatus", + "in": "query" + }, + { + "type": "integer", + "name": "seriesId", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/updateBook": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "更新书籍信息", + "parameters": [ + { + "description": "书籍信息", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/book.Book" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/casbin/UpdateCasbin": { "post": { "security": [ @@ -3886,6 +4411,108 @@ const docTemplate = `{ } } }, + "/menu/getMenuRoles": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取拥有指定菜单的角色ID列表", + "parameters": [ + { + "type": "integer", + "description": "菜单ID", + "name": "menuId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/setMenuRoles": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "全量覆盖某菜单关联的角色列表", + "parameters": [ + { + "description": "菜单ID和角色ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetMenuAuthorities" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/menu/updateBaseMenu": { "post": { "security": [ @@ -4036,6 +4663,99 @@ const docTemplate = `{ } } }, + "/sysDictionary/exportSysDictionary": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "导出字典JSON(包含字典详情)", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "描述", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典ID", + "name": "parentID", + "in": "query" + }, + { + "type": "boolean", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "字典名(英)", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + } + ], + "responses": { + "200": { + "description": "导出字典JSON", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionary/findSysDictionary": { "get": { "security": [ @@ -4078,6 +4798,12 @@ const docTemplate = `{ "name": "name", "in": "query" }, + { + "type": "integer", + "description": "父级字典ID", + "name": "parentID", + "in": "query" + }, { "type": "boolean", "description": "状态", @@ -4140,6 +4866,14 @@ const docTemplate = `{ "SysDictionary" ], "summary": "分页获取SysDictionary列表", + "parameters": [ + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + } + ], "responses": { "200": { "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", @@ -4165,6 +4899,56 @@ const docTemplate = `{ } } }, + "/sysDictionary/importSysDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "导入字典JSON(包含字典详情)", + "parameters": [ + { + "description": "字典JSON数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ImportSysDictionaryRequest" + } + } + ], + "responses": { + "200": { + "description": "导入字典", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionary/updateSysDictionary": { "put": { "security": [ @@ -4345,6 +5129,12 @@ const docTemplate = `{ "name": "createdAt", "in": "query" }, + { + "type": "boolean", + "description": "禁用状态,根据status字段动态计算", + "name": "disabled", + "in": "query" + }, { "type": "string", "description": "扩展值", @@ -4357,6 +5147,24 @@ const docTemplate = `{ "name": "label", "in": "query" }, + { + "type": "integer", + "description": "层级深度,从0开始", + "name": "level", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典详情ID", + "name": "parentID", + "in": "query" + }, + { + "type": "string", + "description": "层级路径,如 \"1,2,3\"", + "name": "path", + "in": "query" + }, { "type": "integer", "description": "排序标记", @@ -4414,6 +5222,234 @@ const docTemplate = `{ } } }, + "/sysDictionaryDetail/getDictionaryDetailsByParent": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "根据父级ID获取字典详情", + "parameters": [ + { + "type": "boolean", + "description": "是否包含子级数据", + "name": "includeChildren", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典详情ID,为空时获取顶级", + "name": "parentID", + "in": "query" + }, + { + "type": "integer", + "description": "字典ID", + "name": "sysDictionaryID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryPath": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "获取字典详情的完整路径", + "parameters": [ + { + "type": "integer", + "description": "字典详情ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情路径", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryTreeList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "获取字典详情树形结构", + "parameters": [ + { + "type": "integer", + "description": "字典ID", + "name": "sysDictionaryID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情树形结构", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryTreeListByType": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "根据字典类型获取字典详情树形结构", + "parameters": [ + { + "type": "string", + "description": "字典类型", + "name": "type", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情树形结构", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionaryDetail/getSysDictionaryDetailList": { "get": { "security": [ @@ -4444,6 +5480,12 @@ const docTemplate = `{ "name": "createdAt", "in": "query" }, + { + "type": "boolean", + "description": "禁用状态,根据status字段动态计算", + "name": "disabled", + "in": "query" + }, { "type": "string", "description": "扩展值", @@ -4462,6 +5504,12 @@ const docTemplate = `{ "name": "label", "in": "query" }, + { + "type": "integer", + "description": "层级深度,用于查询指定层级的数据", + "name": "level", + "in": "query" + }, { "type": "integer", "description": "页码", @@ -4474,6 +5522,18 @@ const docTemplate = `{ "name": "pageSize", "in": "query" }, + { + "type": "integer", + "description": "父级字典详情ID,用于查询指定父级下的子项", + "name": "parentID", + "in": "query" + }, + { + "type": "string", + "description": "层级路径,如 \"1,2,3\"", + "name": "path", + "in": "query" + }, { "type": "integer", "description": "排序标记", @@ -4580,7 +5640,146 @@ const docTemplate = `{ } } }, - "/sysExportTemplate/ExportTemplate": { + "/sysError/createSysError": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "创建错误日志", + "parameters": [ + { + "description": "创建错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "创建成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/deleteSysError": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "删除错误日志", + "parameters": [ + { + "description": "删除错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/deleteSysErrorByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "批量删除错误日志", + "responses": { + "200": { + "description": "批量删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/findSysError": { "get": { "security": [ { @@ -4594,10 +5793,220 @@ const docTemplate = `{ "application/json" ], "tags": [ - "SysExportTemplate" + "SysError" ], - "summary": "导出表格模板", - "responses": {} + "summary": "用id查询错误日志", + "parameters": [ + { + "type": "integer", + "description": "用id查询错误日志", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/system.SysError" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/getSysErrorList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "分页获取错误日志列表", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "name": "createdAtRange", + "in": "query" + }, + { + "type": "string", + "name": "form", + "in": "query" + }, + { + "type": "string", + "name": "info", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/getSysErrorSolution": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "根据ID触发处理:标记为处理中,1分钟后自动改为处理完成", + "parameters": [ + { + "type": "string", + "description": "错误日志ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "处理已提交", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/updateSysError": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "更新错误日志", + "parameters": [ + { + "description": "更新错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } } }, "/sysExportTemplate/createSysExportTemplate": { @@ -4734,6 +6143,66 @@ const docTemplate = `{ "responses": {} } }, + "/sysExportTemplate/exportExcelByToken": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ExportExcelByToken" + ], + "summary": "导出表格", + "responses": {} + } + }, + "/sysExportTemplate/exportTemplate": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "导出表格模板", + "responses": {} + } + }, + "/sysExportTemplate/exportTemplateByToken": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ExportTemplateByToken" + ], + "summary": "通过token导出表格模板", + "responses": {} + } + }, "/sysExportTemplate/findSysExportTemplate": { "get": { "security": [ @@ -4770,6 +6239,12 @@ const docTemplate = `{ "name": "dbName", "in": "query" }, + { + "type": "string", + "description": "自定义导入SQL", + "name": "importSql", + "in": "query" + }, { "type": "integer", "name": "limit", @@ -4786,6 +6261,12 @@ const docTemplate = `{ "name": "order", "in": "query" }, + { + "type": "string", + "description": "自定义导出SQL", + "name": "sql", + "in": "query" + }, { "type": "string", "description": "表名称", @@ -4862,6 +6343,12 @@ const docTemplate = `{ "name": "endCreatedAt", "in": "query" }, + { + "type": "string", + "description": "自定义导入SQL", + "name": "importSql", + "in": "query" + }, { "type": "string", "description": "关键字", @@ -4896,6 +6383,12 @@ const docTemplate = `{ "name": "pageSize", "in": "query" }, + { + "type": "string", + "description": "自定义导出SQL", + "name": "sql", + "in": "query" + }, { "type": "string", "name": "startCreatedAt", @@ -4956,6 +6449,63 @@ const docTemplate = `{ "responses": {} } }, + "/sysExportTemplate/previewSQL": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "预览最终生成的SQL(不执行查询,仅返回SQL字符串)", + "parameters": [ + { + "type": "string", + "description": "导出模板ID", + "name": "templateID", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "查询参数编码字符串,参考 ExportExcel 组件", + "name": "params", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + ] + } + } + } + } + }, "/sysExportTemplate/updateSysExportTemplate": { "put": { "security": [ @@ -4994,56 +6544,6 @@ const docTemplate = `{ } } }, - "/sysOperationRecord/createSysOperationRecord": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "SysOperationRecord" - ], - "summary": "创建SysOperationRecord", - "parameters": [ - { - "description": "创建SysOperationRecord", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysOperationRecord" - } - } - ], - "responses": { - "200": { - "description": "创建SysOperationRecord", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/sysOperationRecord/deleteSysOperationRecord": { "delete": { "security": [ @@ -5818,6 +7318,415 @@ const docTemplate = `{ } } }, + "/sysVersion/deleteSysVersion": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "删除版本管理", + "parameters": [ + { + "description": "删除版本管理", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysVersion" + } + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/deleteSysVersionByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "批量删除版本管理", + "responses": { + "200": { + "description": "批量删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/downloadVersionJson": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "下载版本JSON数据", + "parameters": [ + { + "type": "string", + "description": "版本ID", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "下载成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/exportVersion": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "创建发版数据", + "parameters": [ + { + "description": "创建发版数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ExportVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "创建成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/findSysVersion": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "用id查询版本管理", + "parameters": [ + { + "type": "integer", + "description": "用id查询版本管理", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/system.SysVersion" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/getSysVersionList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "分页获取版本管理列表", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "name": "createdAtRange", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "versionCode", + "in": "query" + }, + { + "type": "string", + "name": "versionName", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/getSysVersionPublic": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "不需要鉴权的版本管理接口", + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/importVersion": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "导入版本数据", + "parameters": [ + { + "description": "版本JSON数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ImportVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "导入成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/system/getServerInfo": { "post": { "security": [ @@ -5910,10 +7819,10 @@ const docTemplate = `{ "tags": [ "System" ], - "summary": "重启系统", + "summary": "重载系统", "responses": { "200": { - "description": "重启系统", + "description": "重载系统", "schema": { "allOf": [ { @@ -6530,6 +8439,71 @@ const docTemplate = `{ } }, "definitions": { + "book.Book": { + "type": "object", + "properties": { + "bookType": { + "type": "string" + }, + "commentCount": { + "type": "integer" + }, + "completionStatus": { + "type": "string" + }, + "coverUrl": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "eraTag": { + "type": "string" + }, + "hotScore": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "intro": { + "type": "string" + }, + "publishStatus": { + "type": "string" + }, + "publishedAt": { + "type": "string" + }, + "publisher": { + "type": "string" + }, + "rating": { + "type": "number" + }, + "rawTxtUrl": { + "type": "string" + }, + "seriesId": { + "type": "integer" + }, + "seriesSort": { + "type": "integer" + }, + "subtitle": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "wordCount": { + "type": "integer" + } + } + }, "common.JSONMap": { "type": "object", "additionalProperties": true @@ -6659,7 +8633,7 @@ const docTemplate = `{ "type": "integer" }, "open-captcha": { - "description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码", + "description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码次数,如3代表错误三次后出现验证码", "type": "integer" }, "open-captcha-timeout": { @@ -6761,6 +8735,48 @@ const docTemplate = `{ } } }, + "config.MCP": { + "type": "object", + "properties": { + "addr": { + "type": "integer" + }, + "auth_header": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "message_path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "request_timeout": { + "type": "integer" + }, + "separate": { + "type": "boolean" + }, + "sse_path": { + "description": "Deprecated fields kept for backward compatibility with older configs.", + "type": "string" + }, + "upstream_base_url": { + "type": "string" + }, + "url_prefix": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "config.Minio": { "type": "object", "properties": { @@ -7216,6 +9232,14 @@ const docTemplate = `{ } ] }, + "mcp": { + "description": "MCP配置", + "allOf": [ + { + "$ref": "#/definitions/config.MCP" + } + ] + }, "minio": { "$ref": "#/definitions/config.Minio" }, @@ -7401,6 +9425,10 @@ const docTemplate = `{ "description": "数据库类型:mysql(默认)|sqlite|sqlserver|postgresql", "type": "string" }, + "disable-auto-migrate": { + "description": "自动迁移数据库表结构,生产环境建议设为false,手动迁移", + "type": "boolean" + }, "iplimit-count": { "type": "integer" }, @@ -7678,6 +9706,10 @@ const docTemplate = `{ "description": "服务器地址 例如 smtp.qq.com 请前往QQ或者你要发邮件的邮箱查看其smtp协议", "type": "string" }, + "is-loginauth": { + "description": "是否LoginAuth 是否使用LoginAuth认证方式(适用于IBM、微软邮箱服务器等)", + "type": "boolean" + }, "is-ssl": { "description": "是否SSL 是否开启SSL", "type": "boolean" @@ -8052,6 +10084,48 @@ const docTemplate = `{ } } }, + "request.ExportVersionRequest": { + "type": "object", + "required": [ + "versionCode", + "versionName" + ], + "properties": { + "apiIds": { + "description": "选中的API ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "dictIds": { + "description": "选中的字典ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "menuIds": { + "description": "选中的菜单ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "versionCode": { + "description": "版本号", + "type": "string" + }, + "versionName": { + "description": "版本名称", + "type": "string" + } + } + }, "request.GetAuthorityId": { "type": "object", "properties": { @@ -8073,6 +10147,10 @@ const docTemplate = `{ "request.GetUserList": { "type": "object", "properties": { + "desc": { + "description": "排序方式:升序false(默认)|降序true", + "type": "boolean" + }, "email": { "type": "string" }, @@ -8083,6 +10161,10 @@ const docTemplate = `{ "nickName": { "type": "string" }, + "orderKey": { + "description": "排序", + "type": "string" + }, "page": { "description": "页码", "type": "integer" @@ -8110,6 +10192,55 @@ const docTemplate = `{ } } }, + "request.ImportSysDictionaryRequest": { + "type": "object", + "required": [ + "json" + ], + "properties": { + "json": { + "description": "JSON字符串", + "type": "string" + } + } + }, + "request.ImportVersionRequest": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "apis": { + "description": "API数据,直接复用SysApi", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysApi" + } + }, + "dictionaries": { + "description": "字典数据,直接复用SysDictionary", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, + "menus": { + "description": "菜单数据,直接复用SysBaseMenu", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysBaseMenu" + } + }, + "version": { + "description": "版本信息", + "allOf": [ + { + "$ref": "#/definitions/request.VersionInfo" + } + ] + } + } + }, "request.InitDB": { "type": "object", "required": [ @@ -8286,6 +10417,58 @@ const docTemplate = `{ } } }, + "request.SetApiAuthorities": { + "type": "object", + "properties": { + "authorityIds": { + "description": "角色ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "method": { + "description": "请求方法", + "type": "string" + }, + "path": { + "description": "API路径", + "type": "string" + } + } + }, + "request.SetMenuAuthorities": { + "type": "object", + "properties": { + "authorityIds": { + "description": "角色ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "menuId": { + "description": "菜单ID", + "type": "integer" + } + } + }, + "request.SetRoleUsers": { + "type": "object", + "properties": { + "authorityId": { + "description": "角色ID", + "type": "integer" + }, + "userIds": { + "description": "用户ID列表", + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "request.SetUserAuth": { "type": "object", "properties": { @@ -8369,6 +10552,39 @@ const docTemplate = `{ } } }, + "request.VersionInfo": { + "type": "object", + "required": [ + "code", + "name" + ], + "properties": { + "code": { + "description": "版本号", + "type": "string" + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "exportTime": { + "description": "导出时间", + "type": "string" + }, + "name": { + "description": "版本名称", + "type": "string" + } + } + }, + "response.BookResponse": { + "type": "object", + "properties": { + "book": { + "$ref": "#/definitions/book.Book" + } + } + }, "response.Email": { "type": "object", "properties": { @@ -8447,6 +10663,36 @@ const docTemplate = `{ } } }, + "response.PluginInfo": { + "type": "object", + "properties": { + "apis": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysApi" + } + }, + "dictionaries": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, + "menus": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysBaseMenu" + } + }, + "pluginName": { + "type": "string" + }, + "pluginType": { + "description": "web, server, full", + "type": "string" + } + } + }, "response.PolicyPathResponse": { "type": "object", "properties": { @@ -8666,6 +10912,10 @@ const docTemplate = `{ "title": { "description": "菜单名", "type": "string" + }, + "transitionType": { + "description": "路由切换动画", + "type": "string" } } }, @@ -8890,6 +11140,13 @@ const docTemplate = `{ "description": "主键ID", "type": "integer" }, + "children": { + "description": "子字典", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, "createdAt": { "description": "创建时间", "type": "string" @@ -8902,6 +11159,10 @@ const docTemplate = `{ "description": "字典名(中)", "type": "string" }, + "parentID": { + "description": "父级字典ID", + "type": "integer" + }, "status": { "description": "状态", "type": "boolean" @@ -8929,10 +11190,21 @@ const docTemplate = `{ "description": "主键ID", "type": "integer" }, + "children": { + "description": "子字典详情", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, "createdAt": { "description": "创建时间", "type": "string" }, + "disabled": { + "description": "禁用状态,根据status字段动态计算", + "type": "boolean" + }, "extend": { "description": "扩展值", "type": "string" @@ -8941,6 +11213,18 @@ const docTemplate = `{ "description": "展示值", "type": "string" }, + "level": { + "description": "层级深度,从0开始", + "type": "integer" + }, + "parentID": { + "description": "父级字典详情ID", + "type": "integer" + }, + "path": { + "description": "层级路径,如 \"1,2,3\"", + "type": "string" + }, "sort": { "description": "排序标记", "type": "integer" @@ -8963,6 +11247,45 @@ const docTemplate = `{ } } }, + "system.SysError": { + "type": "object", + "required": [ + "form" + ], + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "form": { + "description": "错误来源", + "type": "string" + }, + "info": { + "description": "错误内容", + "type": "string" + }, + "level": { + "type": "string" + }, + "solution": { + "description": "解决方案", + "type": "string" + }, + "status": { + "description": "处理状态:未处理/处理中/处理完成", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "system.SysExportTemplate": { "type": "object", "properties": { @@ -8984,6 +11307,10 @@ const docTemplate = `{ "description": "数据库名称", "type": "string" }, + "importSql": { + "description": "自定义导入SQL", + "type": "string" + }, "joinTemplate": { "type": "array", "items": { @@ -9000,6 +11327,10 @@ const docTemplate = `{ "order": { "type": "string" }, + "sql": { + "description": "自定义导出SQL", + "type": "string" + }, "tableName": { "description": "表名称", "type": "string" @@ -9270,6 +11601,43 @@ const docTemplate = `{ } } }, + "system.SysVersion": { + "type": "object", + "required": [ + "versionCode", + "versionName" + ], + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "versionCode": { + "description": "版本号", + "type": "string" + }, + "versionData": { + "description": "版本数据", + "type": "string" + }, + "versionName": { + "description": "版本名称", + "type": "string" + } + } + }, "system.System": { "type": "object", "properties": { @@ -9299,7 +11667,7 @@ const docTemplate = `{ // SwaggerInfo holds exported Swagger Info so clients can modify it var SwaggerInfo = &swag.Spec{ - Version: global.Version, + Version: "v2.9.1", Host: "", BasePath: "", Schemes: []string{}, @@ -9307,6 +11675,8 @@ var SwaggerInfo = &swag.Spec{ Description: "使用gin+vue进行极速开发的全栈开发基础平台", InfoInstanceName: "swagger", SwaggerTemplate: docTemplate, + LeftDelim: "{{", + RightDelim: "}}", } func init() { diff --git a/server/docs/swagger.json b/server/docs/swagger.json index 9eb3da4..8ae14ec 100644 --- a/server/docs/swagger.json +++ b/server/docs/swagger.json @@ -4,7 +4,7 @@ "description": "使用gin+vue进行极速开发的全栈开发基础平台", "title": "Gin-Vue-Admin Swagger API接口文档", "contact": {}, - "version": "v2.7.9-beta" + "version": "v2.9.1" }, "paths": { "/api/createApi": { @@ -414,6 +414,65 @@ } } }, + "/api/getApiRoles": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "获取拥有指定API权限的角色ID列表", + "parameters": [ + { + "type": "string", + "description": "API路径", + "name": "path", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "请求方法", + "name": "method", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/ignoreApi": { "post": { "security": [ @@ -453,6 +512,56 @@ } } }, + "/api/setApiRoles": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysApi" + ], + "summary": "全量覆盖某API关联的角色列表", + "parameters": [ + { + "description": "API路径、请求方法和角色ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetApiAuthorities" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/api/syncApi": { "get": { "security": [ @@ -871,6 +980,60 @@ } } }, + "/authority/getUsersByAuthority": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authority" + ], + "summary": "获取拥有指定角色的用户ID列表", + "parameters": [ + { + "type": "integer", + "description": "角色ID", + "name": "authorityId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "integer" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/authority/setDataAuthority": { "post": { "security": [ @@ -921,6 +1084,56 @@ } } }, + "/authority/setRoleUsers": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authority" + ], + "summary": "全量覆盖某角色关联的用户列表", + "parameters": [ + { + "description": "角色ID和用户ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetRoleUsers" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/authority/updateAuthority": { "put": { "security": [ @@ -1350,92 +1563,6 @@ } } }, - "/autoCode/getColumn": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前表所有字段", - "responses": { - "200": { - "description": "获取当前表所有字段", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, - "/autoCode/getDB": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前所有数据库", - "responses": { - "200": { - "description": "获取当前所有数据库", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/autoCode/getMeta": { "post": { "security": [ @@ -1533,6 +1660,45 @@ } } }, + "/autoCode/getPluginList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "获取插件列表", + "responses": { + "200": { + "description": "获取插件列表成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/response.PluginInfo" + } + } + } + } + ] + } + } + } + } + }, "/autoCode/getSysHistory": { "post": { "security": [ @@ -1586,49 +1752,6 @@ } } }, - "/autoCode/getTables": { - "get": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "AutoCode" - ], - "summary": "获取当前数据库所有表", - "responses": { - "200": { - "description": "获取当前数据库所有表", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "data": { - "type": "object", - "additionalProperties": true - }, - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/autoCode/getTemplates": { "get": { "security": [ @@ -1715,6 +1838,49 @@ } } }, + "/autoCode/initDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "打包插件", + "responses": { + "200": { + "description": "打包插件成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/initMenu": { "post": { "security": [ @@ -1797,9 +1963,7 @@ "properties": { "data": { "type": "array", - "items": { - "type": "object" - } + "items": {} }, "msg": { "type": "string" @@ -1918,6 +2082,58 @@ } } }, + "/autoCode/removePlugin": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "AutoCodePlugin" + ], + "summary": "删除插件", + "parameters": [ + { + "type": "string", + "description": "插件名称", + "name": "pluginName", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "插件类型", + "name": "pluginType", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "删除插件成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/autoCode/rollback": { "post": { "security": [ @@ -2055,6 +2271,319 @@ } } }, + "/book/createBook": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Book" + ], + "summary": "创建书籍信息", + "parameters": [ + { + "description": "书籍信息", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/book.Book" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/deleteBook": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "删除书籍信息", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/deleteBookByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "批量删除书籍信息", + "parameters": [ + { + "type": "array", + "items": { + "type": "integer" + }, + "collectionFormat": "csv", + "description": "主键ID数组", + "name": "ids", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/findBook": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "查询书籍详情", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.BookResponse" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/getBookList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "分页获取书籍列表", + "parameters": [ + { + "type": "string", + "name": "bookType", + "in": "query" + }, + { + "type": "string", + "name": "completionStatus", + "in": "query" + }, + { + "type": "string", + "name": "eraTag", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "publishStatus", + "in": "query" + }, + { + "type": "integer", + "name": "seriesId", + "in": "query" + }, + { + "type": "string", + "name": "title", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/book/updateBook": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "tags": [ + "Book" + ], + "summary": "更新书籍信息", + "parameters": [ + { + "description": "书籍信息", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/book.Book" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/casbin/UpdateCasbin": { "post": { "security": [ @@ -3874,6 +4403,108 @@ } } }, + "/menu/getMenuRoles": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "获取拥有指定菜单的角色ID列表", + "parameters": [ + { + "type": "integer", + "description": "菜单ID", + "name": "menuId", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/menu/setMenuRoles": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "AuthorityMenu" + ], + "summary": "全量覆盖某菜单关联的角色列表", + "parameters": [ + { + "description": "菜单ID和角色ID列表", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.SetMenuAuthorities" + } + } + ], + "responses": { + "200": { + "description": "设置成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/menu/updateBaseMenu": { "post": { "security": [ @@ -4024,6 +4655,99 @@ } } }, + "/sysDictionary/exportSysDictionary": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "导出字典JSON(包含字典详情)", + "parameters": [ + { + "type": "integer", + "description": "主键ID", + "name": "ID", + "in": "query" + }, + { + "type": "string", + "description": "创建时间", + "name": "createdAt", + "in": "query" + }, + { + "type": "string", + "description": "描述", + "name": "desc", + "in": "query" + }, + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典ID", + "name": "parentID", + "in": "query" + }, + { + "type": "boolean", + "description": "状态", + "name": "status", + "in": "query" + }, + { + "type": "string", + "description": "字典名(英)", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "更新时间", + "name": "updatedAt", + "in": "query" + } + ], + "responses": { + "200": { + "description": "导出字典JSON", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": true + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionary/findSysDictionary": { "get": { "security": [ @@ -4066,6 +4790,12 @@ "name": "name", "in": "query" }, + { + "type": "integer", + "description": "父级字典ID", + "name": "parentID", + "in": "query" + }, { "type": "boolean", "description": "状态", @@ -4128,6 +4858,14 @@ "SysDictionary" ], "summary": "分页获取SysDictionary列表", + "parameters": [ + { + "type": "string", + "description": "字典名(中)", + "name": "name", + "in": "query" + } + ], "responses": { "200": { "description": "分页获取SysDictionary列表,返回包括列表,总数,页码,每页数量", @@ -4153,6 +4891,56 @@ } } }, + "/sysDictionary/importSysDictionary": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionary" + ], + "summary": "导入字典JSON(包含字典详情)", + "parameters": [ + { + "description": "字典JSON数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ImportSysDictionaryRequest" + } + } + ], + "responses": { + "200": { + "description": "导入字典", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionary/updateSysDictionary": { "put": { "security": [ @@ -4333,6 +5121,12 @@ "name": "createdAt", "in": "query" }, + { + "type": "boolean", + "description": "禁用状态,根据status字段动态计算", + "name": "disabled", + "in": "query" + }, { "type": "string", "description": "扩展值", @@ -4345,6 +5139,24 @@ "name": "label", "in": "query" }, + { + "type": "integer", + "description": "层级深度,从0开始", + "name": "level", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典详情ID", + "name": "parentID", + "in": "query" + }, + { + "type": "string", + "description": "层级路径,如 \"1,2,3\"", + "name": "path", + "in": "query" + }, { "type": "integer", "description": "排序标记", @@ -4402,6 +5214,234 @@ } } }, + "/sysDictionaryDetail/getDictionaryDetailsByParent": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "根据父级ID获取字典详情", + "parameters": [ + { + "type": "boolean", + "description": "是否包含子级数据", + "name": "includeChildren", + "in": "query" + }, + { + "type": "integer", + "description": "父级字典详情ID,为空时获取顶级", + "name": "parentID", + "in": "query" + }, + { + "type": "integer", + "description": "字典ID", + "name": "sysDictionaryID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情列表", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryPath": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "获取字典详情的完整路径", + "parameters": [ + { + "type": "integer", + "description": "字典详情ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情路径", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryTreeList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "获取字典详情树形结构", + "parameters": [ + { + "type": "integer", + "description": "字典ID", + "name": "sysDictionaryID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情树形结构", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysDictionaryDetail/getDictionaryTreeListByType": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysDictionaryDetail" + ], + "summary": "根据字典类型获取字典详情树形结构", + "parameters": [ + { + "type": "string", + "description": "字典类型", + "name": "type", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "获取字典详情树形结构", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/sysDictionaryDetail/getSysDictionaryDetailList": { "get": { "security": [ @@ -4432,6 +5472,12 @@ "name": "createdAt", "in": "query" }, + { + "type": "boolean", + "description": "禁用状态,根据status字段动态计算", + "name": "disabled", + "in": "query" + }, { "type": "string", "description": "扩展值", @@ -4450,6 +5496,12 @@ "name": "label", "in": "query" }, + { + "type": "integer", + "description": "层级深度,用于查询指定层级的数据", + "name": "level", + "in": "query" + }, { "type": "integer", "description": "页码", @@ -4462,6 +5514,18 @@ "name": "pageSize", "in": "query" }, + { + "type": "integer", + "description": "父级字典详情ID,用于查询指定父级下的子项", + "name": "parentID", + "in": "query" + }, + { + "type": "string", + "description": "层级路径,如 \"1,2,3\"", + "name": "path", + "in": "query" + }, { "type": "integer", "description": "排序标记", @@ -4568,7 +5632,146 @@ } } }, - "/sysExportTemplate/ExportTemplate": { + "/sysError/createSysError": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "创建错误日志", + "parameters": [ + { + "description": "创建错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "创建成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/deleteSysError": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "删除错误日志", + "parameters": [ + { + "description": "删除错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/deleteSysErrorByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "批量删除错误日志", + "responses": { + "200": { + "description": "批量删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/findSysError": { "get": { "security": [ { @@ -4582,10 +5785,220 @@ "application/json" ], "tags": [ - "SysExportTemplate" + "SysError" ], - "summary": "导出表格模板", - "responses": {} + "summary": "用id查询错误日志", + "parameters": [ + { + "type": "integer", + "description": "用id查询错误日志", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/system.SysError" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/getSysErrorList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "分页获取错误日志列表", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "name": "createdAtRange", + "in": "query" + }, + { + "type": "string", + "name": "form", + "in": "query" + }, + { + "type": "string", + "name": "info", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/getSysErrorSolution": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "根据ID触发处理:标记为处理中,1分钟后自动改为处理完成", + "parameters": [ + { + "type": "string", + "description": "错误日志ID", + "name": "id", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "处理已提交", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysError/updateSysError": { + "put": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysError" + ], + "summary": "更新错误日志", + "parameters": [ + { + "description": "更新错误日志", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysError" + } + } + ], + "responses": { + "200": { + "description": "更新成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } } }, "/sysExportTemplate/createSysExportTemplate": { @@ -4722,6 +6135,66 @@ "responses": {} } }, + "/sysExportTemplate/exportExcelByToken": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ExportExcelByToken" + ], + "summary": "导出表格", + "responses": {} + } + }, + "/sysExportTemplate/exportTemplate": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "导出表格模板", + "responses": {} + } + }, + "/sysExportTemplate/exportTemplateByToken": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "ExportTemplateByToken" + ], + "summary": "通过token导出表格模板", + "responses": {} + } + }, "/sysExportTemplate/findSysExportTemplate": { "get": { "security": [ @@ -4758,6 +6231,12 @@ "name": "dbName", "in": "query" }, + { + "type": "string", + "description": "自定义导入SQL", + "name": "importSql", + "in": "query" + }, { "type": "integer", "name": "limit", @@ -4774,6 +6253,12 @@ "name": "order", "in": "query" }, + { + "type": "string", + "description": "自定义导出SQL", + "name": "sql", + "in": "query" + }, { "type": "string", "description": "表名称", @@ -4850,6 +6335,12 @@ "name": "endCreatedAt", "in": "query" }, + { + "type": "string", + "description": "自定义导入SQL", + "name": "importSql", + "in": "query" + }, { "type": "string", "description": "关键字", @@ -4884,6 +6375,12 @@ "name": "pageSize", "in": "query" }, + { + "type": "string", + "description": "自定义导出SQL", + "name": "sql", + "in": "query" + }, { "type": "string", "name": "startCreatedAt", @@ -4944,6 +6441,63 @@ "responses": {} } }, + "/sysExportTemplate/previewSQL": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysExportTemplate" + ], + "summary": "预览最终生成的SQL(不执行查询,仅返回SQL字符串)", + "parameters": [ + { + "type": "string", + "description": "导出模板ID", + "name": "templateID", + "in": "query", + "required": true + }, + { + "type": "string", + "description": "查询参数编码字符串,参考 ExportExcel 组件", + "name": "params", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + } + ] + } + } + } + } + }, "/sysExportTemplate/updateSysExportTemplate": { "put": { "security": [ @@ -4982,56 +6536,6 @@ } } }, - "/sysOperationRecord/createSysOperationRecord": { - "post": { - "security": [ - { - "ApiKeyAuth": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "SysOperationRecord" - ], - "summary": "创建SysOperationRecord", - "parameters": [ - { - "description": "创建SysOperationRecord", - "name": "data", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/system.SysOperationRecord" - } - } - ], - "responses": { - "200": { - "description": "创建SysOperationRecord", - "schema": { - "allOf": [ - { - "$ref": "#/definitions/response.Response" - }, - { - "type": "object", - "properties": { - "msg": { - "type": "string" - } - } - } - ] - } - } - } - } - }, "/sysOperationRecord/deleteSysOperationRecord": { "delete": { "security": [ @@ -5806,6 +7310,415 @@ } } }, + "/sysVersion/deleteSysVersion": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "删除版本管理", + "parameters": [ + { + "description": "删除版本管理", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/system.SysVersion" + } + } + ], + "responses": { + "200": { + "description": "删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/deleteSysVersionByIds": { + "delete": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "批量删除版本管理", + "responses": { + "200": { + "description": "批量删除成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/downloadVersionJson": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "下载版本JSON数据", + "parameters": [ + { + "type": "string", + "description": "版本ID", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "下载成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/exportVersion": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "创建发版数据", + "parameters": [ + { + "description": "创建发版数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ExportVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "创建成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/findSysVersion": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "用id查询版本管理", + "parameters": [ + { + "type": "integer", + "description": "用id查询版本管理", + "name": "ID", + "in": "query", + "required": true + } + ], + "responses": { + "200": { + "description": "查询成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/system.SysVersion" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/getSysVersionList": { + "get": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "分页获取版本管理列表", + "parameters": [ + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "csv", + "name": "createdAtRange", + "in": "query" + }, + { + "type": "string", + "description": "关键字", + "name": "keyword", + "in": "query" + }, + { + "type": "integer", + "description": "页码", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "每页大小", + "name": "pageSize", + "in": "query" + }, + { + "type": "string", + "name": "versionCode", + "in": "query" + }, + { + "type": "string", + "name": "versionName", + "in": "query" + } + ], + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/response.PageResult" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/getSysVersionPublic": { + "get": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "不需要鉴权的版本管理接口", + "responses": { + "200": { + "description": "获取成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "data": { + "type": "object" + }, + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, + "/sysVersion/importVersion": { + "post": { + "security": [ + { + "ApiKeyAuth": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "SysVersion" + ], + "summary": "导入版本数据", + "parameters": [ + { + "description": "版本JSON数据", + "name": "data", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/request.ImportVersionRequest" + } + } + ], + "responses": { + "200": { + "description": "导入成功", + "schema": { + "allOf": [ + { + "$ref": "#/definitions/response.Response" + }, + { + "type": "object", + "properties": { + "msg": { + "type": "string" + } + } + } + ] + } + } + } + } + }, "/system/getServerInfo": { "post": { "security": [ @@ -5898,10 +7811,10 @@ "tags": [ "System" ], - "summary": "重启系统", + "summary": "重载系统", "responses": { "200": { - "description": "重启系统", + "description": "重载系统", "schema": { "allOf": [ { @@ -6518,6 +8431,71 @@ } }, "definitions": { + "book.Book": { + "type": "object", + "properties": { + "bookType": { + "type": "string" + }, + "commentCount": { + "type": "integer" + }, + "completionStatus": { + "type": "string" + }, + "coverUrl": { + "type": "string" + }, + "createdAt": { + "type": "string" + }, + "eraTag": { + "type": "string" + }, + "hotScore": { + "type": "integer" + }, + "id": { + "type": "integer" + }, + "intro": { + "type": "string" + }, + "publishStatus": { + "type": "string" + }, + "publishedAt": { + "type": "string" + }, + "publisher": { + "type": "string" + }, + "rating": { + "type": "number" + }, + "rawTxtUrl": { + "type": "string" + }, + "seriesId": { + "type": "integer" + }, + "seriesSort": { + "type": "integer" + }, + "subtitle": { + "type": "string" + }, + "title": { + "type": "string" + }, + "updatedAt": { + "type": "string" + }, + "wordCount": { + "type": "integer" + } + } + }, "common.JSONMap": { "type": "object", "additionalProperties": true @@ -6647,7 +8625,7 @@ "type": "integer" }, "open-captcha": { - "description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码", + "description": "防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码次数,如3代表错误三次后出现验证码", "type": "integer" }, "open-captcha-timeout": { @@ -6749,6 +8727,48 @@ } } }, + "config.MCP": { + "type": "object", + "properties": { + "addr": { + "type": "integer" + }, + "auth_header": { + "type": "string" + }, + "base_url": { + "type": "string" + }, + "message_path": { + "type": "string" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "request_timeout": { + "type": "integer" + }, + "separate": { + "type": "boolean" + }, + "sse_path": { + "description": "Deprecated fields kept for backward compatibility with older configs.", + "type": "string" + }, + "upstream_base_url": { + "type": "string" + }, + "url_prefix": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, "config.Minio": { "type": "object", "properties": { @@ -7204,6 +9224,14 @@ } ] }, + "mcp": { + "description": "MCP配置", + "allOf": [ + { + "$ref": "#/definitions/config.MCP" + } + ] + }, "minio": { "$ref": "#/definitions/config.Minio" }, @@ -7389,6 +9417,10 @@ "description": "数据库类型:mysql(默认)|sqlite|sqlserver|postgresql", "type": "string" }, + "disable-auto-migrate": { + "description": "自动迁移数据库表结构,生产环境建议设为false,手动迁移", + "type": "boolean" + }, "iplimit-count": { "type": "integer" }, @@ -7666,6 +9698,10 @@ "description": "服务器地址 例如 smtp.qq.com 请前往QQ或者你要发邮件的邮箱查看其smtp协议", "type": "string" }, + "is-loginauth": { + "description": "是否LoginAuth 是否使用LoginAuth认证方式(适用于IBM、微软邮箱服务器等)", + "type": "boolean" + }, "is-ssl": { "description": "是否SSL 是否开启SSL", "type": "boolean" @@ -8040,6 +10076,48 @@ } } }, + "request.ExportVersionRequest": { + "type": "object", + "required": [ + "versionCode", + "versionName" + ], + "properties": { + "apiIds": { + "description": "选中的API ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "dictIds": { + "description": "选中的字典ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "menuIds": { + "description": "选中的菜单ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "versionCode": { + "description": "版本号", + "type": "string" + }, + "versionName": { + "description": "版本名称", + "type": "string" + } + } + }, "request.GetAuthorityId": { "type": "object", "properties": { @@ -8061,6 +10139,10 @@ "request.GetUserList": { "type": "object", "properties": { + "desc": { + "description": "排序方式:升序false(默认)|降序true", + "type": "boolean" + }, "email": { "type": "string" }, @@ -8071,6 +10153,10 @@ "nickName": { "type": "string" }, + "orderKey": { + "description": "排序", + "type": "string" + }, "page": { "description": "页码", "type": "integer" @@ -8098,6 +10184,55 @@ } } }, + "request.ImportSysDictionaryRequest": { + "type": "object", + "required": [ + "json" + ], + "properties": { + "json": { + "description": "JSON字符串", + "type": "string" + } + } + }, + "request.ImportVersionRequest": { + "type": "object", + "required": [ + "version" + ], + "properties": { + "apis": { + "description": "API数据,直接复用SysApi", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysApi" + } + }, + "dictionaries": { + "description": "字典数据,直接复用SysDictionary", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, + "menus": { + "description": "菜单数据,直接复用SysBaseMenu", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysBaseMenu" + } + }, + "version": { + "description": "版本信息", + "allOf": [ + { + "$ref": "#/definitions/request.VersionInfo" + } + ] + } + } + }, "request.InitDB": { "type": "object", "required": [ @@ -8274,6 +10409,58 @@ } } }, + "request.SetApiAuthorities": { + "type": "object", + "properties": { + "authorityIds": { + "description": "角色ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "method": { + "description": "请求方法", + "type": "string" + }, + "path": { + "description": "API路径", + "type": "string" + } + } + }, + "request.SetMenuAuthorities": { + "type": "object", + "properties": { + "authorityIds": { + "description": "角色ID列表", + "type": "array", + "items": { + "type": "integer" + } + }, + "menuId": { + "description": "菜单ID", + "type": "integer" + } + } + }, + "request.SetRoleUsers": { + "type": "object", + "properties": { + "authorityId": { + "description": "角色ID", + "type": "integer" + }, + "userIds": { + "description": "用户ID列表", + "type": "array", + "items": { + "type": "integer" + } + } + } + }, "request.SetUserAuth": { "type": "object", "properties": { @@ -8357,6 +10544,39 @@ } } }, + "request.VersionInfo": { + "type": "object", + "required": [ + "code", + "name" + ], + "properties": { + "code": { + "description": "版本号", + "type": "string" + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "exportTime": { + "description": "导出时间", + "type": "string" + }, + "name": { + "description": "版本名称", + "type": "string" + } + } + }, + "response.BookResponse": { + "type": "object", + "properties": { + "book": { + "$ref": "#/definitions/book.Book" + } + } + }, "response.Email": { "type": "object", "properties": { @@ -8435,6 +10655,36 @@ } } }, + "response.PluginInfo": { + "type": "object", + "properties": { + "apis": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysApi" + } + }, + "dictionaries": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, + "menus": { + "type": "array", + "items": { + "$ref": "#/definitions/system.SysBaseMenu" + } + }, + "pluginName": { + "type": "string" + }, + "pluginType": { + "description": "web, server, full", + "type": "string" + } + } + }, "response.PolicyPathResponse": { "type": "object", "properties": { @@ -8654,6 +10904,10 @@ "title": { "description": "菜单名", "type": "string" + }, + "transitionType": { + "description": "路由切换动画", + "type": "string" } } }, @@ -8878,6 +11132,13 @@ "description": "主键ID", "type": "integer" }, + "children": { + "description": "子字典", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionary" + } + }, "createdAt": { "description": "创建时间", "type": "string" @@ -8890,6 +11151,10 @@ "description": "字典名(中)", "type": "string" }, + "parentID": { + "description": "父级字典ID", + "type": "integer" + }, "status": { "description": "状态", "type": "boolean" @@ -8917,10 +11182,21 @@ "description": "主键ID", "type": "integer" }, + "children": { + "description": "子字典详情", + "type": "array", + "items": { + "$ref": "#/definitions/system.SysDictionaryDetail" + } + }, "createdAt": { "description": "创建时间", "type": "string" }, + "disabled": { + "description": "禁用状态,根据status字段动态计算", + "type": "boolean" + }, "extend": { "description": "扩展值", "type": "string" @@ -8929,6 +11205,18 @@ "description": "展示值", "type": "string" }, + "level": { + "description": "层级深度,从0开始", + "type": "integer" + }, + "parentID": { + "description": "父级字典详情ID", + "type": "integer" + }, + "path": { + "description": "层级路径,如 \"1,2,3\"", + "type": "string" + }, "sort": { "description": "排序标记", "type": "integer" @@ -8951,6 +11239,45 @@ } } }, + "system.SysError": { + "type": "object", + "required": [ + "form" + ], + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "form": { + "description": "错误来源", + "type": "string" + }, + "info": { + "description": "错误内容", + "type": "string" + }, + "level": { + "type": "string" + }, + "solution": { + "description": "解决方案", + "type": "string" + }, + "status": { + "description": "处理状态:未处理/处理中/处理完成", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + } + } + }, "system.SysExportTemplate": { "type": "object", "properties": { @@ -8972,6 +11299,10 @@ "description": "数据库名称", "type": "string" }, + "importSql": { + "description": "自定义导入SQL", + "type": "string" + }, "joinTemplate": { "type": "array", "items": { @@ -8988,6 +11319,10 @@ "order": { "type": "string" }, + "sql": { + "description": "自定义导出SQL", + "type": "string" + }, "tableName": { "description": "表名称", "type": "string" @@ -9258,6 +11593,43 @@ } } }, + "system.SysVersion": { + "type": "object", + "required": [ + "versionCode", + "versionName" + ], + "properties": { + "ID": { + "description": "主键ID", + "type": "integer" + }, + "createdAt": { + "description": "创建时间", + "type": "string" + }, + "description": { + "description": "版本描述", + "type": "string" + }, + "updatedAt": { + "description": "更新时间", + "type": "string" + }, + "versionCode": { + "description": "版本号", + "type": "string" + }, + "versionData": { + "description": "版本数据", + "type": "string" + }, + "versionName": { + "description": "版本名称", + "type": "string" + } + } + }, "system.System": { "type": "object", "properties": { diff --git a/server/docs/swagger.yaml b/server/docs/swagger.yaml index 1a1f8cc..3e1719a 100644 --- a/server/docs/swagger.yaml +++ b/server/docs/swagger.yaml @@ -1,4 +1,47 @@ definitions: + book.Book: + properties: + bookType: + type: string + commentCount: + type: integer + completionStatus: + type: string + coverUrl: + type: string + createdAt: + type: string + eraTag: + type: string + hotScore: + type: integer + id: + type: integer + intro: + type: string + publishStatus: + type: string + publishedAt: + type: string + publisher: + type: string + rating: + type: number + rawTxtUrl: + type: string + seriesId: + type: integer + seriesSort: + type: integer + subtitle: + type: string + title: + type: string + updatedAt: + type: string + wordCount: + type: integer + type: object common.JSONMap: additionalProperties: true type: object @@ -85,7 +128,7 @@ definitions: description: 验证码长度 type: integer open-captcha: - description: 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码此数,如3代表错误三次后出现验证码 + description: 防爆破验证码开启此数,0代表每次登录都需要验证码,其他数字代表错误密码次数,如3代表错误三次后出现验证码 type: integer open-captcha-timeout: description: 防爆破验证码超时时间,单位:s(秒) @@ -153,6 +196,35 @@ definitions: description: 本地文件存储路径 type: string type: object + config.MCP: + properties: + addr: + type: integer + auth_header: + type: string + base_url: + type: string + message_path: + type: string + name: + type: string + path: + type: string + request_timeout: + type: integer + separate: + type: boolean + sse_path: + description: Deprecated fields kept for backward compatibility with older + configs. + type: string + upstream_base_url: + type: string + url_prefix: + type: string + version: + type: string + type: object config.Minio: properties: access-key-id: @@ -477,6 +549,10 @@ definitions: allOf: - $ref: '#/definitions/config.Local' description: oss + mcp: + allOf: + - $ref: '#/definitions/config.MCP' + description: MCP配置 minio: $ref: '#/definitions/config.Minio' mongo: @@ -608,6 +684,9 @@ definitions: db-type: description: 数据库类型:mysql(默认)|sqlite|sqlserver|postgresql type: string + disable-auto-migrate: + description: 自动迁移数据库表结构,生产环境建议设为false,手动迁移 + type: boolean iplimit-count: type: integer iplimit-time: @@ -802,6 +881,9 @@ definitions: host: description: 服务器地址 例如 smtp.qq.com 请前往QQ或者你要发邮件的邮箱查看其smtp协议 type: string + is-loginauth: + description: 是否LoginAuth 是否使用LoginAuth认证方式(适用于IBM、微软邮箱服务器等) + type: boolean is-ssl: description: 是否SSL 是否开启SSL type: boolean @@ -1074,6 +1156,36 @@ definitions: description: 每页大小 type: integer type: object + request.ExportVersionRequest: + properties: + apiIds: + description: 选中的API ID列表 + items: + type: integer + type: array + description: + description: 版本描述 + type: string + dictIds: + description: 选中的字典ID列表 + items: + type: integer + type: array + menuIds: + description: 选中的菜单ID列表 + items: + type: integer + type: array + versionCode: + description: 版本号 + type: string + versionName: + description: 版本名称 + type: string + required: + - versionCode + - versionName + type: object request.GetAuthorityId: properties: authorityId: @@ -1088,6 +1200,9 @@ definitions: type: object request.GetUserList: properties: + desc: + description: 排序方式:升序false(默认)|降序true + type: boolean email: type: string keyword: @@ -1095,6 +1210,9 @@ definitions: type: string nickName: type: string + orderKey: + description: 排序 + type: string page: description: 页码 type: integer @@ -1113,6 +1231,38 @@ definitions: type: integer type: array type: object + request.ImportSysDictionaryRequest: + properties: + json: + description: JSON字符串 + type: string + required: + - json + type: object + request.ImportVersionRequest: + properties: + apis: + description: API数据,直接复用SysApi + items: + $ref: '#/definitions/system.SysApi' + type: array + dictionaries: + description: 字典数据,直接复用SysDictionary + items: + $ref: '#/definitions/system.SysDictionary' + type: array + menus: + description: 菜单数据,直接复用SysBaseMenu + items: + $ref: '#/definitions/system.SysBaseMenu' + type: array + version: + allOf: + - $ref: '#/definitions/request.VersionInfo' + description: 版本信息 + required: + - version + type: object request.InitDB: properties: adminPassword: @@ -1241,6 +1391,42 @@ definitions: description: 更新时间 type: string type: object + request.SetApiAuthorities: + properties: + authorityIds: + description: 角色ID列表 + items: + type: integer + type: array + method: + description: 请求方法 + type: string + path: + description: API路径 + type: string + type: object + request.SetMenuAuthorities: + properties: + authorityIds: + description: 角色ID列表 + items: + type: integer + type: array + menuId: + description: 菜单ID + type: integer + type: object + request.SetRoleUsers: + properties: + authorityId: + description: 角色ID + type: integer + userIds: + description: 用户ID列表 + items: + type: integer + type: array + type: object request.SetUserAuth: properties: authorityId: @@ -1298,6 +1484,29 @@ definitions: description: 主键ID type: integer type: object + request.VersionInfo: + properties: + code: + description: 版本号 + type: string + description: + description: 版本描述 + type: string + exportTime: + description: 导出时间 + type: string + name: + description: 版本名称 + type: string + required: + - code + - name + type: object + response.BookResponse: + properties: + book: + $ref: '#/definitions/book.Book' + type: object response.Email: properties: body: @@ -1349,6 +1558,26 @@ definitions: total: type: integer type: object + response.PluginInfo: + properties: + apis: + items: + $ref: '#/definitions/system.SysApi' + type: array + dictionaries: + items: + $ref: '#/definitions/system.SysDictionary' + type: array + menus: + items: + $ref: '#/definitions/system.SysBaseMenu' + type: array + pluginName: + type: string + pluginType: + description: web, server, full + type: string + type: object response.PolicyPathResponse: properties: paths: @@ -1495,6 +1724,9 @@ definitions: title: description: 菜单名 type: string + transitionType: + description: 路由切换动画 + type: string type: object system.SysApi: properties: @@ -1651,6 +1883,11 @@ definitions: ID: description: 主键ID type: integer + children: + description: 子字典 + items: + $ref: '#/definitions/system.SysDictionary' + type: array createdAt: description: 创建时间 type: string @@ -1660,6 +1897,9 @@ definitions: name: description: 字典名(中) type: string + parentID: + description: 父级字典ID + type: integer status: description: 状态 type: boolean @@ -1679,15 +1919,32 @@ definitions: ID: description: 主键ID type: integer + children: + description: 子字典详情 + items: + $ref: '#/definitions/system.SysDictionaryDetail' + type: array createdAt: description: 创建时间 type: string + disabled: + description: 禁用状态,根据status字段动态计算 + type: boolean extend: description: 扩展值 type: string label: description: 展示值 type: string + level: + description: 层级深度,从0开始 + type: integer + parentID: + description: 父级字典详情ID + type: integer + path: + description: 层级路径,如 "1,2,3" + type: string sort: description: 排序标记 type: integer @@ -1704,6 +1961,34 @@ definitions: description: 字典值 type: string type: object + system.SysError: + properties: + ID: + description: 主键ID + type: integer + createdAt: + description: 创建时间 + type: string + form: + description: 错误来源 + type: string + info: + description: 错误内容 + type: string + level: + type: string + solution: + description: 解决方案 + type: string + status: + description: 处理状态:未处理/处理中/处理完成 + type: string + updatedAt: + description: 更新时间 + type: string + required: + - form + type: object system.SysExportTemplate: properties: ID: @@ -1719,6 +2004,9 @@ definitions: dbName: description: 数据库名称 type: string + importSql: + description: 自定义导入SQL + type: string joinTemplate: items: $ref: '#/definitions/system.JoinTemplate' @@ -1730,6 +2018,9 @@ definitions: type: string order: type: string + sql: + description: 自定义导出SQL + type: string tableName: description: 表名称 type: string @@ -1920,6 +2211,33 @@ definitions: description: 用户UUID type: string type: object + system.SysVersion: + properties: + ID: + description: 主键ID + type: integer + createdAt: + description: 创建时间 + type: string + description: + description: 版本描述 + type: string + updatedAt: + description: 更新时间 + type: string + versionCode: + description: 版本号 + type: string + versionData: + description: 版本数据 + type: string + versionName: + description: 版本名称 + type: string + required: + - versionCode + - versionName + type: object system.System: properties: config: @@ -1929,7 +2247,7 @@ info: contact: {} description: 使用gin+vue进行极速开发的全栈开发基础平台 title: Gin-Vue-Admin Swagger API接口文档 - version: v2.7.9-beta + version: v2.9.1 paths: /api/createApi: post: @@ -2157,6 +2475,41 @@ paths: summary: 分页获取API列表 tags: - SysApi + /api/getApiRoles: + get: + consumes: + - application/json + parameters: + - description: API路径 + in: query + name: path + required: true + type: string + - description: 请求方法 + in: query + name: method + required: true + type: string + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: true + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取拥有指定API权限的角色ID列表 + tags: + - SysApi /api/ignoreApi: post: consumes: @@ -2178,6 +2531,34 @@ paths: summary: 忽略API tags: - IgnoreApi + /api/setApiRoles: + post: + consumes: + - application/json + parameters: + - description: API路径、请求方法和角色ID列表 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.SetApiAuthorities' + produces: + - application/json + responses: + "200": + description: 设置成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 全量覆盖某API关联的角色列表 + tags: + - SysApi /api/syncApi: get: consumes: @@ -2413,6 +2794,37 @@ paths: summary: 分页获取角色列表 tags: - Authority + /authority/getUsersByAuthority: + get: + consumes: + - application/json + parameters: + - description: 角色ID + in: query + name: authorityId + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + type: integer + type: array + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取拥有指定角色的用户ID列表 + tags: + - Authority /authority/setDataAuthority: post: consumes: @@ -2441,6 +2853,34 @@ paths: summary: 设置角色资源权限 tags: - Authority + /authority/setRoleUsers: + post: + consumes: + - application/json + parameters: + - description: 角色ID和用户ID列表 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.SetRoleUsers' + produces: + - application/json + responses: + "200": + description: 设置成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 全量覆盖某角色关联的用户列表 + tags: + - Authority /authority/updateAuthority: put: consumes: @@ -2686,54 +3126,6 @@ paths: summary: 删除回滚记录 tags: - AutoCode - /autoCode/getColumn: - get: - consumes: - - application/json - produces: - - application/json - responses: - "200": - description: 获取当前表所有字段 - schema: - allOf: - - $ref: '#/definitions/response.Response' - - properties: - data: - additionalProperties: true - type: object - msg: - type: string - type: object - security: - - ApiKeyAuth: [] - summary: 获取当前表所有字段 - tags: - - AutoCode - /autoCode/getDB: - get: - consumes: - - application/json - produces: - - application/json - responses: - "200": - description: 获取当前所有数据库 - schema: - allOf: - - $ref: '#/definitions/response.Response' - - properties: - data: - additionalProperties: true - type: object - msg: - type: string - type: object - security: - - ApiKeyAuth: [] - summary: 获取当前所有数据库 - tags: - - AutoCode /autoCode/getMeta: post: consumes: @@ -2789,6 +3181,27 @@ paths: summary: 获取package tags: - AutoCodePackage + /autoCode/getPluginList: + get: + produces: + - application/json + responses: + "200": + description: 获取插件列表成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/response.PluginInfo' + type: array + type: object + security: + - ApiKeyAuth: [] + summary: 获取插件列表 + tags: + - AutoCodePlugin /autoCode/getSysHistory: post: consumes: @@ -2819,30 +3232,6 @@ paths: summary: 查询回滚记录 tags: - AutoCode - /autoCode/getTables: - get: - consumes: - - application/json - produces: - - application/json - responses: - "200": - description: 获取当前数据库所有表 - schema: - allOf: - - $ref: '#/definitions/response.Response' - - properties: - data: - additionalProperties: true - type: object - msg: - type: string - type: object - security: - - ApiKeyAuth: [] - summary: 获取当前数据库所有表 - tags: - - AutoCode /autoCode/getTemplates: get: consumes: @@ -2891,6 +3280,30 @@ paths: summary: 打包插件 tags: - AutoCodePlugin + /autoCode/initDictionary: + post: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 打包插件成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: true + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 打包插件 + tags: + - AutoCodePlugin /autoCode/initMenu: post: consumes: @@ -2935,8 +3348,7 @@ paths: - $ref: '#/definitions/response.Response' - properties: data: - items: - type: object + items: {} type: array msg: type: string @@ -3007,6 +3419,36 @@ paths: summary: 打包插件 tags: - AutoCodePlugin + /autoCode/removePlugin: + post: + parameters: + - description: 插件名称 + in: query + name: pluginName + required: true + type: string + - description: 插件类型 + in: query + name: pluginType + required: true + type: string + produces: + - application/json + responses: + "200": + description: 删除插件成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 删除插件 + tags: + - AutoCodePlugin /autoCode/rollback: post: consumes: @@ -3084,6 +3526,182 @@ paths: summary: 用户登录 tags: - Base + /book/createBook: + post: + consumes: + - application/json + parameters: + - description: 书籍信息 + in: body + name: data + required: true + schema: + $ref: '#/definitions/book.Book' + produces: + - application/json + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 创建书籍信息 + tags: + - Book + /book/deleteBook: + delete: + parameters: + - description: 主键ID + in: query + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 删除书籍信息 + tags: + - Book + /book/deleteBookByIds: + delete: + parameters: + - collectionFormat: csv + description: 主键ID数组 + in: query + items: + type: integer + name: ids + required: true + type: array + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 批量删除书籍信息 + tags: + - Book + /book/findBook: + get: + parameters: + - description: 主键ID + in: query + name: id + required: true + type: integer + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/response.BookResponse' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 查询书籍详情 + tags: + - Book + /book/getBookList: + get: + parameters: + - in: query + name: bookType + type: string + - in: query + name: completionStatus + type: string + - in: query + name: eraTag + type: string + - description: 关键字 + in: query + name: keyword + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + - in: query + name: publishStatus + type: string + - in: query + name: seriesId + type: integer + - in: query + name: title + type: string + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/response.PageResult' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 分页获取书籍列表 + tags: + - Book + /book/updateBook: + put: + parameters: + - description: 书籍信息 + in: body + name: data + required: true + schema: + $ref: '#/definitions/book.Book' + responses: + "200": + description: OK + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 更新书籍信息 + tags: + - Book /casbin/UpdateCasbin: post: consumes: @@ -4120,6 +4738,64 @@ paths: summary: 分页获取基础menu列表 tags: - Menu + /menu/getMenuRoles: + get: + consumes: + - application/json + parameters: + - description: 菜单ID + in: query + name: menuId + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: true + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取拥有指定菜单的角色ID列表 + tags: + - AuthorityMenu + /menu/setMenuRoles: + post: + consumes: + - application/json + parameters: + - description: 菜单ID和角色ID列表 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.SetMenuAuthorities' + produces: + - application/json + responses: + "200": + description: 设置成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 全量覆盖某菜单关联的角色列表 + tags: + - AuthorityMenu /menu/updateBaseMenu: post: consumes: @@ -4204,6 +4880,63 @@ paths: summary: 删除SysDictionary tags: - SysDictionary + /sysDictionary/exportSysDictionary: + get: + consumes: + - application/json + parameters: + - description: 主键ID + in: query + name: ID + type: integer + - description: 创建时间 + in: query + name: createdAt + type: string + - description: 描述 + in: query + name: desc + type: string + - description: 字典名(中) + in: query + name: name + type: string + - description: 父级字典ID + in: query + name: parentID + type: integer + - description: 状态 + in: query + name: status + type: boolean + - description: 字典名(英) + in: query + name: type + type: string + - description: 更新时间 + in: query + name: updatedAt + type: string + produces: + - application/json + responses: + "200": + description: 导出字典JSON + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: true + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 导出字典JSON(包含字典详情) + tags: + - SysDictionary /sysDictionary/findSysDictionary: get: consumes: @@ -4225,6 +4958,10 @@ paths: in: query name: name type: string + - description: 父级字典ID + in: query + name: parentID + type: integer - description: 状态 in: query name: status @@ -4261,6 +4998,11 @@ paths: get: consumes: - application/json + parameters: + - description: 字典名(中) + in: query + name: name + type: string produces: - application/json responses: @@ -4280,6 +5022,34 @@ paths: summary: 分页获取SysDictionary列表 tags: - SysDictionary + /sysDictionary/importSysDictionary: + post: + consumes: + - application/json + parameters: + - description: 字典JSON数据 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.ImportSysDictionaryRequest' + produces: + - application/json + responses: + "200": + description: 导入字典 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 导入字典JSON(包含字典详情) + tags: + - SysDictionary /sysDictionary/updateSysDictionary: put: consumes: @@ -4377,6 +5147,10 @@ paths: in: query name: createdAt type: string + - description: 禁用状态,根据status字段动态计算 + in: query + name: disabled + type: boolean - description: 扩展值 in: query name: extend @@ -4385,6 +5159,18 @@ paths: in: query name: label type: string + - description: 层级深度,从0开始 + in: query + name: level + type: integer + - description: 父级字典详情ID + in: query + name: parentID + type: integer + - description: 层级路径,如 "1,2,3" + in: query + name: path + type: string - description: 排序标记 in: query name: sort @@ -4425,6 +5211,138 @@ paths: summary: 用id查询SysDictionaryDetail tags: - SysDictionaryDetail + /sysDictionaryDetail/getDictionaryDetailsByParent: + get: + consumes: + - application/json + parameters: + - description: 是否包含子级数据 + in: query + name: includeChildren + type: boolean + - description: 父级字典详情ID,为空时获取顶级 + in: query + name: parentID + type: integer + - description: 字典ID + in: query + name: sysDictionaryID + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 获取字典详情列表 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/system.SysDictionaryDetail' + type: array + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 根据父级ID获取字典详情 + tags: + - SysDictionaryDetail + /sysDictionaryDetail/getDictionaryPath: + get: + consumes: + - application/json + parameters: + - description: 字典详情ID + in: query + name: id + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 获取字典详情路径 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/system.SysDictionaryDetail' + type: array + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取字典详情的完整路径 + tags: + - SysDictionaryDetail + /sysDictionaryDetail/getDictionaryTreeList: + get: + consumes: + - application/json + parameters: + - description: 字典ID + in: query + name: sysDictionaryID + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 获取字典详情树形结构 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/system.SysDictionaryDetail' + type: array + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 获取字典详情树形结构 + tags: + - SysDictionaryDetail + /sysDictionaryDetail/getDictionaryTreeListByType: + get: + consumes: + - application/json + parameters: + - description: 字典类型 + in: query + name: type + required: true + type: string + produces: + - application/json + responses: + "200": + description: 获取字典详情树形结构 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + items: + $ref: '#/definitions/system.SysDictionaryDetail' + type: array + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 根据字典类型获取字典详情树形结构 + tags: + - SysDictionaryDetail /sysDictionaryDetail/getSysDictionaryDetailList: get: consumes: @@ -4438,6 +5356,10 @@ paths: in: query name: createdAt type: string + - description: 禁用状态,根据status字段动态计算 + in: query + name: disabled + type: boolean - description: 扩展值 in: query name: extend @@ -4450,6 +5372,10 @@ paths: in: query name: label type: string + - description: 层级深度,用于查询指定层级的数据 + in: query + name: level + type: integer - description: 页码 in: query name: page @@ -4458,6 +5384,14 @@ paths: in: query name: pageSize type: integer + - description: 父级字典详情ID,用于查询指定父级下的子项 + in: query + name: parentID + type: integer + - description: 层级路径,如 "1,2,3" + in: query + name: path + type: string - description: 排序标记 in: query name: sort @@ -4525,18 +5459,215 @@ paths: summary: 更新SysDictionaryDetail tags: - SysDictionaryDetail - /sysExportTemplate/ExportTemplate: - get: + /sysError/createSysError: + post: + consumes: + - application/json + parameters: + - description: 创建错误日志 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysError' + produces: + - application/json + responses: + "200": + description: 创建成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 创建错误日志 + tags: + - SysError + /sysError/deleteSysError: + delete: + consumes: + - application/json + parameters: + - description: 删除错误日志 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysError' + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 删除错误日志 + tags: + - SysError + /sysError/deleteSysErrorByIds: + delete: consumes: - application/json produces: - application/json - responses: {} + responses: + "200": + description: 批量删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object security: - ApiKeyAuth: [] - summary: 导出表格模板 + summary: 批量删除错误日志 tags: - - SysExportTemplate + - SysError + /sysError/findSysError: + get: + consumes: + - application/json + parameters: + - description: 用id查询错误日志 + in: query + name: ID + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/system.SysError' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 用id查询错误日志 + tags: + - SysError + /sysError/getSysErrorList: + get: + consumes: + - application/json + parameters: + - collectionFormat: csv + in: query + items: + type: string + name: createdAtRange + type: array + - in: query + name: form + type: string + - in: query + name: info + type: string + - description: 关键字 + in: query + name: keyword + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/response.PageResult' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 分页获取错误日志列表 + tags: + - SysError + /sysError/getSysErrorSolution: + get: + consumes: + - application/json + parameters: + - description: 错误日志ID + in: query + name: id + required: true + type: string + produces: + - application/json + responses: + "200": + description: 处理已提交 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 根据ID触发处理:标记为处理中,1分钟后自动改为处理完成 + tags: + - SysError + /sysError/updateSysError: + put: + consumes: + - application/json + parameters: + - description: 更新错误日志 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysError' + produces: + - application/json + responses: + "200": + description: 更新成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 更新错误日志 + tags: + - SysError /sysExportTemplate/createSysExportTemplate: post: consumes: @@ -4618,6 +5749,42 @@ paths: summary: 导出表格 tags: - SysExportTemplate + /sysExportTemplate/exportExcelByToken: + get: + consumes: + - application/json + produces: + - application/json + responses: {} + security: + - ApiKeyAuth: [] + summary: 导出表格 + tags: + - ExportExcelByToken + /sysExportTemplate/exportTemplate: + get: + consumes: + - application/json + produces: + - application/json + responses: {} + security: + - ApiKeyAuth: [] + summary: 导出表格模板 + tags: + - SysExportTemplate + /sysExportTemplate/exportTemplateByToken: + get: + consumes: + - application/json + produces: + - application/json + responses: {} + security: + - ApiKeyAuth: [] + summary: 通过token导出表格模板 + tags: + - ExportTemplateByToken /sysExportTemplate/findSysExportTemplate: get: consumes: @@ -4635,6 +5802,10 @@ paths: in: query name: dbName type: string + - description: 自定义导入SQL + in: query + name: importSql + type: string - in: query name: limit type: integer @@ -4645,6 +5816,10 @@ paths: - in: query name: order type: string + - description: 自定义导出SQL + in: query + name: sql + type: string - description: 表名称 in: query name: tableName @@ -4693,6 +5868,10 @@ paths: - in: query name: endCreatedAt type: string + - description: 自定义导入SQL + in: query + name: importSql + type: string - description: 关键字 in: query name: keyword @@ -4715,6 +5894,10 @@ paths: in: query name: pageSize type: integer + - description: 自定义导出SQL + in: query + name: sql + type: string - in: query name: startCreatedAt type: string @@ -4758,6 +5941,39 @@ paths: summary: 导入表格 tags: - SysImportTemplate + /sysExportTemplate/previewSQL: + get: + consumes: + - application/json + parameters: + - description: 导出模板ID + in: query + name: templateID + required: true + type: string + - description: 查询参数编码字符串,参考 ExportExcel 组件 + in: query + name: params + type: string + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + additionalProperties: + type: string + type: object + type: object + security: + - ApiKeyAuth: [] + summary: 预览最终生成的SQL(不执行查询,仅返回SQL字符串) + tags: + - SysExportTemplate /sysExportTemplate/updateSysExportTemplate: put: consumes: @@ -4781,34 +5997,6 @@ paths: summary: 更新导出模板 tags: - SysExportTemplate - /sysOperationRecord/createSysOperationRecord: - post: - consumes: - - application/json - parameters: - - description: 创建SysOperationRecord - in: body - name: data - required: true - schema: - $ref: '#/definitions/system.SysOperationRecord' - produces: - - application/json - responses: - "200": - description: 创建SysOperationRecord - schema: - allOf: - - $ref: '#/definitions/response.Response' - - properties: - msg: - type: string - type: object - security: - - ApiKeyAuth: [] - summary: 创建SysOperationRecord - tags: - - SysOperationRecord /sysOperationRecord/deleteSysOperationRecord: delete: consumes: @@ -5267,6 +6455,238 @@ paths: summary: 更新参数 tags: - SysParams + /sysVersion/deleteSysVersion: + delete: + consumes: + - application/json + parameters: + - description: 删除版本管理 + in: body + name: data + required: true + schema: + $ref: '#/definitions/system.SysVersion' + produces: + - application/json + responses: + "200": + description: 删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 删除版本管理 + tags: + - SysVersion + /sysVersion/deleteSysVersionByIds: + delete: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 批量删除成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 批量删除版本管理 + tags: + - SysVersion + /sysVersion/downloadVersionJson: + get: + consumes: + - application/json + parameters: + - description: 版本ID + in: query + name: ID + required: true + type: string + produces: + - application/json + responses: + "200": + description: 下载成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + type: object + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 下载版本JSON数据 + tags: + - SysVersion + /sysVersion/exportVersion: + post: + consumes: + - application/json + parameters: + - description: 创建发版数据 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.ExportVersionRequest' + produces: + - application/json + responses: + "200": + description: 创建成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 创建发版数据 + tags: + - SysVersion + /sysVersion/findSysVersion: + get: + consumes: + - application/json + parameters: + - description: 用id查询版本管理 + in: query + name: ID + required: true + type: integer + produces: + - application/json + responses: + "200": + description: 查询成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/system.SysVersion' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 用id查询版本管理 + tags: + - SysVersion + /sysVersion/getSysVersionList: + get: + consumes: + - application/json + parameters: + - collectionFormat: csv + in: query + items: + type: string + name: createdAtRange + type: array + - description: 关键字 + in: query + name: keyword + type: string + - description: 页码 + in: query + name: page + type: integer + - description: 每页大小 + in: query + name: pageSize + type: integer + - in: query + name: versionCode + type: string + - in: query + name: versionName + type: string + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + $ref: '#/definitions/response.PageResult' + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 分页获取版本管理列表 + tags: + - SysVersion + /sysVersion/getSysVersionPublic: + get: + consumes: + - application/json + produces: + - application/json + responses: + "200": + description: 获取成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + data: + type: object + msg: + type: string + type: object + summary: 不需要鉴权的版本管理接口 + tags: + - SysVersion + /sysVersion/importVersion: + post: + consumes: + - application/json + parameters: + - description: 版本JSON数据 + in: body + name: data + required: true + schema: + $ref: '#/definitions/request.ImportVersionRequest' + produces: + - application/json + responses: + "200": + description: 导入成功 + schema: + allOf: + - $ref: '#/definitions/response.Response' + - properties: + msg: + type: string + type: object + security: + - ApiKeyAuth: [] + summary: 导入版本数据 + tags: + - SysVersion /system/getServerInfo: post: produces: @@ -5316,7 +6736,7 @@ paths: - application/json responses: "200": - description: 重启系统 + description: 重载系统 schema: allOf: - $ref: '#/definitions/response.Response' @@ -5326,7 +6746,7 @@ paths: type: object security: - ApiKeyAuth: [] - summary: 重启系统 + summary: 重载系统 tags: - System /system/setSystemConfig: diff --git a/server/model/book/book.go b/server/model/book/book.go index 6ae9df9..7dc73e8 100644 --- a/server/model/book/book.go +++ b/server/model/book/book.go @@ -18,8 +18,6 @@ const ( BookPublishStatusDraft = "draft" BookPublishStatusOffShelf = "off_shelf" BookPublishStatusOnShelf = "on_shelf" - BookAuthorStatusEnabled = "enabled" - BookAuthorStatusDisabled = "disabled" BookCommentStatusNormal = "normal" BookCommentStatusHidden = "hidden" ) diff --git a/server/model/book/book_author.go b/server/model/book/book_author.go index d81df88..fef30e8 100644 --- a/server/model/book/book_author.go +++ b/server/model/book/book_author.go @@ -3,7 +3,7 @@ package book type BookAuthor struct { HardDeleteModel Name string `json:"name" form:"name" gorm:"type:varchar(128);not null;uniqueIndex:uk_book_author_name;comment:作者名称"` - AuthorStatus string `json:"authorStatus" form:"authorStatus" gorm:"type:varchar(32);not null;default:enabled;index;comment:作者状态字典值,对应 book_author_status"` + AuthorStatus string `json:"authorStatus" form:"authorStatus" gorm:"type:varchar(32);not null;default:enabled;index;comment:作者启用状态字典值,对应 common_enabled_status"` Intro string `json:"intro" form:"intro" gorm:"type:text;comment:作者简介"` CoverUrl string `json:"coverUrl" form:"coverUrl" gorm:"type:varchar(500);comment:作者头像或封面 URL"` } diff --git a/server/model/book/response/book.go b/server/model/book/response/book.go index 61a8a97..ca1c868 100644 --- a/server/model/book/response/book.go +++ b/server/model/book/response/book.go @@ -8,9 +8,17 @@ type BookResponse struct { type BookAuthorResponse struct { BookAuthor book.BookAuthor `json:"bookAuthor"` } +type BookAuthorListItem struct { + book.BookAuthor `gorm:"embedded"` + AuthorName string `json:"authorName" gorm:"column:author_name"` +} type BookAuthorRelationResponse struct { BookAuthorRelation book.BookAuthorRelation `json:"bookAuthorRelation"` } +type BookAuthorRelationListItem struct { + book.BookAuthorRelation `gorm:"embedded"` + AuthorName string `json:"authorName" gorm:"column:author_name"` +} type BookChapterResponse struct { BookChapter book.BookChapter `json:"bookChapter"` } diff --git a/server/model/common/status.go b/server/model/common/status.go new file mode 100644 index 0000000..4759b7d --- /dev/null +++ b/server/model/common/status.go @@ -0,0 +1,6 @@ +package common + +const ( + CommonEnabledStatusEnabled = "enabled" + CommonEnabledStatusDisabled = "disabled" +) diff --git a/server/service/book/book_author.go b/server/service/book/book_author.go index 7f8b804..bc63b3a 100644 --- a/server/service/book/book_author.go +++ b/server/service/book/book_author.go @@ -4,6 +4,7 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/book" bookReq "github.com/flipped-aurora/gin-vue-admin/server/model/book/request" + bookRes "github.com/flipped-aurora/gin-vue-admin/server/model/book/response" commonReq "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" ) @@ -36,7 +37,7 @@ func (s *BookAuthorService) GetBookAuthor(id uint) (item book.BookAuthor, err er return } -func (s *BookAuthorService) GetBookAuthorInfoList(info bookReq.BookAuthorSearch) (list []book.BookAuthor, total int64, err error) { +func (s *BookAuthorService) GetBookAuthorInfoList(info bookReq.BookAuthorSearch) (list []bookRes.BookAuthorListItem, total int64, err error) { db := global.GVA_DB.Model(&book.BookAuthor{}) if info.Name != "" { db = db.Where("name LIKE ?", "%"+info.Name+"%") @@ -51,6 +52,6 @@ func (s *BookAuthorService) GetBookAuthorInfoList(info bookReq.BookAuthorSearch) if err != nil { return } - err = db.Scopes(paginate(info.PageInfo)).Order("id desc").Find(&list).Error + err = db.Select("book_author.*, book_author.name AS author_name").Scopes(paginate(info.PageInfo)).Order("id desc").Scan(&list).Error return } diff --git a/server/service/book/book_author_list_test.go b/server/service/book/book_author_list_test.go new file mode 100644 index 0000000..df4ddc4 --- /dev/null +++ b/server/service/book/book_author_list_test.go @@ -0,0 +1,70 @@ +package book + +import ( + "testing" + + "github.com/flipped-aurora/gin-vue-admin/server/global" + "github.com/flipped-aurora/gin-vue-admin/server/model/book" + bookReq "github.com/flipped-aurora/gin-vue-admin/server/model/book/request" + commonReq "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" + "github.com/glebarez/sqlite" + "github.com/stretchr/testify/require" + "gorm.io/gorm" +) + +func setupBookAuthorListTestDB(t *testing.T) { + t.Helper() + + db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) + require.NoError(t, err) + require.NoError(t, db.AutoMigrate(&book.BookAuthor{}, &book.BookAuthorRelation{})) + + global.GVA_DB = db + t.Cleanup(func() { + global.GVA_DB = nil + }) +} + +func TestBookAuthorService_GetBookAuthorInfoListReturnsAuthorName(t *testing.T) { + setupBookAuthorListTestDB(t) + + require.NoError(t, global.GVA_DB.Create(&book.BookAuthor{ + Name: "鲁迅", + AuthorStatus: "enabled", + }).Error) + + list, total, err := (&BookAuthorService{}).GetBookAuthorInfoList(bookReq.BookAuthorSearch{ + PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, + }) + require.NoError(t, err) + require.EqualValues(t, 1, total) + require.Len(t, list, 1) + require.Equal(t, "鲁迅", list[0].Name) + require.Equal(t, "鲁迅", list[0].AuthorName) +} + +func TestBookAuthorRelationService_GetBookAuthorRelationInfoListReturnsAuthorName(t *testing.T) { + setupBookAuthorListTestDB(t) + + author := book.BookAuthor{Name: "沈从文", AuthorStatus: "enabled"} + require.NoError(t, global.GVA_DB.Create(&author).Error) + require.NoError(t, global.GVA_DB.Create(&book.BookAuthorRelation{ + BookID: 11, + AuthorID: author.ID, + AuthorSort: 1, + }).Error) + + list, total, err := (&BookAuthorRelationService{}).GetBookAuthorRelationInfoList(bookReq.BookAuthorRelationSearch{ + PageInfo: commonReq.PageInfo{Page: 1, PageSize: 10}, + BookID: uintPtr(11), + }) + require.NoError(t, err) + require.EqualValues(t, 1, total) + require.Len(t, list, 1) + require.Equal(t, author.ID, list[0].AuthorID) + require.Equal(t, "沈从文", list[0].AuthorName) +} + +func uintPtr(v uint) *uint { + return &v +} diff --git a/server/service/book/book_author_relation.go b/server/service/book/book_author_relation.go index 8ceb545..4055810 100644 --- a/server/service/book/book_author_relation.go +++ b/server/service/book/book_author_relation.go @@ -4,6 +4,7 @@ import ( "github.com/flipped-aurora/gin-vue-admin/server/global" "github.com/flipped-aurora/gin-vue-admin/server/model/book" bookReq "github.com/flipped-aurora/gin-vue-admin/server/model/book/request" + bookRes "github.com/flipped-aurora/gin-vue-admin/server/model/book/response" commonReq "github.com/flipped-aurora/gin-vue-admin/server/model/common/request" ) @@ -37,18 +38,22 @@ func (s *BookAuthorRelationService) GetBookAuthorRelation(id uint) (item book.Bo return } -func (s *BookAuthorRelationService) GetBookAuthorRelationInfoList(info bookReq.BookAuthorRelationSearch) (list []book.BookAuthorRelation, total int64, err error) { - db := global.GVA_DB.Model(&book.BookAuthorRelation{}) +func (s *BookAuthorRelationService) GetBookAuthorRelationInfoList(info bookReq.BookAuthorRelationSearch) (list []bookRes.BookAuthorRelationListItem, total int64, err error) { + db := global.GVA_DB.Table("book_author_relation AS bar") if info.BookID != nil { - db = db.Where("book_id = ?", *info.BookID) + db = db.Where("bar.book_id = ?", *info.BookID) } if info.AuthorID != nil { - db = db.Where("author_id = ?", *info.AuthorID) + db = db.Where("bar.author_id = ?", *info.AuthorID) } err = db.Count(&total).Error if err != nil { return } - err = db.Scopes(paginate(info.PageInfo)).Order("book_id asc, author_sort asc, id desc").Find(&list).Error + err = db.Select("bar.*, ba.name AS author_name"). + Joins("LEFT JOIN book_author AS ba ON ba.id = bar.author_id"). + Scopes(paginate(info.PageInfo)). + Order("bar.book_id asc, bar.author_sort asc, bar.id desc"). + Scan(&list).Error return } diff --git a/server/service/book/validation.go b/server/service/book/validation.go index a86f430..3b5558e 100644 --- a/server/service/book/validation.go +++ b/server/service/book/validation.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/flipped-aurora/gin-vue-admin/server/model/book" + commonModel "github.com/flipped-aurora/gin-vue-admin/server/model/common" ) func validateBook(item book.Book) error { @@ -59,8 +60,8 @@ var validBookPublishStatuses = map[string]bool{ } var validBookAuthorStatuses = map[string]bool{ - book.BookAuthorStatusEnabled: true, - book.BookAuthorStatusDisabled: true, + commonModel.CommonEnabledStatusEnabled: true, + commonModel.CommonEnabledStatusDisabled: true, } var validBookCommentStatuses = map[string]bool{ diff --git a/server/service/book/validation_test.go b/server/service/book/validation_test.go index 15086a4..f9856eb 100644 --- a/server/service/book/validation_test.go +++ b/server/service/book/validation_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/flipped-aurora/gin-vue-admin/server/model/book" + commonModel "github.com/flipped-aurora/gin-vue-admin/server/model/common" ) func TestValidateBookRejectsOutOfRangeAggregates(t *testing.T) { @@ -51,6 +52,15 @@ func TestValidateBookAuthorRejectsInvalidStatus(t *testing.T) { assertValidationErrorContains(t, err, "authorStatus") } +func TestValidateBookAuthorAcceptsCommonEnabledStatus(t *testing.T) { + if err := validateBookAuthor(book.BookAuthor{AuthorStatus: commonModel.CommonEnabledStatusEnabled}); err != nil { + t.Fatalf("validateBookAuthor enabled error = %v", err) + } + if err := validateBookAuthor(book.BookAuthor{AuthorStatus: commonModel.CommonEnabledStatusDisabled}); err != nil { + t.Fatalf("validateBookAuthor disabled error = %v", err) + } +} + func TestApplyBookAuthorRelationDefaults(t *testing.T) { item := applyBookAuthorRelationDefaults(book.BookAuthorRelation{}) if item.AuthorSort != 1 { diff --git a/server/source/system/dictionary.go b/server/source/system/dictionary.go index 8d498db..ee99b71 100644 --- a/server/source/system/dictionary.go +++ b/server/source/system/dictionary.go @@ -50,7 +50,7 @@ func (i *initDict) InitializeData(ctx context.Context) (next context.Context, er {Name: "数据库浮点型", Type: "float64", Status: &True, Desc: "数据库浮点型"}, {Name: "数据库字符串", Type: "string", Status: &True, Desc: "数据库字符串"}, {Name: "数据库bool类型", Type: "bool", Status: &True, Desc: "数据库bool类型"}, - {Name: "作者状态", Type: "book_author_status", Status: &True, Desc: "作者状态字典"}, + {Name: "通用启用状态", Type: "common_enabled_status", Status: &True, Desc: "通用启用禁用状态字典"}, {Name: "书籍评论状态", Type: "book_comment_status", Status: &True, Desc: "书籍评论状态字典"}, {Name: "书籍完结状态", Type: "book_completion_status", Status: &True, Desc: "书籍完结状态字典"}, {Name: "书籍时代标签", Type: "book_era_tag", Status: &True, Desc: "书籍时代标签字典"},