Revalidate Docs / Revalidate Docs (push) Failing after 2s
E2E CI / Check Duplicate Run (push) Failing after 5s
Test CI / Check Duplicate Run (push) Failing after 6s
E2E CI / Test Web App (push) Has been skipped
Test CI / Test Packages (push) Has been skipped
Test CI / Test App (shard 1/3) (push) Has been skipped
Test CI / Test App (shard 2/3) (push) Has been skipped
Test CI / Test App (shard 3/3) (push) Has been skipped
Test CI / Test Desktop App (push) Has been skipped
🔄 Branch Synchronization / sync-branches (push) Failing after 11s
Test CI / Test Database (push) Has been skipped
Test CI / Merge and Upload App Coverage (push) Has been skipped
Database Schema Visualization CI / build (push) Failing after 4m14s
474 lines
10 KiB
Markdown
474 lines
10 KiB
Markdown
我已经完整阅读了后端的 API 密钥系统代码。下面是完整的接口文档:
|
||
|
||
---
|
||
|
||
# 工单系统 — 外部 API 密钥调用接口文档
|
||
|
||
## 一、认证方式
|
||
|
||
所有请求通过 HTTP 请求头 `X-Api-Key` 传递 API 密钥进行认证。
|
||
|
||
```
|
||
X-Api-Key: gd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||
```
|
||
|
||
- 密钥格式:`gd_live_` + 40 位十六进制字符
|
||
- 密钥仅在创建时返回一次明文,之后无法再次获取
|
||
- 密钥支持过期时间和启用/禁用控制
|
||
|
||
## 二、权限模型
|
||
|
||
### 2.1 模块权限
|
||
|
||
每个 API 密钥创建时需指定 `allowedModules`,限制可访问的模块范围。合法模块如下:
|
||
|
||
| 模块键 | 路由前缀 | 说明 |
|
||
|---|---|---|
|
||
| `ticket` | `/api/tickets` | 工单管理 |
|
||
| `customer` | `/api/customers` | 客户管理 |
|
||
| `engineer` | `/api/engineers` | 工程师/运维管理 |
|
||
| `attachment` | `/api/attachments` | 附件上传 |
|
||
| `statusMonitor` | `/api/status` | 状态监控 |
|
||
|
||
请求路径不在上述模块范围内的,跳过模块权限检查。
|
||
|
||
### 2.2 角色映射
|
||
|
||
API 密钥通过认证后,系统会生成一个**合成 ADMIN 用户**(`id: api-key:<keyId>`, `role: ADMIN`)。因此 API 密钥只能访问 `@Roles(...)` 中包含 `ADMIN` 的接口。
|
||
|
||
### 2.3 禁止访问的路径
|
||
|
||
以下管理端路径**明确禁止** API 密钥访问(即使密钥有效也返回 `401`):
|
||
|
||
- `/api/api-keys/**` — API 密钥管理
|
||
- `/api/api-permissions/**` — API 模块权限管理
|
||
|
||
---
|
||
|
||
## 三、接口列表
|
||
|
||
> 基础路径:`/api`
|
||
> 所有请求需携带 `X-Api-Key` 请求头
|
||
> 返回格式:JSON
|
||
|
||
---
|
||
|
||
### 3.1 工单模块 (`ticket`)
|
||
|
||
需要 `allowedModules` 包含 `"ticket"`。
|
||
|
||
#### 3.1.1 创建工单
|
||
|
||
```
|
||
POST /api/tickets
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `platform` | string | ✅ | 平台类型:`taiji` / `xm` / `original` |
|
||
| `accountInfo` | string | ✅ | 账号信息 |
|
||
| `modelUsed` | string | ✅ | 使用的模型 |
|
||
| `description` | string | ✅ | 问题描述 |
|
||
| `requestExample` | string | ✅ | 请求示例 |
|
||
| `contactInfo` | string | ❌ | 联系方式 |
|
||
| `framework` | string | ❌ | 使用框架 |
|
||
| `networkEnv` | string | ❌ | 网络环境:`local` / `cloud` |
|
||
| `attachmentUrls` | string[] | ❌ | 附件 URL 列表 |
|
||
| `requestedLevel` | string | ❌ | 请求工程师等级:`L1` / `L2` / `L3` |
|
||
|
||
#### 3.1.2 为指定客户创建工单
|
||
|
||
```
|
||
POST /api/tickets/for-customer/:customerId
|
||
```
|
||
|
||
**路径参数:** `customerId` — 客户 ID
|
||
|
||
**请求体:** 同 3.1.1
|
||
|
||
#### 3.1.3 查询工单列表
|
||
|
||
```
|
||
GET /api/tickets?page=1&pageSize=20&status=PENDING
|
||
```
|
||
|
||
**查询参数:**
|
||
|
||
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|
||
|---|---|---|---|---|
|
||
| `page` | number | ❌ | 1 | 页码 |
|
||
| `pageSize` | number | ❌ | 20 | 每页条数 |
|
||
| `status` | string | ❌ | — | 筛选状态:`PENDING` / `ACCEPTED` / `IN_PROGRESS` / `PENDING_CLOSE` / `CLOSED` |
|
||
|
||
#### 3.1.4 查询单个工单
|
||
|
||
```
|
||
GET /api/tickets/:id
|
||
```
|
||
|
||
#### 3.1.5 更新工单状态
|
||
|
||
```
|
||
PUT /api/tickets/:id/status
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `status` | string | ✅ | 目标状态 |
|
||
|
||
#### 3.1.6 自行接单
|
||
|
||
```
|
||
PUT /api/tickets/:id/self-assign
|
||
```
|
||
|
||
#### 3.1.7 分配工程师
|
||
|
||
```
|
||
PUT /api/tickets/:id/assign
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `engineerId` | string | ✅ | 工程师 ID |
|
||
|
||
#### 3.1.8 客户关闭工单
|
||
|
||
```
|
||
PUT /api/tickets/:id/customer-close
|
||
```
|
||
|
||
#### 3.1.9 申请关闭工单
|
||
|
||
```
|
||
PUT /api/tickets/:id/close-request
|
||
```
|
||
|
||
#### 3.1.10 审批关闭工单
|
||
|
||
```
|
||
PUT /api/tickets/:id/close-approve
|
||
```
|
||
|
||
#### 3.1.11 拒绝关闭工单
|
||
|
||
```
|
||
PUT /api/tickets/:id/close-reject
|
||
```
|
||
|
||
#### 3.1.12 催单
|
||
|
||
```
|
||
POST /api/tickets/:id/urge
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `note` | string | ❌ | 催单备注 |
|
||
|
||
#### 3.1.13 获取工单留言列表
|
||
|
||
```
|
||
GET /api/tickets/:id/messages
|
||
```
|
||
|
||
#### 3.1.14 添加工单留言
|
||
|
||
```
|
||
POST /api/tickets/:id/messages
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `content` | string | ✅ | 留言内容 |
|
||
| `attachmentUrls` | string[] | ❌ | 附件 URL 列表 |
|
||
|
||
#### 3.1.15 删除工单留言
|
||
|
||
```
|
||
DELETE /api/tickets/messages/:messageId
|
||
```
|
||
|
||
#### ⚠️ 不可访问的接口
|
||
|
||
| 接口 | 原因 |
|
||
|---|---|
|
||
| `GET /api/tickets/daily-usage/me` | 仅限 `CUSTOMER` 角色,API 密钥为 `ADMIN` 角色,无权限 |
|
||
|
||
---
|
||
|
||
### 3.2 客户模块 (`customer`)
|
||
|
||
需要 `allowedModules` 包含 `"customer"`。
|
||
|
||
#### 3.2.1 查询客户列表
|
||
|
||
```
|
||
GET /api/customers
|
||
```
|
||
|
||
#### 3.2.2 查询单个客户
|
||
|
||
```
|
||
GET /api/customers/:id
|
||
```
|
||
|
||
#### ⚠️ 不可访问的接口
|
||
|
||
以下接口仅限 `OPERATOR` 角色,API 密钥(`ADMIN`)无权访问:
|
||
|
||
| 接口 | 方法 |
|
||
|---|---|
|
||
| `POST /api/customers` | 创建客户 |
|
||
| `PATCH /api/customers/:id/tier` | 更新客户等级 |
|
||
| `PATCH /api/customers/:id/bind-engineer` | 绑定工程师 |
|
||
|
||
---
|
||
|
||
### 3.3 工程师/运维模块 (`engineer`)
|
||
|
||
需要 `allowedModules` 包含 `"engineer"`。
|
||
|
||
#### 3.3.1 查询工程师列表
|
||
|
||
```
|
||
GET /api/engineers
|
||
```
|
||
|
||
#### 3.3.2 创建工程师
|
||
|
||
```
|
||
POST /api/engineers
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `username` | string | ✅ | 用户名 |
|
||
| `email` | string | ✅ | 邮箱 |
|
||
| `password` | string | ✅ | 密码 |
|
||
| `level` | string | ✅ | 等级:`L1` / `L2` / `L3` |
|
||
| `isAdmin` | boolean | ❌ | 是否管理员 |
|
||
|
||
#### 3.3.3 创建运维人员
|
||
|
||
```
|
||
POST /api/engineers/operators
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `username` | string | ✅ | 用户名 |
|
||
| `email` | string | ✅ | 邮箱 |
|
||
| `password` | string | ✅ | 密码 |
|
||
|
||
#### 3.3.4 管理端 — 查询工程师列表
|
||
|
||
```
|
||
GET /api/engineers/admin/engineers
|
||
```
|
||
|
||
#### 3.3.5 管理端 — 更新工程师信息
|
||
|
||
```
|
||
PATCH /api/engineers/admin/engineers/:id
|
||
```
|
||
|
||
**请求体(均可选):**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `username` | string | 用户名 |
|
||
| `email` | string | 邮箱 |
|
||
| `level` | string | 等级:`L1` / `L2` / `L3` |
|
||
| `isAvailable` | boolean | 是否可用 |
|
||
|
||
#### 3.3.6 管理端 — 重置工程师密码
|
||
|
||
```
|
||
PATCH /api/engineers/admin/engineers/:id/password
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `newPassword` | string | ✅ | 新密码 |
|
||
|
||
#### 3.3.7 管理端 — 删除工程师
|
||
|
||
```
|
||
DELETE /api/engineers/admin/engineers/:id
|
||
```
|
||
|
||
#### 3.3.8 管理端 — 查询运维人员列表
|
||
|
||
```
|
||
GET /api/engineers/admin/operators
|
||
```
|
||
|
||
#### 3.3.9 管理端 — 更新运维人员信息
|
||
|
||
```
|
||
PATCH /api/engineers/admin/operators/:id
|
||
```
|
||
|
||
**请求体(均可选):**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `username` | string | 用户名 |
|
||
| `email` | string | 邮箱 |
|
||
|
||
#### 3.3.10 管理端 — 重置运维人员密码
|
||
|
||
```
|
||
PATCH /api/engineers/admin/operators/:id/password
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `newPassword` | string | ✅ | 新密码 |
|
||
|
||
#### 3.3.11 管理端 — 删除运维人员
|
||
|
||
```
|
||
DELETE /api/engineers/admin/operators/:id
|
||
```
|
||
|
||
#### ⚠️ 注意 — `me` 接口的局限性
|
||
|
||
以下接口虽然角色上允许 `ADMIN` 访问,但 API 密钥的合成用户 ID 为 `api-key:<keyId>`,不对应真实工程师账号,**调用会在服务层失败**:
|
||
|
||
| 接口 | 说明 |
|
||
|---|---|
|
||
| `PATCH /api/engineers/me/availability` | 更新可用状态 |
|
||
| `PATCH /api/engineers/me/email` | 更新邮箱 |
|
||
| `PATCH /api/engineers/me/password` | 修改密码 |
|
||
|
||
---
|
||
|
||
### 3.4 附件模块 (`attachment`)
|
||
|
||
需要 `allowedModules` 包含 `"attachment"`。
|
||
|
||
#### 3.4.1 获取上传 SAS Token
|
||
|
||
```
|
||
POST /api/attachments/sas-token
|
||
```
|
||
|
||
**请求体:**
|
||
|
||
| 字段 | 类型 | 必填 | 说明 |
|
||
|---|---|---|---|
|
||
| `fileName` | string | ✅ | 文件名(会被安全化处理) |
|
||
|
||
**返回:** 包含 Azure Blob Storage 上传所需的 SAS Token。
|
||
|
||
---
|
||
|
||
### 3.5 状态监控模块 (`statusMonitor`)
|
||
|
||
需要 `allowedModules` 包含 `"statusMonitor"`。
|
||
|
||
#### 3.5.1 获取外部服务状态
|
||
|
||
```
|
||
GET /api/status/external
|
||
```
|
||
|
||
#### 3.5.2 获取运维仪表盘
|
||
|
||
```
|
||
GET /api/status/dashboard
|
||
```
|
||
|
||
#### 3.5.3 获取公开仪表盘
|
||
|
||
```
|
||
GET /api/status/public-dashboard
|
||
```
|
||
|
||
> 注:此接口本身无需认证即可访问。使用 API 密钥访问时会消耗模块权限检查。
|
||
|
||
---
|
||
|
||
## 四、白名单路径(无需模块检查)
|
||
|
||
以下路径不受 API 模块权限限制,但部分仍需 JWT 认证(API 密钥不可替代):
|
||
|
||
| 路径 | 说明 |
|
||
|---|---|
|
||
| `/api/auth/*` | 认证相关 |
|
||
| `/api/health` | 健康检查 |
|
||
| `/api/public/bing-background` | 必应壁纸 |
|
||
| `/api/api-permissions/*` | 权限管理(**禁止**API密钥访问) |
|
||
| `/api/api-keys*` | 密钥管理(**禁止**API密钥访问) |
|
||
|
||
---
|
||
|
||
## 五、错误码说明
|
||
|
||
| HTTP 状态码 | 说明 |
|
||
|---|---|
|
||
| `401 Unauthorized` | 密钥无效、已禁用、已过期,或尝试访问禁止路径 |
|
||
| `403 Forbidden` | 密钥的 `allowedModules` 不包含请求的模块 / 角色不足 |
|
||
| `400 Bad Request` | 请求参数校验失败 |
|
||
| `404 Not Found` | 资源不存在 |
|
||
|
||
---
|
||
|
||
## 六、示例调用
|
||
|
||
```bash
|
||
# 查询工单列表
|
||
curl -H "X-Api-Key: gd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
|
||
"https://your-domain/api/tickets?page=1&pageSize=10"
|
||
|
||
# 创建工单
|
||
curl -X POST \
|
||
-H "X-Api-Key: gd_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"platform": "taiji",
|
||
"accountInfo": "test-account",
|
||
"modelUsed": "gpt-4",
|
||
"description": "API调用异常",
|
||
"requestExample": "curl https://api.example.com/v1/chat"
|
||
}' \
|
||
"https://your-domain/api/tickets"
|
||
```
|
||
|
||
---
|
||
|
||
## 七、认证流程总结
|
||
|
||
```
|
||
请求 → [全局 ApiKeyGuard] 读取 X-Api-Key → 验证密钥 → 设置 req.apiClient
|
||
→ [全局 ApiModulePermissionGuard] 解析路径模块 → 检查 allowedModules
|
||
→ [控制器 JwtAuthGuard] 检测 apiClient → 合成 ADMIN 用户 → 跳过 JWT 校验
|
||
→ [控制器 RolesGuard] 检查 ADMIN 是否在 @Roles() 的允许列表中
|
||
→ 执行业务逻辑
|
||
```
|
||
|
||
关键源码参考:
|
||
- 密钥验证:api-key.service.ts(`validateKey` 方法)
|
||
- 密钥 Guard:api-key.guard.ts
|
||
- 模块权限 Guard:api-module-permission.guard.ts
|
||
- JWT Guard 中的 API Key 处理:jwt-auth.guard.ts |