触发条件视图 — 设置页(SettingsPage)
页面:SettingsPage
路由:/settings
数据来源:直接调用 API,不走 DataContext(个人资料除外,由 AuthContext 注入)
---
页面进入时
> SettingsPage 在加载时不主动拉取数据,而是等用户点击具体操作时触发 API。
用户信息加载时机:通过 AuthContext 注入(全局已登录状态),由 AuthProvider 初始化时通过 GET /api/auth/me 加载。
---
查看个人资料(读取 AuthContext)
说明:当前登录用户的个人信息来自 AuthContext,由 GET /api/auth/me(应用启动时已调用)提供。
AuthContext 暴露的字段:
{
"user": {
"id": "string",
"phone": "string",
"nickname": "string",
"email": "string | null",
"avatar_url": "string",
"prefer_green_expense": 0 | 1,
"is_guest": 0 | 1,
"has_onboarded": 0 | 1,
"role": "user | admin | developer",
"created_at": "ISO8601"
}
}
---
修改昵称(输入新昵称 → 点击保存)
触发 API:
PUT /api/auth/me/profile
请求:
{
"nickname": "新昵称"
}
约束:
后端处理:
1. 校验 nickname 长度
2. UPDATE users SET nickname = :nickname, updated_at = NOW() WHERE id = :userId
DB 表:users
后续动作:更新成功后刷新 AuthContext 中的 user 对象
---
修改头像(选择图片 → 点击保存)
触发 API:
PUT /api/auth/me/profile
请求:
{
"avatar_url": "https://example.com/avatar.jpg"
}
说明:
DB 表:users
后续动作:成功后刷新 AuthContext
---
切换「支出绿色显示」开关
触发 API:
PUT /api/auth/me/profile
请求:
{
"prefer_green_expense": true
}
说明:
prefer_green_expense = 1 → 支出金额显示为绿色prefer_green_expense = 0 → 支出金额显示为红色(默认)DB 表:users
后续动作:成功后刷新 AuthContext,HomePage/BillPage 的交易金额颜色同步更新
---
修改密码(设置页 → 密码修改)
> 注:需正式账号(is_guest=0),游客无密码字段
说明:设置页如有密码修改入口,对应的是注册流程中的 POST /auth/upgrade-guest(游客转正带密码)或忘记密码重置流程,与 SettingsPage 本身无直接关联。
---
AI Keys 管理(AI 配置卡片)
说明:AI Keys 管理是 SettingsPage 的核心功能之一,允许用户配置、管理和共享 AI API Keys。
页面加载时
触发 API(fetchKeys(),并行请求):
1. GET /api/apikeys/user
说明:获取当前用户在指定账单下配置的个人 Key 列表
Query 参数:billId(当前账单 ID)
响应:
{
"keys": [
{
"id": "string",
"provider": "openai | claude | gemini | ...",
"model": "gpt-4o | claude-3-5-sonnet | gemini-1.5-pro | ...",
"api_key_encrypted": "HIDDEN | sk-...",
"is_shared": 1,
"priority": 100
}
]
}
2. GET /api/apikeys/suggestions
说明:获取可从其他账单导入的 Key 建议
Query 参数:currentBillId(当前账单 ID,排除已配置项)
响应:
{
"suggestions": [
{
"id": "string",
"name": "工作账单 (其他)",
"key_count": 1,
"details": [{ "provider": "gemini", "model": "gemini-1.5-pro" }]
}
]
}
关联 DB 表:api_keys、bills
---
点击「添加配置」→ 填写表单 → 点击「保存」
前置条件:先选择 Provider 和 Model,再填写 API Key
触发 API(保存前先验证):
1. POST /api/apikeys/verify/user(验证连通性)
说明:仅当填写了 api_key 时才发送验证请求
请求:
{
"provider": "openai",
"api_key": "sk-...",
"model": "gpt-4o",
"billId": "B8K2L4P9Q0"
}
后端处理:用该 Key 实际发起 API 调用测试连通性
用途:让用户在保存前确认 Key 有效
2. PUT /api/apikeys/user(保存/更新)
请求:
{
"provider": "openai",
"api_key": "sk-...",
"model": "gpt-4o",
"is_shared": 1,
"priority": 100,
"billId": "B8K2L4P9Q0"
}
说明:
api_key 留空则保留原值(不清空)is_shared = 1 → 允许账单成员使用priority 越小越优先关联 DB 表:api_keys
后续动作:
1. 调用 fetchKeys() 刷新 Key 列表
2. 触发 ai-keys-updated 事件,通知 ChatBar 等组件刷新
---
点击「共享开关」→ 切换共享状态
触发 API:
PATCH /api/apikeys/user/share
请求:
{
"billId": "B8K2L4P9Q0",
"provider": "openai",
"model": "gpt-4o",
"is_shared": 1
}
说明:切换 Key 的共享状态
向后兼容:若后端返回 404,则 fallback 到 PUT /api/apikeys/user 全量更新
关联 DB 表:api_keys
---
点击「删除」→ 确认删除
触发 API:
DELETE /api/apikeys/user/:provider
请求:Query 参数 model + billId
DELETE /api/apikeys/user/openai?model=gpt-4o&billId=B8K2L4P9Q0
说明:删除用户在指定账单下的某个 Key 配置
关联 DB 表:api_keys
后续动作:
1. 调用 fetchKeys() 刷新列表
2. 触发 ai-keys-updated 事件
---
点击「导入」→ 从其他账单同步配置
触发 API:
POST /api/apikeys/import
请求:
{
"fromBillId": "OTHER_BILL_ID",
"toBillId": "B8K2L4P9Q0",
"provider": "openai",
"model": "gpt-4o"
}
说明:
provider + model 省略时导入该账单全部 Key关联 DB 表:api_keys
后续动作:调用 fetchKeys() 刷新状态
---
拖拽调整 Key 优先级 → 优先级变更
触发 API:
PATCH /api/apikeys/order/user
请求:
{
"billId": "B8K2L4P9Q0",
"orders": [
{
"provider": "gemini",
"model": "gemini-1.5-pro",
"owner_type": "user",
"owner_id": "U7X9R1P2A1",
"priority": 1
},
{
"provider": "openai",
"model": "gpt-4o",
"owner_type": "user",
"owner_id": "U7X9R1P2A1",
"priority": 2
}
]
}
说明:批量更新用户在指定账单下的 Key 优先级顺序(用于 failover 顺序)
关联 DB 表:user_provider_order
---
AI Prompt 设置(每个账单独立)
说明:每个账单可以设置独立的 AI 对话 Prompt(Custom Prompt),由 BillPage 的「Custom Prompt」入口触发。
> ⚠️ 已知问题:见 P13
触发 API:
PUT /api/bills/:billId/prompt
请求:
{
"prompt": "你是一个专业的家庭财务顾问..."
}
权限:任意账单成员(owner / editor / viewer)均可设置
后端处理:UPDATE bill_members SET custom_prompt = :prompt, updated_at = NOW() WHERE bill_id = :billId AND user_id = :userId
DB 表:bill_members(注意:prompt 属于 bill_members 表,每个用户在每个账单有独立的 custom_prompt)
---
退出登录(点击「退出登录」)
触发 API:
POST /api/auth/logout
请求:
{
"refreshToken": ""
}
说明:
后端处理:删除 refresh_tokens 表中对应记录
后续动作:
1. 清除 localStorage 中的 accessToken 和 refreshToken
2. 跳转至登录页 /login
3. 重置所有 Context 状态
---
账号注销 / 删除(若有)
> 注:当前前端可能无账号注销入口,以下为后端已知端点说明
DB 表:users(删除后 CASCADE 至 bills、bill_members、transactions、api_keys 等)
---
游客升级(点击「升级为正式账号」)
说明:游客在 SettingsPage 点击升级按钮,填写完整信息后提交
触发 API:
POST /api/auth/upgrade-guest
请求:
{
"phone": "+8613812345678",
"password": "123456",
"passwordConfirm": "123456",
"nickname": "张三",
"email": "user@example.com",
"emailCode": "123456",
"captchaId": "...",
"captchaAnswer": "ABCDE"
}
后端处理:
1. 确认当前用户是 is_guest=1
2. 校验新手机号+邮箱未被他用户占用
3. 校验邮箱验证码
4. bcrypt 更新 password_hash
5. 更新 users 表:is_guest=0
6. 生成新 JWT(2h)
DB 表:users
---
权限判断汇总
| 操作 | 权限 | API 端点 |
|------|------|---------|
| 查看个人资料 | 任意登录用户 | GET /api/auth/me(AuthContext 注入) |
| 修改昵称 | 任意登录用户 | PUT /api/auth/me/profile |
| 修改头像 | 任意登录用户 | PUT /api/auth/me/profile |
| 切换支出颜色 | 任意登录用户 | PUT /api/auth/me/profile |
| 查看 AI Key 列表 | 任意登录用户 | GET /api/apikeys/user |
| 查看 Key 建议 | 任意登录用户 | GET /api/apikeys/suggestions |
| 验证 Key | 任意登录用户 | POST /api/apikeys/verify/user |
| 保存/更新 Key | 任意登录用户 | PUT /api/apikeys/user |
| 切换共享状态 | 任意登录用户 | PATCH /api/apikeys/user/share |
| 删除 Key | 任意登录用户 | DELETE /api/apikeys/user/:provider |
| 导入其他账单的 Key | 任意登录用户 | POST /api/apikeys/import |
| 更新 Key 优先级 | 任意登录用户 | PATCH /api/apikeys/order/user |
| 设置 AI Prompt | 任意账单成员 | PUT /api/bills/:billId/prompt |
| 游客升级 | 游客用户 | POST /api/auth/upgrade-guest |
| 退出登录 | 任意登录用户 | POST /api/auth/logout |