# 桌面端版本检查接口对接文档 > 面向桌面端客户端和其他项目 agent。本文只说明「获取当前软件最新版本」接口如何调用,不涉及 API Key、点数、生成接口或用户账本。 ## 接口用途 桌面端启动时或用户点击「检查更新」时,请求 cmhub 获取当前平台的最新客户端版本、下载地址、SHA256 校验值和发布说明。 该接口是公开只读接口: - 不需要 `Authorization`。 - 不需要登录态 cookie。 - 不读取用户信息。 - 不扣点。 - 不占用生成接口限流。 - 不返回后台 ID、本地文件系统路径、用户信息、API Key、模型配置或密钥。 ## 请求地址 生产环境: ```text GET https://cm.833729.com/api/v1/client/releases/latest?platform=windows ``` 本地开发: ```text GET http://127.0.0.1:8000/api/v1/client/releases/latest?platform=windows ``` ## 请求参数 | 参数 | 必填 | 默认值 | 可选值 | 说明 | | --- | --- | --- | --- | --- | | `platform` | 否 | `windows` | `windows` / `macos` / `linux` | 客户端运行平台。当前桌面端 Windows 客户端传 `windows` 即可。 | 建议桌面端显式传 `platform=windows`,不要依赖默认值。 ## 请求 Demo ### curl ```bash curl -s "https://cm.833729.com/api/v1/client/releases/latest?platform=windows" ``` ### Windows PowerShell ```powershell Invoke-RestMethod ` -Method Get ` -Uri "https://cm.833729.com/api/v1/client/releases/latest?platform=windows" ` -TimeoutSec 10 ``` ### Python ```python import requests url = "https://cm.833729.com/api/v1/client/releases/latest" response = requests.get(url, params={"platform": "windows"}, timeout=10) response.raise_for_status() data = response.json() release = data.get("release") if release is None: print("暂未发布") else: print(release["version"], release["download_url"]) ``` ### JavaScript / TypeScript ```ts const response = await fetch( "https://cm.833729.com/api/v1/client/releases/latest?platform=windows", { method: "GET" }, ); if (!response.ok) { throw new Error(`version check failed: ${response.status}`); } const data = await response.json(); if (data.release) { console.log(data.release.version, data.release.download_url); } ``` ## 成功响应:有当前版本 HTTP 状态码:`200` ```json { "platform": "windows", "release": { "version": "1.0.0", "download_url": "https://cm.833729.com/media/downloads/cmhub-desktop-1.0.0.exe", "sha256": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef", "release_notes": "本次更新说明", "published_at": "2026-07-07T10:30:00+08:00" } } ``` 字段说明: | 字段 | 类型 | 说明 | | --- | --- | --- | | `platform` | string | 服务端实际查询的平台。 | | `release.version` | string | 最新客户端版本号。 | | `release.download_url` | string | 下载地址。可能是本站 `/media/downloads/...` 的绝对 URL,也可能是后台配置的外部 CDN / 对象存储 URL。 | | `release.sha256` | string | 安装包 SHA256。桌面端下载后应计算本地文件 SHA256 并比对。 | | `release.release_notes` | string | 发布说明,可能为空字符串。 | | `release.published_at` | string | ISO 8601 时间;当前实现使用发布记录更新时间。 | ## 成功响应:暂未发布 HTTP 状态码:`200` ```json { "platform": "windows", "release": null, "message": "暂未发布" } ``` 客户端处理建议: - 把 `release === null` 视为「没有可下载版本」。 - 不要弹错误框。 - 可在日志中记录,也可在「检查更新」按钮下显示「暂未发布」。 ## 错误响应:非法平台 HTTP 状态码:`400` ```json { "error": { "code": "bad_request", "message": "参数错误" } } ``` 常见原因:`platform=android` 或其他未支持的平台。 ## 客户端对接要求 1. 调用版本检查接口时不要带 API Key。 2. 不要解析首页 HTML 获取版本号,必须使用本 JSON 接口。 3. 网络超时建议 5 到 10 秒;失败时不影响主程序启动。 4. 客户端应把本地版本号与 `release.version` 比较,只有远端版本更新时才提示用户下载。 5. 下载完成后按 `release.sha256` 校验安装包;校验失败必须删除文件并提示重新下载。 6. 不要假设下载地址一定在 cmhub 域名下,后续可能切到 CDN 或对象存储。 7. 不要依赖 `message` 做业务判断;是否有版本以 `release` 是否为 `null` 为准。 ## 版本比较建议 版本号建议采用语义化版本格式,例如: ```text 1.0.0 1.1.0 1.1.1 2.0.0 ``` 客户端比较时不要做普通字符串比较。例如 `"1.10.0"` 应大于 `"1.9.0"`。 简化 Python 示例: ```python def parse_version(version: str) -> tuple[int, ...]: return tuple(int(part) for part in version.split(".")) if parse_version(remote_version) > parse_version(local_version): print("发现新版本") ``` 如果未来版本号包含 `beta` / `rc` 等预发布标记,客户端需要使用更完整的语义化版本解析器。 ## 下载校验建议 Python 计算 SHA256 示例: ```python import hashlib from pathlib import Path def sha256_file(path: str) -> str: digest = hashlib.sha256() with Path(path).open("rb") as file: for chunk in iter(lambda: file.read(1024 * 1024), b""): digest.update(chunk) return digest.hexdigest() ``` 比对时建议统一转小写: ```python if sha256_file(downloaded_path).lower() != release["sha256"].lower(): raise RuntimeError("安装包 SHA256 校验失败") ``` ## 服务端发布前置条件 运营在 django-admin 的「客户端下载版本」里维护发布记录: - `platform`:选择 `windows`。 - `version`:填写客户端版本号。 - `file` 或 `external_url`:至少填写一个。 - `sha256`:填写安装包 SHA256。 - `is_current`:勾选当前版本。 - `release_notes`:填写发布说明。 同一平台只能有一个当前版本;保存新的当前版本时,旧当前版本会自动取消当前状态。 如果使用本地上传文件,生产环境必须确保 Nginx 正确服务 `MEDIA_ROOT/downloads/`,否则接口会返回下载 URL,但客户端下载可能 404。 ## 排查清单 | 现象 | 优先检查 | | --- | --- | | 返回 `release:null` | django-admin 是否有该 `platform` 的 `is_current=True` 发布记录;发布记录是否有 `external_url` 或上传文件。 | | 返回 `400 bad_request` | `platform` 是否为 `windows` / `macos` / `linux`。 | | `download_url` 访问 404 | Nginx media 配置是否正确;本地上传文件是否存在;若使用 `external_url`,外部地址是否可访问。 | | SHA256 校验失败 | 后台填写的 SHA256 是否对应当前安装包;安装包是否被重新打包但未更新 SHA256。 | | 客户端每次都提示更新 | 客户端版本比较逻辑是否按数字段比较,而不是字符串比较。 |