Files
cmautobuy/docs/task/93-client在线更新与安全回退.md
T

79 lines
4.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 93 Client:实现安全的在线检查、下载和下次启动更新
- 类型:需求
- 父级大工单:#1
- 所属 MVP / 版本:MVP 后续 / 在线更新
- 状态:已完成,用户验收通过
- 日期:2026-08-10
- Gitea 工单:http://ilaer.eicp.net:8418/chengma/cmautobuy/issues/93
## 背景与目标
#92 已建立 `Launcher.exe + app/ + data/` 发布结构,但 Client 仍需人工取得并
替换更新包。本任务增加用户主动检查和下载更新的能力,并保证更新不阻塞界面、
不覆盖本地数据,也不强制中断正在执行的采集或采购任务。
## 最终方案
- 设置页显示当前版本、HTTPS 清单地址、检查按钮和稳定的更新状态。
- 检查和下载使用 `QObject + moveToThread`,发现新版本后先由用户确认。
- 清单地址只允许不含凭据、查询参数和片段的 HTTPS URL;更新包必须同源,并校验
大小、SHA256、版本和 ZIP 路径。
- 更新包安全暂存到 `data/update/app.new`,不会直接替换运行中的程序。
- 下次通过 `Launcher.exe` 启动时才替换 `app`,旧版保留为 `app.old`;移动失败或
新版本未通过健康检查时恢复旧版。
- Client 版本升级为 `0.2.0`。由于 `0.1.0` 的 Launcher 不具备更新能力,第一次
升级到 `0.2.0` 仍须人工替换完整发布目录,从 `0.2.0` 起才支持在线更新。
最终实现与建单方案一致。清单 URL 额外禁止查询参数,避免 token 一类凭据随地址
写入 SQLite 或错误提示。
## 改了哪些
- `client/src/update_service.py`:检查清单、下载校验、安全解压和待更新状态。
- `client/src/update_ui_event.py`:在线更新后台 Worker、确认框、进度和生命周期。
- `client/src/settings_ui.py`、`settings_ui_event.py`:设置页软件更新区域及事件装配。
- `client/build_tools/launcher.py`:下次启动替换、运行识别、健康确认和失败回退。
- `client/src/ui_main.py`、`version.py`:启动健康标记和 `0.2.0` 版本号。
- `client/test/test_update_service.py`、`test_update_ui_event.py`、`test_packaging.py`:
更新服务、界面线程和 Launcher 测试。
- `docs/client/01-requirements.md`、`02-architecture.md`、`05-ui-specification.md`、
`06-quality-security.md`:同步需求、架构、界面和安全基线。
## 验收结果
| 验收标准 | 结果 |
|---|---|
| 设置页可配置 HTTPS 清单地址,非法地址有明确提示 | 通过 |
| 检查和下载不阻塞主线程,且防止重复启动 | 通过 |
| 新版本由用户确认下载,完成后不强制重启 | 通过 |
| 校验大小、SHA256、版本、HTTPS 和同源 | 通过 |
| 拒绝越界路径、绝对路径、反斜杠路径和符号链接 | 通过 |
| 更新只写 `data/update`,本地 `data` 内容保持不变 | 通过 |
| Launcher 保留 `app.old`,支持移动失败和健康失败回退 | 通过 |
| 已运行的主程序不会被 Launcher 替换 | 通过 |
| 真实下单开关和 Admin 业务接口未改变 | 通过 |
| 自动测试、打包和旧版升级冒烟通过 | 通过 |
## 测试
- 执行的命令:
- 在 `client/` 执行
`C:/Python310/python.exe -m pytest test -q --disable-warnings`
- 在 `client/` 执行 `.\build_client.bat`
- 在临时发布目录使用最终 `Launcher.exe` 执行 0.1.0 → 0.2.0 升级冒烟
- 结果:256 项测试通过;0.2.0 发布产物生成成功;升级后当前 `app` 为 0.2.0,
`app.old` 为 0.1.0,`data` 哨兵保留,健康标记生成,待更新状态清除。
- **没验证到的部分**:尚无真实 HTTPS 静态发布地址,未执行真实公网下载;尚未在
全新且未安装 Python 的 Windows 机器上人工验证;重复 Launcher 的提示由单元
测试覆盖,未人工点击原生提示框。
## 遗留问题
- 当前 SHA256 用于发现下载损坏,不能证明发布者身份。清单签名和 Windows 代码
签名不在本工单范围内。
## 相关提交
- `6d6829e` feat: 实现 Client 在线更新与安全回退 (#93)