3.5 KiB
3.5 KiB
id, title, phase, deps, status, created
| id | title | phase | deps | status | created | ||
|---|---|---|---|---|---|---|---|
| T-618 | 强制升级进度窗口与自动下载重启编排 | 8 |
|
TODO | 2026-07-13 |
问题 / 背景
T-544当前“下载新版”只打开浏览器并退出。完成安全下载暂存和独立更新器后,需要把它们接回启动门禁:用户点击「立即升级」后在软件内看到持续进度,下载和准备完成后旧程序退出,由更新器替换并自动启动新版。
方案
- 扩展
UpdateInfo/UpdateCheckResult,解析并校验size_bytes、package_format、updater_protocol、可选签名字段;旧接口仍可用于手动下载提示,但只有完整自动安装元数据才能启用「立即升级」。 - 用专用模态
QDialog替代当前一次性QMessageBox。状态包括:发现必须升级、下载、校验、暂存、准备重启、失败;显示中文阶段、进度百分比、已下载/总大小和发布说明,不显示URL、内部路径、堆栈或英文异常。 - 下载、hash、解压和manifest校验全部由
QObject + QThreadworker执行;主线程只更新UI。线程引用保留到thread.finished,退出/取消使用协作式停止并等待安全清理,禁止出现QThread: Destroyed while thread is still running。 - 强制响应元数据完整时按钮为「立即升级」「退出程序」;运行中允许退出并协作式取消;失败后为「重试」「退出程序」。没有成功启动更新器前,用户不能进入主窗口。
- 区分失败边界:版本接口完全不可达/非法时保持T-544失败放行;一旦服务端已明确返回强制升级,后续元数据缺失、下载、校验、暂存或启动更新器失败都保持阻断,只允许重试或退出。
- 启动时先检查本地已验证
pending.json;有效则直接进入“准备重启”,不重复下载。无效pending清理后再请求/下载。 - 暂存成功后生成plan,把更新器复制到临时目录并以无窗口方式启动;确认更新器进程创建成功后,主程序退出事件循环。更新器完成替换后自动启动新版。
- 同步
app/gui/__init__.py、docs/update-check.md、docs/packaging.md和docs/routes.md。普通非强制更新仍不新增提示。
验收要点
- 命中强制更新后不能创建或进入
MainWindow;点击「立即升级」不调用浏览器。 - 下载、校验、暂存阶段GUI持续响应且中文进度正确;失败可重试,退出不会遗留运行线程或把part当完整包。
- 服务端明确强制但hash/大小/格式不完整时阻断自动安装并给中文原因,不降级放行旧版。
- 有效pending重启后直接继续安装,不重复下载或重复解压。
- 更新器启动失败时旧程序文件完全不变;启动成功后旧主程序退出,新程序由更新器拉起。
- 版本接口断网仍按现有策略允许进入,且记录脱敏诊断日志。
测试要求
- 更新
tests/test_update_check.py、tests/test_gui.py,新增worker/对话框测试,覆盖状态转换、进度、重试、取消、失败放行与强制后阻断。 - 使用mock更新器验证主程序只在更新器成功创建后退出;不得在自动化测试访问真实线上。
- 运行ruff、compileall、完整unittest和
git diff --check。
边界(不改什么)
- 不改变非强制更新产品策略。
- 不实现早期崩溃健康回滚和失败版本熔断;T-619负责。
- 不修改五个业务Tab、CDP、AI、Excel、SQLite业务表或蝦皮流程。
执行记录
(完成后记录实现、验证命令与结果。)