API Keys 模块 API 文档
基础信息
- Base URL:
/api/apikeys - 认证方式: JWT Bearer Token
数据库表
api_keys 表
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | text (PK) | 必填 | 10位随机ID |
| bill_id | text (FK→bills) | 必填 | 所属账单 |
| owner_id | text (FK→users) | 必填 | Key 所有者用户ID |
| owner_type | text | 必填 | user(目前只有这一个值) |
| provider | text | 必填 | AI 提供商(openai/anthropic/gemini 等) |
| model | text | 必填 | 模型名 |
| api_key_encrypted | text | 必填 | Base64 编码(明文可解码,不是加密) |
| is_shared | integer | 必填 | 0=不共享, 1=共享给账单成员 |
| priority | integer | 必填 | 优先级,数字越小越优先(默认100) |
| last_used_at | datetime | 选填 | 最后使用时间 |
| expires_at | datetime | 选填 | Key 过期时间 |
| revoked_at | datetime | 选填 | 撤销时间(设置后 = 已撤销) |
| created_at | datetime | 必填 | 创建时间 |
| updated_at | datetime | 必填 | 更新时间 |
唯一约束: (bill_id, owner_type, owner_id, provider, model) — 同账单内不能有重复的 owner+provider+model 组合
user_provider_order 表(排序配置)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
| id | text (PK) | 必填 | 10位随机ID |
| bill_id | text (FK→bills) | 必填 | 所属账单 |
| user_id | text (FK→users) | 必填 | 排序用户 |
| provider | text | 必填 | AI 提供商 |
| model | text | 必填 | 模型名 |
| owner_type | text | 必填 | Key 类型 |
| owner_id | text | 必填 | Key 所有者ID |
| priority | integer | 必填 | 排序优先级 |
| created_at | datetime | 必填 | 创建时间 |
| updated_at | datetime | 必填 | 更新时间 |
唯一约束: (bill_id, user_id, provider, model, owner_type, owner_id)
接口列表
1. 获取用户在账单中的 Key 列表
GET /api/apikeys/user
触发时机: 进入 开发者页面(DeveloperPage) 时请求(查询当前用户在当前账单配置的 Key)
DeveloperPage 加载 → GET /apikeys/user?billId=xxx
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | 必填 | 账单ID(Query Param) |
响应:
{
"keys": [
{
"id": "string",
"owner_type": "user",
"owner_id": "string",
"provider": "openai",
"model": "gpt-4o",
"is_shared": 0 | 1,
"priority": 100,
"created_at": "ISO8601"
}
]
}
2. 获取账单最优 Key 列表(AI 请求用)
GET /api/apikeys/resolve/:billId
触发时机: AI 对话发起前,由 keyResolver.js 调用(前端不发请求,是后端内部解析逻辑)
Key 解析规则:
- 用户个人 Key 优先(
owner_type=user AND owner_id=当前用户) - 同账单已共享 Key 其次(
is_shared=1) - 按
priority升序(数字越小越优先) - 排除
revoked_at IS NOT NULL的 Key
3. 获取账单全量可见 Key 条目
GET /api/apikeys/resolve-all/:billId
触发时机: 开发者页面加载时,与 /apikeys/user 一起请求
DeveloperPage 加载 → Promise.all([
GET /apikeys/user?billId=xxx,
GET /apikeys/resolve-all/:billId
])
响应: 与 /resolve 类似,但返回更多上下文信息(包含 owner_nickname 等)
4. 测试 Key 连通性
POST /api/apikeys/verify/user
触发时机: 在 开发者页面 点击某个 Key 卡片的「测试连接」按钮
DeveloperPage → 展开某 Key → 点击"测试连接" → POST /apikeys/verify/user
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| provider | string | 必填 | AI 提供商 |
| api_key | string | 必填 | Key 明文 |
| model | string | 必填 | 模型名 |
| billId | string | 必填 | 账单ID |
后端处理: 调用 proxyChatByProvider 向该 Provider 发送测试请求(ping 消息)
5. 保存或更新用户 Key
PUT /api/apikeys/user
触发时机: 在 开发者页面 填写/修改 Key 信息后点击「保存」按钮
DeveloperPage → 填写 provider/model/api_key → 点击"保存" → PUT /apikeys/user
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| provider | string | 必填 | 提供商 |
| api_key | string | 选填 | Key 明文(首次必填,后续可省略) |
| model | string | 必填 | 模型名 |
| billId | string | 必填 | 账单ID |
| priority | number | 选填 | 优先级,默认100 |
| is_shared | boolean | 选填 | 是否共享,默认 false |
后端处理:
- 校验 billId 有效
- Base64 编码 Key
- UPSERT:provider+model 组合存在则 UPDATE,否则 INSERT
is_shared=1时同账单成员可使用此 Key
6. 切换 Key 共享状态
PATCH /api/apikeys/user/share
触发时机: 在 开发者页面 Key 卡片上点击「共享」开关
DeveloperPage → Key 卡片 → 点击共享开关 → PATCH /apikeys/user/share
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | 必填 | 账单ID |
| provider | string | 必填 | 提供商 |
| model | string | 必填 | 模型名 |
| is_shared | boolean | 必填 | 是否共享 |
7. 批量更新 Key 排序
PATCH /api/apikeys/order/user
触发时机: 在 开发者页面 拖拽调整 Key 顺序后触发
DeveloperPage → 拖拽调整 Key 顺序 → PATCH /apikeys/order/user
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | 必填 | 账单ID |
| orders | array | 必填 | 排序数组 |
8. 删除用户 Key
DELETE /api/apikeys/user/:provider
触发时机: 在 开发者页面 Key 卡片上点击「删除」按钮
DeveloperPage → Key 卡片 → 点击"删除" → DELETE /apikeys/user/:provider?billId=xxx&model=xxx
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | 必填 | 账单ID(Query Param) |
| model | string | 选填 | 不传则删除该 provider 下所有 Key |
9. 获取跨账单配置建议
GET /api/apikeys/suggestions
触发时机: 在 开发者页面 提示用户可以从其他账单导入配置
DeveloperPage → 显示"从其他账单导入"建议 → GET /apikeys/suggestions?currentBillId=xxx
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| currentBillId | string | 选填 | 当前账单ID(排除项) |
10. 跨账单导入 Key 配置
POST /api/apikeys/import
触发时机: 在 开发者页面 点击「从其他账单导入」并选择源账单后确认
DeveloperPage → 点击"导入" → 选择源账单 → 点击确认 → POST /apikeys/import
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| fromBillId | string | 必填 | 源账单ID |
| toBillId | string | 必填 | 目标账单ID(通常为当前账单) |
| provider | string | 选填 | 过滤 provider |
| model | string | 选填 | 过滤 model |
后端处理: UPSERT,同 provider+model 存在则覆盖,否则新增
11. 切换 Key 共享状态
PATCH /api/apikeys/user/share
认证: 必需
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | ✅ | 账单ID |
| provider | string | ✅ | AI 提供商 |
| model | string | ✅ | 模型名 |
| is_shared | boolean | ✅ | 是否共享(true=共享, false=不共享) |
后端处理:
- 校验用户是账单成员
- UPDATE
api_keys SET is_shared = ? WHERE bill_id=? AND owner_type='user' AND owner_id=? AND provider=? AND model=?
数据库表: api_keys
12. 批量更新 Key 排序
PATCH /api/apikeys/order/user
认证: 必需
请求参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| billId | string | ✅ | 账单ID |
| orders | array | ✅ | 排序数组 |
orders 元素结构:
{
"provider": "openai",
"model": "gpt-4o",
"owner_type": "user",
"owner_id": "user_id",
"priority": 1
}
后端处理:
- 校验用户是账单成员
- 遍历 orders 数组,UPSERT
user_provider_order表
数据库表: user_provider_order