feat: external API for QQ bot - client id+secret auth, ticket tracking, bans, per-server data

- db: api_clients table + server_groups.alias + tickets/bans server_name (auto-migrate)
- external.js: client_id+secret auth (multi-client, bcrypt, show-once secret),
  legacy x-external-key compat, JWT pass-through
  - POST /tickets (optional server), GET /tickets/track?token= (full lifecycle)
  - GET/POST /bans, reported-players/stats/all-tickets with server filter
  - GET /servers (alias list), client CRUD (owner/admin, audit logged)
  - resolveServer: alias | 分组/子服 | server_name
- polls.js: server_groups CRUD with alias (add/edit, dup check)
- servers page: alias display + edit; new 外部API page: client mgmt + quick docs
- API.md: full external API section (auth matrix, server param syntax)
- verified: 37 checks incl. resolveServer sandbox (alias/group/fallback)
This commit is contained in:
2026-08-19 19:12:34 +08:00
parent a11df22600
commit 257cd14051
8 changed files with 393 additions and 54 deletions

View File

@@ -329,15 +329,41 @@ Base URL: `http://<host>:3100/api`
| 端点 | 认证 | 说明 |
|------|------|------|
| POST /external/auth/register | external-key | 插件注册(邮箱验证链接) |
| POST /external/auth/login | external-key | 插件登录,返回 JWT |
| GET /external/my-tickets | external-key + Bearer | 我的工单列表(limit ≤50) |
| GET /external/my-tickets/:id | external-key + Bearer | 我的工单详情 |
| POST /external/tickets | external-key | 游戏内提交工单(自动写主身份) |
| GET /external/all-tickets | external-key | 全部工单(分页 page/limit ≤200) |
| GET /external/all-tickets/:id | external-key | 工单详情(含回复/附件) |
| GET /external/reported-players | external-key | 被举报统计 |
| GET /external/stats | external-key | 工单统计 |
| POST /external/auth/register | | 插件注册(邮箱验证链接) |
| POST /external/auth/login | | 插件登录,返回 JWT |
| GET /external/my-tickets | Bearer | 我的工单列表(limit ≤50) |
| GET /external/my-tickets/:id | Bearer | 我的工单详情 |
| POST /external/tickets | client | 提交工单(带 `server` 可选;返回 id + tracking_token) |
| GET /external/tickets/track?token= | client | 按追踪码查工单状态+回复(提交→处理→结束全流程) |
| GET /external/all-tickets | client | 全部工单(分页 page/limit ≤200,可按 `server`/`status`/`type` 过滤) |
| GET /external/all-tickets/:id | client | 工单详情(含回复/附件) |
| GET /external/bans?server=&status=&player= | client | 拉取封禁列表(可按子服/状态/玩家过滤) |
| POST /external/bans | client | 新增封禁(可带 `server`) |
| GET /external/reported-players?server= | client | 被举报统计(可按子服过滤) |
| GET /external/servers | client | 服务器列表(含外部别名) |
| GET /external/stats?server= | client | 工单统计(可按子服过滤) |
| POST /external/clients | Bearer(owner/admin) | 创建 API 客户端,返回 client_id + secret(仅显示一次) |
| GET /external/clients | Bearer(owner/admin) | 客户端列表 |
| PUT /external/clients/:id | Bearer(owner/admin) | 启用/停用客户端 |
| DELETE /external/clients/:id | Bearer(owner/admin) | 删除客户端 |
### 外部鉴权(三选一)
| 方式 | 请求头 | 适用 |
|------|--------|------|
| 多客户端(推荐) | `x-api-client-id` + `x-api-secret` | QQ机器人等外部系统,后台可创建/停用多个客户端 |
| 旧版单 key | `x-external-key` | 兼容旧部署(`config.external_api_key`) |
| 用户 JWT | `Authorization: Bearer <jwt>` | 插件/已登录用户 |
### 子服务器定位(`server` 参数)
每个子服可在「服务器管理」配置**外部别名(alias)**,外部 API 的 `server` 参数支持三种写法:
- **别名**: `survival`(推荐,改名不影响)
- **分组/子服**: `网易服务器/生存服`
- **子服名**: `生存服`(同名时取第一个)
工单/封禁按提交时的 `server` 归属存储,查询时用同一参数即可精确拉取对应子服数据。
---
@@ -365,3 +391,11 @@ Base URL: `http://<host>:3100/api`
5. 工单提交:登录用户可选择任一已绑定身份(后端校验归属);匿名仍走表单字段
> 老数据无需手工处理,服务启动时自动迁移;`users` 表原有字段(主身份)保持不变,完全向后兼容。
外部 API 功能新增迁移(幂等,服务启动自动执行):
1. 创建 `api_clients` 表(多客户端鉴权)
2. `server_groups``alias` 列(子服外部别名)
3. `tickets` / `bans``server_name` 列(按子服归属存储)
> 老工单/封禁 `server_name` 为空串,不影响原有查询;新提交的数据自动带子服归属。