Files
cmshoppe/docs/update-check.md
T
chengmaandClaude Opus 4.8 46adc32e2d
Tests / Python 3.11 / Windows (push) Has been cancelled
docs: add update-check contract (T-559 done)
新增 docs/update-check.md:版本检查接口的服务端响应契约、客户端字段读取、
强制规则与发版约定(方案A force_update / 方案B min_supported_version);
README 加索引;T-559 标 DONE。客户端无需改代码(T-544 已实现)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 14:46:03 +08:00

5.1 KiB
Raw Blame History

版本检查接口契约(启动强制升级)

客户端在启动时请求版本接口,判断是否需要强制升级。本文是服务端响应格式的权威契约——字段以 app/update_check.py 的实际读取逻辑为准,服务端按此返回,避免格式漂移。 客户端逻辑已由 T-544 实现,本文不要求改客户端代码;发强制版时按「发版约定」配置服务端响应即可。

一、接口

  • 客户端在 main() 启动流程里、进主界面之前请求(app/gui/__init__.py 的 _run_startup_update_gate → app/update_check.py)。
  • URL 硬编码于 app/version.py:
    APP_UPDATE_CHECK_URL = "https://cm.833729.com/api/v1/client/releases/latest?platform=windows"
    
  • 方法:GET,请求头 Accept: application/json、User-Agent: cmshopee/<版本>。
  • 客户端当前版本见 app/version.py 的 APP_VERSION。

二、客户端读取的字段(update_check.parse_update_info)

响应是一个 JSON 对象。以下字段顶层 payload 或 release 子对象里都认(客户端按 payload.get(x) or release.get(x) 取,顶层优先):

字段 类型 说明
version / latest_version string 最新版本号。客户端取 payload.latest_version 或 release.version。latest_version 与 min_supported_version 至少要有一个,否则客户端判为"接口缺字段"、按失败放行
force_update bool 是否强制升级。true/1/yes/y/on(大小写不敏感)都识别为真
min_supported_version string 最低支持版本;本地低于它一律强制
download_url string(URL) 「下载新版」按钮打开的地址(用系统浏览器打开)
sha256 string 安装包校验值;第一版不校验,可留空
release_notes / message string 升级说明,显示在强制升级弹窗里。客户端取 message 或 release_notes

版本号比较用语义化数字段比较(compare_versions,逐段比数字),不是字符串字典序:0.1.10 > 0.1.9。

三、强制规则(is_forced_update)

满足任一即判为强制:

  1. force_update = true 且 本地版本 < latest_version;
  2. 本地版本 < min_supported_version。

两者都不满足 → 非强制。

四、客户端行为(T-544 已实现)

  • 强制:弹模态框,显示 release_notes/message,按钮只有「下载新版」(打开 download_url)和「退出程序」;无论点哪个,程序退出、进不了主界面 → 必须升级后才能用。
  • 非强制:不弹任何提示,直接进主界面(当前无"温和可跳过提示"分支;如需另立任务)。
  • 失败放行:接口断网、超时、返回非法 JSON、缺 latest_version/min_supported_version 时,客户端记诊断日志(data/logs/cmshopee.log,step=startup_update_check「已允许继续使用」)并放行,不因服务器故障导致全员打不开。

五、发版约定(服务端据此控制)

想要的效果 服务端返回
强制升到最新(方案 A) release.force_update: true + release.version 高于要淘汰的客户端版本
强制淘汰旧版(方案 B) min_supported_version 设为要淘汰之上的版本(顶层或 release 里都可)
不强制 force_update/min_supported_version 都不给 → 客户端不弹(当前不提示)

六、示例响应

强制升级(方案 A,推荐)

{
  "platform": "windows",
  "release": {
    "version": "0.1.1",
    "download_url": "https://cm.833729.com/media/downloads/%E8%9D%A6%E7%9A%AE%E5%9C%88%E5%84%AA%E5%8C%96%E5%8A%A9%E6%89%8B0.1.1.zip",
    "sha256": "",
    "release_notes": "优化了ai模块的生图的功能",
    "published_at": "2026-07-08T14:30:26.935549+08:00",
    "force_update": true
  }
}

效果:本地 0.1.0 < 0.1.1 且 force_update=true → 强制弹窗、必须升级。

强制淘汰旧版(方案 B)

{
  "platform": "windows",
  "min_supported_version": "0.1.1",
  "release": {
    "version": "0.1.1",
    "download_url": "https://cm.833729.com/media/downloads/...0.1.1.zip",
    "release_notes": "优化了ai模块的生图的功能"
  }
}

效果:本地低于 0.1.1 的一律强制升级。

不强制(有新版但不逼升)

{
  "platform": "windows",
  "release": {
    "version": "0.1.1",
    "download_url": "https://cm.833729.com/media/downloads/...0.1.1.zip",
    "release_notes": "优化了ai模块的生图的功能"
  }
}

效果:客户端解析成功但判为非强制 → 当前不弹提示,直接进主界面。

七、注意

  • 服务端返回 force_update/min_supported_version 属本仓库外的服务端配置;客户端代码(app/update_check.py/app/version.py/启动流程)已按本契约实现,发强制版不需要改客户端。
  • download_url 里的中文可用 URL 编码(如 %E8%9D%A6...),系统浏览器能正确打开。
  • 若将来要"非强制也温和提示(可跳过、不阻断)",需在客户端加一个非强制分支,另立任务。