Files
cjyyzx/工单接口.md
T
xiaohei 428644e286
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
Enterprise AI Workspace prototype: LobeChat (de-branded) + Enterprise Gateway + Postgres/Redis stack
2026-04-21 12:58:00 +08:00

474 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
我已经完整阅读了后端的 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