- 添加dist/目录到.gitignore,用于排除打包输出的绿色免安装版 - 添加Wails打包过程中的临时文件和自动生成文件到.gitignore - 删除build/windows/installer/wails_tools.nsh自动生成文件 - 添加Windows安装器临时目录和Webview2安装文件到忽略列表 feat(docs): 添加万川平台对接文档和产品素材 - 创建万川平台登录到获取模型信息的流程说明文档 - 添加万川平台对接实施计划文档 - 新增产品图片、公司简介图、宣传海报、教程截图、案例展示等素材文件 refactor(runtime): 扩展通知功能类型定义 - 添加NotificationOptions接口定义 - 添加NotificationAction接口定义 - 添加NotificationCategory接口定义 - 扩展通知相关的运行时API类型声明,包括初始化、发送、注册分类等功能
9.5 KiB
万川 AI 平台:从账号密码登录到获取模型信息
本文基于当前未提交的代码梳理,描述用户在「设置」页填入平台地址 + 账号密码后, 系统如何登录、拉取模型配置并写入后端 AI 设置的完整链路。
一、整体链路总览
用户填写平台地址 / 账号 / 密码
│
▼
[1] POST /api/login ───────────────► 返回 token(缓存到 localStorage)
│
▼
[2] 登录成功后并行触发:
├─ GET /api/system/kb/relation/query 拉取岗位知识库列表
└─ syncModel() 同步模型配置
│
▼
[3] 按模型编码 code 分别拉取(携带 token):
├─ GET /api/system/model/getByCode/generic 通用/聊天模型(必拉)
├─ GET /api/system/model/getByCode/vision 视觉模型(可选)
└─ GET /api/system/model/getByCode/voice 语音模型(可选)
│
▼
[4] 解析 providerModels.encryptedConfig(JSON 字符串)
→ { modelName, apiKey, endpointUrl }
│
▼
[5] PUT /api/settings 写入后端 SQLite(app_settings 表)
│
▼
[6] 后端聊天/视觉/语音调用时按用途读取这些配置(带回退)
前端实现:chatlab-web/frontend/src/api/wanchuan.js 触发位置:chatlab-web/frontend/src/pages/SettingsPage.jsx 后端设置:chatlog_fastAPI/routers/settings.py
二、第 1 步:登录获取 token
接口
POST {platformUrl}/api/login
Content-Type: application/json;charset=UTF-8
请求体
{
"username": "用户名",
"password": "密码",
"loginType": "user"
}
响应(兼容多种结构)
代码用以下顺序提取 token,任一命中即可:
result.token
result.data.token
result.data.access_token
result.access_token
典型返回结构:
{
"code": 200,
"msg": "success",
"token": "eyJhbGci...",
"data": {
"token": "eyJhbGci...",
"modules": [ /* 平台模块列表,用于前端展示 */ ]
}
}
token 的存储与使用
- 登录成功后 token 写入
localStorage,key 为chatlab_wanchuan_token。 - 后续所有平台接口都带两个头(平台同时认这两种):
Authorization: Bearer {token} token: Bearer {token}
对应函数:wanchuanLogin(baseUrl, username, password)
(wanchuan.js:39)
三、第 2 步:登录的触发与自动恢复
登录在 SettingsPage.jsx 的 WanchuanPlatformForm 组件里触发,分两种场景:
场景 A:用户点「测试连接」(handleTestConnection)
- 调用
wanchuanLogin()登录。 - 成功后并行执行:
fetchKnowledgeBases()拉知识库列表syncModel()同步平台模型配置 → 写入后端 AI 设置
场景 B:打开设置页自动恢复(autoLogin)
- 配置(平台地址/账号/密码/已选知识库)以后端 SQLite 为唯一数据源,
通过
GET /api/settings/wanchuan读取,不依赖前端 origin(exe 端口变化也能恢复)。 - 挂载时若已有保存的账号密码,自动登录并拉知识库。
- 注意:自动恢复时不自动
syncModel,避免覆盖用户在「AI 模型配置」里手改并保存过的值。模型同步只在用户显式操作(点「测试连接」或「从平台获取」)时进行。
四、第 3-4 步:按模型编码获取模型信息
这是「获取模型信息」的核心。平台按用途用不同的模型编码(code)区分:
| code | 用途 | 同步到的后端字段 |
|---|---|---|
generic |
通用/聊天 | ai_*(话题分析)+ summary_*(报告生成) |
vision |
视觉 | vision_*(图片/视频描述) |
voice |
语音 | voice_*(语音转文字) |
接口
GET {platformUrl}/api/system/model/getByCode/{code}
Authorization: Bearer {token}
token: Bearer {token}
响应结构
{
"code": 200,
"msg": "success",
"data": {
"providerModels": {
"modelName": "qwen-plus",
"encryptedConfig": "{\"apiKey\":\"sk-xxx\",\"endpointUrl\":\"https://...../v1\"}"
}
}
}
关键点:data.providerModels.encryptedConfig 是一个 JSON 字符串,需二次 JSON.parse 才能拿到 apiKey 和 endpointUrl。
解析后得到
{
modelName: pm.modelName, // 模型名
apiKey: cfg.apiKey, // 来自 encryptedConfig
endpointUrl: cfg.endpointUrl, // 来自 encryptedConfig
}
对应函数:getWanchuanModelConfig(baseUrl, code)
(wanchuan.js:110)
错误处理:
- HTTP 非 2xx → 抛
获取模型[{code}]失败 HTTP {status}(便于排查 404 路径错 / 401 token 失效)。 - 无
providerModels→ 抛平台未返回模型[{code}]配置。
五、第 5 步:写入后端 AI 设置
syncWanchuanModelToSettings() 负责编排三次拉取并合并写入:
-
generic 必拉:拿到
endpointUrl / apiKey / modelName后,同时写入两组字段:- 话题分析:
ai_base_url/ai_api_key/ai_model - 报告生成:
summary_base_url/summary_api_key/summary_model(两者同网关,但分开存便于各组独立回显与覆盖。)
- 话题分析:
-
vision / voice 可选:用
Promise.all并行拉取,失败则跳过对应字段(.catch(() => {})),不打断聊天模型同步:vision_base_url/vision_api_key/vision_modelvoice_base_url/voice_api_key/voice_model
-
仅写入非空字段;若最终 payload 为空则抛
平台模型配置为空。 -
最后
PUT /api/settings保存到后端:
PUT /api/settings
Content-Type: application/json
{
"ai_base_url": "...", "ai_api_key": "...", "ai_model": "...",
"summary_base_url": "...", "summary_api_key": "...", "summary_model": "...",
"vision_base_url": "...", "vision_api_key": "...", "vision_model": "...",
"voice_base_url": "...", "voice_api_key": "...", "voice_model": "..."
}
对应函数:syncWanchuanModelToSettings(baseUrl, codes)
(wanchuan.js:151)
六、后端 /api/settings 的处理
实现在 chatlog_fastAPI/routers/settings.py。
可编辑字段(EDITABLE_KEYS)
ai_base_url, ai_api_key, ai_model, summary_model,
vision_model, voice_model, topic_analysis_prompt,
voice_base_url, voice_api_key, vision_base_url, vision_api_key,
summary_base_url, summary_api_key
密钥脱敏(SECRET_KEYS)
ai_api_key / voice_api_key / vision_api_key / summary_api_key 四个字段:
- GET 返回时打码(
_mask_key,只保留首尾、中间打*)。 - PUT 时若值里含
*,说明是 GET 返回的打码值(用户没真改),跳过不写,避免把真实密钥覆盖成打码串。
存储
所有字段以 key-value 形式存进 SQLite 的 app_settings 表(INSERT ... ON CONFLICT DO UPDATE)。
七、第 6 步:后端运行时如何使用这些配置
实现在 chatlog_fastAPI/services/ai_client.py 与 chatlog_fastAPI/services/runtime_settings.py。
get_ai_settings():从 SQLite 读出全部 AI 字段(带默认值),并缓存。get_openai_client():聊天类调用(话题分析 / 报告 / 总结 / 对话)用全局ai_base_url+ai_api_key。get_client_for(purpose):purpose为voice/vision, 优先用{purpose}_base_url/{purpose}_api_key,为空则回退到ai_base_url/ai_api_key(单网关场景无需重复配。- 客户端按
(base_url, api_key)缓存,聊天/视觉/语音可指向不同网关与密钥, 最多累积 3 个,配置变更后自然生成新客户端。
八、相关接口速查表
| 步骤 | 方法 | 路径 | 用途 |
|---|---|---|---|
| 登录 | POST | {platformUrl}/api/login |
账号密码换 token |
| 知识库 | GET | {platformUrl}/api/system/kb/relation/query |
拉岗位知识库列表 |
| 模型信息 | GET | {platformUrl}/api/system/model/getByCode/{code} |
按 code 取模型配置 |
| 上传 | POST | {platformUrl}/api/system/kb/file/upload/async/{datasetId} |
上传文件到知识库 |
| 读平台配置 | GET | /api/settings/wanchuan |
后端存的平台地址/账号/密码/已选库 |
| 存平台配置 | PUT | /api/settings/wanchuan |
保存平台配置 |
| 读 AI 配置 | GET | /api/settings |
回显 AI 模型配置(密钥脱敏) |
| 写 AI 配置 | PUT | /api/settings |
保存/同步 AI 模型配置 |
九、关键数据结构小结
登录请求:{ username, password, loginType: "user" }
登录响应取 token:result.token 等多路径兜底
模型接口响应:data.providerModels.{ modelName, encryptedConfig }
encryptedConfig(JSON 字符串):{ apiKey, endpointUrl, ... }
最终归一化模型对象:{ modelName, apiKey, endpointUrl }
写入后端的 12 个字段:{ai,summary,vision,voice}_{base_url,api_key,model}