API Keys 模块 API 文档

基础信息


数据库表

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 组合

Schema 问题: `api_key_encrypted` 只是 Base64 编码,任何人能直接解码,生产环境应使用真正加密

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"
    }
  ]
}
不返回 `api_key_encrypted` 明文

2. 获取账单最优 Key 列表(AI 请求用)

GET /api/apikeys/resolve/:billId

触发时机: AI 对话发起前,由 keyResolver.js 调用(前端不发请求,是后端内部解析逻辑)

注意: 此接口由后端 AI 模块内部调用,前端不直接使用

Key 解析规则:

  1. 用户个人 Key 优先(owner_type=user AND owner_id=当前用户
  2. 同账单已共享 Key 其次(is_shared=1
  3. priority 升序(数字越小越优先)
  4. 排除 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 消息)

测试失败不影响已保存的 Key,只做验证

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

后端处理:

  1. 校验 billId 有效
  2. Base64 编码 Key
  3. UPSERT:provider+model 组合存在则 UPDATE,否则 INSERT
  4. is_shared=1 时同账单成员可使用此 Key
Schema 注意: `is_shared` 是 integer(0/1),不是 boolean,传布尔值会被 `Number(is_shared) === 1` 处理
重要: 首次保存必须提供 `api_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 存在则覆盖,否则新增

Schema 注意: 导入时会复制 `api_key_encrypted`(明文 Base64),目标账单拿到的是实际可用的 Key

11. 切换 Key 共享状态

PATCH /api/apikeys/user/share

认证: 必需

请求参数:

参数 类型 必填 说明
billId string 账单ID
provider string AI 提供商
model string 模型名
is_shared boolean 是否共享(true=共享, false=不共享)

后端处理:

  1. 校验用户是账单成员
  2. 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
}

后端处理:

  1. 校验用户是账单成员
  2. 遍历 orders 数组,UPSERT user_provider_order

数据库表: user_provider_order