Files
qiweimanager-master/config/docs/万川平台-登录到获取模型信息-流程说明.md
yuanzhipeng a926ee6b1b chore(build): 更新.gitignore配置和清理Wails临时文件
- 添加dist/目录到.gitignore,用于排除打包输出的绿色免安装版
- 添加Wails打包过程中的临时文件和自动生成文件到.gitignore
- 删除build/windows/installer/wails_tools.nsh自动生成文件
- 添加Windows安装器临时目录和Webview2安装文件到忽略列表

feat(docs): 添加万川平台对接文档和产品素材

- 创建万川平台登录到获取模型信息的流程说明文档
- 添加万川平台对接实施计划文档
- 新增产品图片、公司简介图、宣传海报、教程截图、案例展示等素材文件

refactor(runtime): 扩展通知功能类型定义

- 添加NotificationOptions接口定义
- 添加NotificationAction接口定义
- 添加NotificationCategory接口定义
- 扩展通知相关的运行时API类型声明,包括初始化、发送、注册分类等功能
2026-06-25 18:13:11 +08:00

9.5 KiB
Raw Blame History

万川 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  写入后端 SQLiteapp_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 写入 localStoragekey 为 chatlab_wanchuan_token
  • 后续所有平台接口都带两个头(平台同时认这两种):
    Authorization: Bearer {token}
    token: Bearer {token}
    

对应函数:wanchuanLogin(baseUrl, username, password) wanchuan.js:39


三、第 2 步:登录的触发与自动恢复

登录在 SettingsPage.jsxWanchuanPlatformForm 组件里触发,分两种场景:

场景 A用户点「测试连接」handleTestConnection

  1. 调用 wanchuanLogin() 登录。
  2. 成功后并行执行:
    • fetchKnowledgeBases() 拉知识库列表
    • syncModel() 同步平台模型配置 → 写入后端 AI 设置

场景 B打开设置页自动恢复autoLogin

  • 配置(平台地址/账号/密码/已选知识库)以后端 SQLite 为唯一数据源 通过 GET /api/settings/wanchuan 读取,不依赖前端 originexe 端口变化也能恢复)。
  • 挂载时若已有保存的账号密码,自动登录并拉知识库。
  • 注意:自动恢复时自动 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 才能拿到 apiKeyendpointUrl

解析后得到

{
  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() 负责编排三次拉取并合并写入:

  1. generic 必拉:拿到 endpointUrl / apiKey / modelName 后,同时写入两组字段:

    • 话题分析:ai_base_url / ai_api_key / ai_model
    • 报告生成:summary_base_url / summary_api_key / summary_model (两者同网关,但分开存便于各组独立回显与覆盖。)
  2. vision / voice 可选:用 Promise.all 并行拉取,失败则跳过对应字段.catch(() => {})),不打断聊天模型同步:

    • vision_base_url / vision_api_key / vision_model
    • voice_base_url / voice_api_key / voice_model
  3. 仅写入非空字段;若最终 payload 为空则抛 平台模型配置为空

  4. 最后 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.pychatlog_fastAPI/services/runtime_settings.py

  • get_ai_settings():从 SQLite 读出全部 AI 字段(带默认值),并缓存。
  • get_openai_client():聊天类调用(话题分析 / 报告 / 总结 / 对话)用全局 ai_base_url + ai_api_key
  • get_client_for(purpose)purposevoice / 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" } 登录响应取 tokenresult.token 等多路径兜底 模型接口响应data.providerModels.{ modelName, encryptedConfig } encryptedConfigJSON 字符串):{ apiKey, endpointUrl, ... } 最终归一化模型对象{ modelName, apiKey, endpointUrl } 写入后端的 12 个字段{ai,summary,vision,voice}_{base_url,api_key,model}