feat: LAN update check on startup with notify banner (stage 2)

Read manifest.json from the configured update_source and show a dismissable
banner when a newer version is available. Notify-only — no install yet.

- services/update_service.py: version compare + check_for_update (pure, tested)
- config: add update_source key (empty = no check)
- main_window: top banner, background-thread check; open folder via os.startfile
  (QDesktopServices.openUrl mishandles file:// folder URLs — ShellExecute err 2)
- tests: +15 covering version compare and check_for_update branches
- docs 02/05/10 + tasks 17.16

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-17 17:05:46 +08:00
co-authored by Claude Opus 4.8
parent f2b08fecb3
commit 0392e1c8a2
8 changed files with 373 additions and 9 deletions
+6 -6
View File
@@ -116,7 +116,7 @@
## 7. 更新源与版本清单
更新源为内网共享目录(UNC 路径)或内网文件服务,例如:
更新源路径由 `app_config.json` 的 `update_source` 配置(见 `docs/02-prd.md`);为空时不做更新检查。更新源为内网共享目录(UNC 路径)或内网文件服务,例如:
```text
\\nas\cmbot\releases\
@@ -225,12 +225,12 @@
## 16. 实现阶段建议
建议分阶段落地,每阶段可独立验证:
分阶段落地,每阶段可独立验证:
1. **地基**:数据目录分离(第 5 节)。任何更新方案的前提,先行完成并通过现有测试。
2. **只读通知**:启动时读取 `manifest.json` 比对版本,有新版仅提示并打开更新源目录(不自动安装)。验证版本检查与降级逻辑。
3. **自动安装**:实现启动器完整流程(下载 → 校验 → 原子切换 → 启动 → 回滚)。
4. **强制更新与保留策略**:补全 `mandatory` / `min_supported` 与版本清理。
1. **地基**:数据目录分离(第 5 节)。任何更新方案的前提。✅ 已实现。
2. **只读通知**:启动时读取 `manifest.json` 比对版本,有新版仅提示并打开更新源目录(不自动安装)。✅ 已实现——`services/update_service.py`(`check_for_update` / 版本比较,纯逻辑可测)+ 主窗口顶部通知横幅,检查在后台线程进行(更新源不可达不阻塞启动),更新源路径由 `update_source` 配置。
3. **自动安装**:实现启动器完整流程(下载 → 校验 → 原子切换 → 启动 → 回滚)。⛔ 未做。
4. **强制更新与保留策略**:补全 `mandatory` / `min_supported` 与版本清理。⛔ 未做。
## 17. 暂不做