触发条件视图 — 开发者页(DeveloperPage)


页面:DeveloperPage


路由/dev


可见性:仅 role = 'developer''admin' 的用户可见(普通 user 看不到入口)


数据来源:直接调用 API,不走 DataContext


---


页面进入时


触发 API(并行请求):


1. GET /api/apikeys/user?billId=xxx

说明:获取当前用户在当前账单下配置的 Key 列表

请求:Query Param:billId


响应


{
  "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 明文(只存 Base64 编码,非真正加密) ⚠️ P06


2. GET /api/apikeys/resolve-all/:billId

说明:获取账单所有可用 Key(含其他用户共享的 Key)

响应:与 /user 类似,但包含更多上下文(owner_nickname 等)


3. GET /api/apikeys/suggestions?currentBillId=xxx

说明:获取跨账单 Key 导入建议(从其他账单导入已有配置)

查询参数currentBillId(排除当前账单)


响应


{
  "suggestions": [
    {
      "bill_id": "string",
      "bill_name": "string",
      "providers": ["openai", "anthropic"]
    }
  ]
}

---


添加新 Key(填写表单 → 点击保存)


触发 API


PUT /api/apikeys/user

请求


{
  "provider": "openai",
  "model": "gpt-4o",
  "api_key": "sk-xxxxx",
  "billId": "string",
  "priority": 100,
  "is_shared": false
}

约束

  • 首次保存必须提供 api_key 明文(后端 Base64 编码存储)
  • 后续更新可省略 api_key(使用数据库已有值)
  • 同账单内 owner_id + provider + model 组合唯一,重复则覆盖

  • 后端处理

    1. 校验 billId 有效,用户是账单成员

    2. Base64 编码 api_key(⚠️ 非真正加密,见 P06)

    3. UPSERT api_keys


    DB 表api_keys


    后续动作:保存成功后刷新 Key 列表 + 刷新 suggestions


    ---


    测试 Key 连通性(点击「测试连接」)


    触发 API


    POST /api/apikeys/verify/user

    请求

    
    {
      "provider": "openai",
      "api_key": "sk-xxxxx",
      "model": "gpt-4o",
      "billId": "string"
    }
    

    后端处理:调用对应 Provider 的 ping 接口验证 Key 有效性


    响应

    
    {
      "success": true | false,
      "message": "string"
    }
    

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


    ---


    修改 Key 共享状态(点击 Key 卡片的「共享」开关)


    触发 API


    PATCH /api/apikeys/user/share

    请求

    
    {
      "billId": "string",
      "provider": "openai",
      "model": "gpt-4o",
      "is_shared": true
    }
    

    说明

  • is_shared = true → 同账单成员可使用此 Key
  • is_shared = false → 仅自己可用
  • ⚠️ 注意:is_shared 是 integer(0/1),不是 boolean,传布尔值会被 Number(is_shared) === 1 处理

  • DB 表api_keys


    后续动作:成功后刷新 Key 列表


    ---


    拖拽调整 Key 顺序(调整优先级)


    触发 API


    PATCH /api/apikeys/order/user

    请求

    
    {
      "billId": "string",
      "orders": [
        {
          "provider": "openai",
          "model": "gpt-4o",
          "owner_type": "user",
          "owner_id": "user_id",
          "priority": 1
        },
        {
          "provider": "anthropic",
          "model": "claude-3-opus",
          "owner_type": "user",
          "owner_id": "user_id",
          "priority": 2
        }
      ]
    }
    

    说明:priority 数字越小优先级越高,AI 请求时优先使用排序靠前的 Key


    > ⚠️ 前端可能未实现拖拽排序 UI(见 P12 备注)


    DB 表user_provider_order


    ---


    删除 Key(点击 Key 卡片的「删除」按钮)


    触发 API


    DELETE /api/apikeys/user/:provider

    Query 参数

    
    DELETE /api/apikeys/user/openai?billId=xxx&model=gpt-4o
    
    参数类型必填说明

    |------|------|------|------|

    billIdstring必填账单ID
    modelstring选填不传则删除该 provider 下所有 Key

    DB 表api_keys(级联删除 user_provider_order 中相关记录)


    后续动作:成功后刷新 Key 列表


    ---


    从其他账单导入 Key(点击「从其他账单导入」)


    触发 API(选择源账单后):


    POST /api/apikeys/import

    请求

    
    {
      "fromBillId": "源账单ID",
      "toBillId": "当前账单ID",
      "provider": "openai",
      "model": "gpt-4o"
    }
    

    说明

  • 可选 provider / model 参数,不传则导入源账单全部 Key
  • 目标账单已有相同 provider+model 则覆盖
  • ⚠️ 导入时直接复制 api_key_encrypted(Base64),无重加密(见 P11)

  • DB 表api_keys(UPSERT)、user_provider_order


    ---


    Key 解析规则(后端 AI 模块内部逻辑)


    当用户发起 AI 对话时,后端 /api/ai/chat 内部调用 Key 解析:


    1. 个人 Key 优先owner_type = 'user' AND owner_id = 当前用户

    2. 同账单已共享 Key 其次is_shared = 1

    3. 按 priority 升序排列(数字越小越优先)

    4. 排除已撤销revoked_at IS NOT NULL

    5. 排除已过期expires_at IS NOT NULL AND expires_at < NOW()(⚠️ expires_at 字段存在但前端无管理 UI,见 P12)


    ---


    权限判断汇总


    操作权限API 端点

    |------|------|---------|

    查看 DeveloperPagedeveloper / admin 角色
    查看自己的 Key 列表账单成员GET /api/apikeys/user?billId=xxx
    查看账单所有可用 Key账单成员GET /api/apikeys/resolve-all/:billId
    添加 / 更新 Key账单成员PUT /api/apikeys/user
    测试 Key 连通性账单成员POST /api/apikeys/verify/user
    切换 Key 共享状态Key 所有者PATCH /api/apikeys/user/share
    调整 Key 顺序账单成员PATCH /api/apikeys/order/user
    删除 KeyKey 所有者DELETE /api/apikeys/user/:provider
    获取跨账单导入建议账单成员GET /api/apikeys/suggestions
    从其他账单导入 Key账单成员POST /api/apikeys/import