# KT Template Online API 本文是当前 API 的人工索引。字段细节、Swagger 示例和 DTO 以运行态 Swagger/Knife4j 为准: - 全量 Swagger:`/api` - OpenAPI JSON:`/api-json` - Admin 分组:`/api/admin` - QQBot 分组:`/api/qqbot` - WordPress 分组:`/api/wordpress` - 基础能力分组:`/api/basic` ## 通用约定 后端固定监听 `48085`。根路径 `GET /` 重定向到 `/api#/`。 除文件下载、SSE、反向 WebSocket 等特殊接口外,业务接口统一返回: ```json { "code": 200, "msg": "操作成功", "data": {} } ``` 错误响应统一把 `err` 输出为字符串: ```json { "code": 400, "msg": "操作失败", "err": "错误原因" } ``` ### 认证 Admin、Component、Dict、MinIO、Blog 管理、WordPress 管理和 QQBot 管理接口默认需要后台登录态。 支持两种 access token 传递方式: - `Authorization: Bearer ` - 登录接口写入的 httpOnly `admin_access_token` cookie 公开接口包括 `/auth/login`、`/auth/refresh`、`/auth/logout`、部分 Blog public 接口和根路径。具体以 Controller 上的 `@Public()` 为准。 ### ID 与时间 - 后台主键使用 Snowflake 数字 ID,接口按字符串返回,避免 JavaScript 长整型精度丢失。 - DTO/Entity 需要后端格式化的时间字段使用 `@FormatDateTime()`,输出格式为 `YYYY-MM-DD HH:mm:ss`。 - `POST */save` 默认会删除请求体里的 `id`,防止新增接口误用前端主键。 ## 环境变量分组 | 分组 | 关键变量 | | --- | --- | | MySQL | `DB_HOST`、`DB_PORT`、`DB_USERNAME`、`DB_PASSWORD`、`DB_DATABASE`、`DB_SYNC` | | MinIO | `MINIO_ENDPOINT`、`MINIO_PORT`、`MINIO_ACCESS_KEY`、`MINIO_SECRET_KEY`、`MINIO_BUCKET` | | Admin | `ADMIN_TOKEN_SECRET`、`ADMIN_COOKIE_SECURE`、`SNOWFLAKE_WORKER_ID`、`SNOWFLAKE_DATACENTER_ID` | | WordPress | `WORDPRESS_BASE_URL`、`WORDPRESS_HOST_HEADER`、`WORDPRESS_ADMIN_USERNAME`、`WORDPRESS_ADMIN_PASSWORD` | | Loki | `LOG_LEVEL`、`LOG_APP_NAME`、`LOKI_URL`、`LOKI_QUERY_HOST`、`LOKI_QUERY_SELECTOR` | | QQBot | `QQBOT_ENABLED`、`QQBOT_REVERSE_WS_PATH`、`QQBOT_REVERSE_WS_TOKEN`、`QQBOT_EVENT_BUS` | | NapCat | `NAPCAT_WEBUI_BASE_URL`、`NAPCAT_WEBUI_TOKEN`、`QQBOT_NAPCAT_*` | | MQTT | `MQTT_URL`、`MQTT_USERNAME`、`MQTT_PASSWORD`、`MQTT_CLIENT_ID` | | BangDream | `BANGDREAM_TSUGU_MAIN_SERVER`、`BANGDREAM_TSUGU_DISPLAYED_SERVERS`、`BANGDREAM_TSUGU_CACHE_ROOT` | | FF14 Market | `FF14_XIVAPI_BASE_URL`、`FF14_UNIVERSALIS_BASE_URL`、`FF14_DEFAULT_WORLD` | | FFLogs | `FFLOGS_GRAPHQL_URL`、`FFLOGS_TOKEN_URL`、`FFLOGS_CLIENT_ID`、`FFLOGS_CLIENT_SECRET` | 真实密码、Token、OAuth secret 和生产 env 不提交到 Git。 ## Admin 与基础后台 ### Auth / User | 方法 | 路径 | 说明 | | --- | --- | --- | | `POST` | `/auth/login` | 后台登录,返回 accessToken、用户信息和 WordPress 自动登录状态,并写入 httpOnly cookie | | `POST` | `/auth/refresh` | 通过 refresh token cookie 刷新 accessToken | | `POST` | `/auth/logout` | 清理 Admin 与 WordPress 登录 cookie | | `GET` | `/auth/codes` | 获取当前用户按钮权限码 | | `GET` | `/user/info` | 获取当前用户信息 | `/auth/login` 会尝试用 env 中的 WordPress 管理员账号建立 WordPress 登录态。WordPress 不可用时,Admin 主登录仍成功,返回 `wordpressAuth=null`、`wordpressAvailable=false`,菜单和权限码会过滤 Blog 管理入口。 ### Menu / Role / Dept / User Manage | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/menu/all` | 当前用户菜单 | | `GET` | `/system/menu/list` | 系统菜单树 | | `GET` | `/system/menu/name-exists` | 菜单 name 重名校验 | | `GET` | `/system/menu/path-exists` | 菜单 path 重名校验 | | `POST` | `/system/menu` | 新增菜单 | | `PUT` | `/system/menu/:id` | 更新菜单 | | `DELETE` | `/system/menu/:id` | 删除菜单及子菜单 | | `GET` | `/system/role/list` | 角色分页 | | `POST` | `/system/role` | 新增角色 | | `PUT` | `/system/role/:id` | 更新角色 | | `DELETE` | `/system/role/:id` | 删除角色 | | `GET` | `/system/dept/list` | 部门树 | | `POST` | `/system/dept` | 新增部门 | | `PUT` | `/system/dept/:id` | 更新部门 | | `DELETE` | `/system/dept/:id` | 删除部门 | | `GET` | `/system/user/list` | 用户分页 | | `POST` | `/system/user` | 新增用户 | | `PUT` | `/system/user/:id` | 更新用户 | | `DELETE` | `/system/user/:id` | 删除用户 | ### Dict | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/dict/list` | 字典项分页,支持 `dictCode`、`keyword`、`label`、`value`、`childrenCode`、`status` | | `GET` | `/dict/tree` | 兼容树形字典视图 | | `GET` | `/dict/groups` | 字典编码分组列表,适合左右表左侧分组 | | `GET` | `/dict/codes` | 字典编码选项 | | `GET` | `/dict/getDictByKey` | 按 `dictKey` 获取启用字典项 | | `GET` | `/dict/getComponentDictByType` | 按组件一级类型查二级类型 | | `POST` | `/dict/save` | 新增字典项 | | `POST` | `/dict/update` | 更新字典项 | | `DELETE` | `/dict/:id` | 物理删除字典项 | | `POST` | `/dict/toggle` | 启停字典项 | 字典核心字段: | 字段 | 说明 | | --- | --- | | `dictCode` | 字典分组,例如 `COMPONENT_TYPE`、`BANGDREAM_SERVER_ALIAS` | | `label` | 展示文本 | | `value` | 字典值 | | `childrenCode` | 关联子分组编码 | | `sort` | 排序 | | `status` | `1` 启用 | ### Component 组件接口保持 `/component/*` 路径兼容,但数据表为 `admin_component`。 | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/component/allList` | 全量组件 | | `GET` | `/component/list` | 组件分页,支持 `pageNo`、`pageSize`、`name`、`type`、`componentType` | | `GET` | `/component/detail?id=` | 组件详情 | | `POST` | `/component/save` | 新增组件 | | `POST` | `/component/update` | 更新组件 | | `POST` | `/component/remove?id=` | 逻辑删除组件 | ### Timezone / Upload / Demo | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/timezone/getTimezoneOptions` | 时区选项 | | `GET` | `/timezone/getTimezone` | 当前用户时区 | | `POST` | `/timezone/setTimezone` | 设置当前用户时区 | | `POST` | `/upload` | Vben 上传适配,实际写入 MinIO | | `GET` | `/table/list` | Vben 示例表格 | | `GET` | `/status` | 状态码测试 | | `GET` | `/demo/bigint` | BigInt JSON 测试 | | `GET` | `/test` | GET 测试 | | `POST` | `/test` | POST 测试 | ## 系统日志 后端通过 `nestjs-pino` 输出结构化日志。配置 Loki 后,Admin 日志页面通过后端代理查询,不直连 Loki。 | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/system/logs` | 日志分页,支持 `level`、`keyword`、`context`、`path`、`requestId`、`startTime`、`endTime`、`rangeMinutes` | | `GET` | `/system/logs/summary` | 按级别统计 | | `GET` | `/system/logs/levels` | 日志级别选项 | | `GET` | `/system/logs/status` | Loki 查询配置状态 | 日志行包含 `timestamp`、`level`、`message`、`method`、`path`、`statusCode`、`durationMs`、`requestId`、`raw` 等字段。 ## Blog 本地内容 `/blog/*` 是本地博客内容能力,供 `Vue/kt-blog-web` 和 Admin 博客管理使用。 ### Blog Article | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/blog/article/public/list` | 公开文章分页 | | `GET` | `/blog/article/public/detail` | 公开文章详情,支持 id/slug | | `GET` | `/blog/article/list` | 后台文章分页 | | `GET` | `/blog/article/detail` | 后台文章详情 | | `POST` | `/blog/article/save` | 新增文章 | | `POST` | `/blog/article/update` | 更新文章 | | `POST` | `/blog/article/remove` | 删除文章 | | `GET` | `/blog/article/category-options` | 文章分类选项 | | `GET` | `/blog/article/tag-options` | 文章标签选项 | | `POST` | `/blog/article/import-wordpress` | 从 WordPress 导入文章 | 文章 body 常用字段: ```json { "title": "文章标题", "slug": "post-slug", "status": "publish", "content": "Markdown 或 HTML", "contentFormat": "markdown", "cover": "", "categories": ["tech"], "tags": ["kt"] } ``` ### Blog Category / Tag / Theme | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/blog/category/list` | 本地分类分页 | | `GET` | `/blog/category/detail` | 本地分类详情 | | `POST` | `/blog/category/save` | 新增分类 | | `POST` | `/blog/category/update` | 更新分类 | | `POST` | `/blog/category/remove` | 删除分类 | | `GET` | `/blog/tag/list` | 本地标签分页 | | `GET` | `/blog/tag/detail` | 本地标签详情 | | `POST` | `/blog/tag/save` | 新增标签 | | `POST` | `/blog/tag/update` | 更新标签 | | `POST` | `/blog/tag/remove` | 删除标签 | | `GET` | `/blog/term/options` | 分类/标签选项 | | `GET` | `/blog/theme/config` | 获取 Argon 主题配置 | | `POST` | `/blog/theme/save` | 保存本地主题配置 | | `POST` | `/blog/theme/import-wordpress` | 从 WordPress 导入主题配置 | ## WordPress 代理 `/wordpress/*` 需要 Admin 登录态和 WordPress 登录态。后端优先使用 `kt_wordpress_auth` httpOnly cookie,也支持显式透传 WordPress 认证 header。 | 方法 | 路径 | 说明 | | --- | --- | --- | | `POST` | `/wordpress/auth/login` | 使用 env 管理员账号登录 WordPress 并写入 cookie | | `POST` | `/wordpress/auth/logout` | 清理 WordPress cookie | | `GET` | `/wordpress/auth/check` | 校验 WordPress 登录态 | | `GET` | `/wordpress/theme/config` | 读取 WordPress Argon 主题配置 | ### WordPress Article / Tag / Category | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/wordpress/article/public/list` | 公开文章列表代理 | | `GET` | `/wordpress/article/public/detail` | 公开文章详情代理 | | `GET` | `/wordpress/article/list` | WordPress 文章分页 | | `GET` | `/wordpress/article/detail` | WordPress 文章详情 | | `POST` | `/wordpress/article/save` | 新增 WordPress 文章 | | `POST` | `/wordpress/article/update` | 更新 WordPress 文章 | | `POST` | `/wordpress/article/remove` | 删除 WordPress 文章 | | `GET` | `/wordpress/tag/list` | 标签分页 | | `GET` | `/wordpress/tag/detail` | 标签详情 | | `POST` | `/wordpress/tag/save` | 新增标签 | | `POST` | `/wordpress/tag/update` | 更新标签 | | `POST` | `/wordpress/tag/remove` | 删除标签 | | `GET` | `/wordpress/category/list` | 分类分页 | | `GET` | `/wordpress/category/detail` | 分类详情 | | `POST` | `/wordpress/category/save` | 新增分类 | | `POST` | `/wordpress/category/update` | 更新分类 | | `POST` | `/wordpress/category/remove` | 删除分类 | WordPress rewrite 未开启导致 `/wp-json/*` 返回 404 时,后端会回退到 `?rest_route=/...`。 ## MinIO | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/minio/check` | 检查连接和 bucket | | `POST` | `/minio/bucket` | 创建 bucket | | `POST` | `/minio/upload` | 上传文件,`multipart/form-data` | | `GET` | `/minio/list` | 文件列表 | | `GET` | `/minio/url` | 临时访问 URL | | `GET` | `/minio/resource-proxy` | 代理读取资源 | | `GET` | `/minio/download` | 下载文件流 | | `DELETE` | `/minio/remove` | 删除文件 | `bucketName` 不传时使用 `MINIO_BUCKET`。 ## QQBot 管理 QQBot 运行态包括 NapCat 容器登录、OneBot v11 反向 WebSocket、MQTT 事件总线、账号能力绑定、在线命令、自动回复规则、权限名单、发送/接收日志和插件生态。 ### Account / Scan Login | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/qqbot/account/list` | QQBot 账号分页 | | `GET` | `/qqbot/account/enabled` | 启用账号列表 | | `POST` | `/qqbot/account/save` | 手动新增账号 | | `POST` | `/qqbot/account/update` | 更新账号 | | `POST` | `/qqbot/account/scan/create` | 扫码新增账号,创建登录会话 | | `POST` | `/qqbot/account/scan/refresh?id=` | 对已有账号刷新登录态 | | `GET` | `/qqbot/account/scan/status?sessionId=` | 查询扫码会话状态 | | `GET` | `/qqbot/account/scan/events?sessionId=` | SSE 订阅扫码进度 | | `POST` | `/qqbot/account/scan/qrcode/refresh?sessionId=` | 刷新当前会话二维码 | | `POST` | `/qqbot/account/scan/cancel?sessionId=` | 取消扫码会话 | | `POST` | `/qqbot/account/delete?id=` | 删除账号并断开 WS | | `POST` | `/qqbot/account/kick?selfId=` | 断开反向 WS 会话 | | `POST` | `/qqbot/account/bind/command` | 绑定账号和在线命令 | | `POST` | `/qqbot/account/unbind/command` | 解绑账号和在线命令 | | `POST` | `/qqbot/account/bind/rule` | 绑定账号和自动回复规则 | | `POST` | `/qqbot/account/unbind/rule` | 解绑账号和自动回复规则 | 扫码链路返回 `sessionId`,前端应使用 SSE 查看步骤进度,而不是等待长 HTTP 请求完成。 ### Command / Rule / Permission | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/qqbot/command/list` | 在线命令分页,支持 `pluginKey`、`operationKey`、`selfId`、`enabled` | | `POST` | `/qqbot/command/save` | 新增在线命令 | | `POST` | `/qqbot/command/update` | 更新在线命令 | | `POST` | `/qqbot/command/delete?id=` | 删除在线命令 | | `POST` | `/qqbot/command/toggle?id=&enabled=` | 启停在线命令 | | `POST` | `/qqbot/command/test` | 预览测试在线命令 | | `GET` | `/qqbot/rule/list` | 自动回复规则分页 | | `POST` | `/qqbot/rule/save` | 新增自动回复规则 | | `POST` | `/qqbot/rule/update` | 更新自动回复规则 | | `POST` | `/qqbot/rule/delete?id=` | 删除自动回复规则 | | `POST` | `/qqbot/rule/toggle?id=&enabled=` | 启停自动回复规则 | | `GET` | `/qqbot/permission/config` | 权限名单配置 | | `POST` | `/qqbot/permission/config` | 保存权限名单配置 | | `GET` | `/qqbot/permission/allowlist` | 白名单分页 | | `POST` | `/qqbot/permission/allowlist/save` | 新增白名单 | | `POST` | `/qqbot/permission/allowlist/update` | 更新白名单 | | `POST` | `/qqbot/permission/allowlist/delete?id=` | 删除白名单 | | `GET` | `/qqbot/permission/blocklist` | 黑名单分页 | | `POST` | `/qqbot/permission/blocklist/save` | 新增黑名单 | | `POST` | `/qqbot/permission/blocklist/update` | 更新黑名单 | | `POST` | `/qqbot/permission/blocklist/delete?id=` | 删除黑名单 | `/qqbot/command/test` 示例: ```json { "commandId": "2041700000000000001", "text": "/查曲 夏祭り", "selfId": "10000", "targetType": "group", "targetId": "123456", "userId": "2354598417" } ``` 线上 smoke 必须按 `operationKey` 查询启用命令 ID 后传入 `commandId`,避免默认 `preview` selfId 误报未匹配命令。 ### Plugin / Dashboard / Send / Message | 方法 | 路径 | 说明 | | --- | --- | --- | | `GET` | `/qqbot/plugin/list` | 插件列表,支持 `triggerMode=command/event` | | `GET` | `/qqbot/plugin/operation/list` | 插件能力列表 | | `GET` | `/qqbot/plugin/health` | 插件健康检查 | | `GET` | `/qqbot/plugin/event/list` | 事件触发插件绑定状态 | | `POST` | `/qqbot/plugin/event/bind` | 绑定事件触发插件 | | `POST` | `/qqbot/plugin/event/unbind` | 解绑事件触发插件 | | `GET` | `/qqbot/dashboard/summary` | QQBot 工作台汇总 | | `GET` | `/qqbot/send/log/list` | 发送日志分页 | | `POST` | `/qqbot/send/private` | 发送私聊消息 | | `POST` | `/qqbot/send/group` | 发送群聊消息 | | `GET` | `/qqbot/conversation/list` | 会话列表 | | `GET` | `/qqbot/message/list` | 消息列表 | ### OneBot Reverse WebSocket `QQBOT_REVERSE_WS_PATH` 默认是 `/qqbot/onebot/reverse`。NapCat 通过反向 WS 连接 API,token 使用 `QQBOT_REVERSE_WS_TOKEN`。 ## QQBot 插件能力 ### BangDream 插件 key:`bangDream`。当前源码根目录为 `src/qqbot/plugins/bangDream`,不再使用旧 `tsugu` 子目录。 | operation key | 命令 | 说明 | | --- | --- | --- | | `bangdream.song.search` | `/查曲` | 查歌曲信息图片 | | `bangdream.song.chart` | `/查谱面` | 查谱面图片 | | `bangdream.song.random` | `/随机曲` | 随机歌曲 | | `bangdream.song.meta` | `/查询分数表` | 查歌曲分数榜 | | `bangdream.card.search` | `/查卡` | 查卡牌信息图片 | | `bangdream.card.illustration` | `/查卡面` | 查卡面插画 | | `bangdream.character.search` | `/查角色` | 查角色信息 | | `bangdream.event.search` | `/查活动` | 查活动信息 | | `bangdream.event.stage` | `/查试炼` | 查活动试炼,保持拆图输出 | | `bangdream.player.search` | `/查玩家` | 查玩家信息 | | `bangdream.gacha.search` | `/查卡池` | 查卡池 | | `bangdream.gacha.simulate` | `/抽卡模拟` | 模拟抽卡 | | `bangdream.cutoff.detail` | `/ycx` | 单档位预测线 | | `bangdream.cutoff.all` | `/ycxall` | 全档位预测线 | | `bangdream.cutoff.recent` | `/lsycx` | 历史/近期档线 | `registry/operation-registry.ts` 是 BangDream operation、handlerName、别名、冷却和说明的单一来源。新增或调整命令必须同步在线命令 SQL,并跑 registry/command-SQL 测试。 ### FF14 Market 插件 key:`ff14Market`。 | operation key | 说明 | | --- | --- | | `ff14.item.resolve` | 按物品名称或 ID 解析 XIVAPI 物品 | | `ff14.market.price` | 查询指定服务器/大区的 Universalis 市场价格 | 市场查价支持 `item`、`itemId`、`world`、`dataCenter`、`region`、`hq`、`language`。 ### FFLogs 插件 key:`fflogs`。 | operation key | 说明 | | --- | --- | | `fflogs.character.summary` | 查询 FFLogs 角色公开排名;传 `encounter` 时查询指定高难最近记录 | 常用输入:`characterName`、`serverSlug`、`serverRegion`、`encounter`、`limit`、`metric`、`timeframe`、`zoneId`。 ## 初始化 SQL | 文件 | 用途 | | --- | --- | | `sql/vben-admin-init.sql` | 创建 Admin 基础表、用户、角色、菜单、部门、字典和空组件表 | | `sql/blog-init.sql` | 初始化本地 Blog 表 | | `sql/blog-menu.sql` | 初始化 Blog 管理菜单 | | `sql/qqbot-init.sql` | 初始化 QQBot 表、插件命令和字典 | | `sql/system-log-menu.sql` | 初始化系统日志菜单和权限 | | `sql/migrate-dict-to-admin-dict.sql` | 旧 `dict` 迁移到 `admin_dict` | | `sql/migrate-component-to-admin-component.sql` | 旧 `component` 迁移到 `admin_component` | | `sql/fix-admin-menu-meta.sql` | 修复菜单 meta 被覆盖为空 | | `sql/fix-admin-user-zero-id.sql` | 修复旧版本 `admin_user.id=0` 脏数据 | ## 验证入口 常规文档/配置检查: ```bash git diff --check ``` 后端代码检查: ```bash pnpm run typecheck pnpm run lint pnpm test ``` BangDream 图片 smoke: ```powershell .\scripts\bangdream-render-smoke.ps1 -OperationKey bangdream.song.search -Text "夏祭り" -OutFile ".kt-workspace/bangdream-smoke/song.jpg" .\scripts\bangdream-render-smoke.ps1 -OperationKey bangdream.event.stage -Text "310" -OutFile ".kt-workspace/bangdream-smoke/stage.jpg" ``` Jenkins/K8s 发布后还需要观察 rollout、新 Pod 日志,并跑真实运行态 smoke;推送成功不等于发布完成。