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
+3 -1
View File
@@ -330,7 +330,8 @@ CMBot/
"last_garment_dir": "",
"last_print_dir": "",
"last_template": "正方形模板",
"last_batch_mode": "full_combo"
"last_batch_mode": "full_combo",
"update_source": ""
}
```
@@ -339,6 +340,7 @@ CMBot/
- `last_garment_dir` / `last_print_dir`:上次打开的衣服 / 印花文件夹路径,用于让文件夹对话框定位到上次位置。
- `last_template`:上次选中的模板名称,用于启动恢复。
- `last_batch_mode`:上次选择的批量模式(取 `BatchMode` 枚举值,如 `full_combo` / `many_garments` / `many_prints` / `one_to_one`)。
- `update_source`:局域网更新源目录(含 `manifest.json`)。为空时不做更新检查。详见 `docs/10-lan-update.md`。
- 偏好的读取、分发与「改一次存一次」由主窗口集中处理,UI 控件不直接读写配置文件。
## 10. 验收标准
+1 -1
View File
@@ -240,7 +240,7 @@ BatchResult
- 读取和保存应用配置。
- 管理默认配置。
- 在配置损坏或缺失时提供安全默认值。
- 持久化用户偏好:输出设置、上次的衣服/印花文件夹(`last_garment_dir`/`last_print_dir`)、上次选择的模板(`last_template`)、上次选择的批量模式(`last_batch_mode`)等。
- 持久化用户偏好:输出设置、上次的衣服/印花文件夹(`last_garment_dir`/`last_print_dir`)、上次选择的模板(`last_template`)、上次选择的批量模式(`last_batch_mode`)、局域网更新源(`update_source`)等。
由主窗口集中使用:启动时加载一次并把初值分发给各面板,面板选择变化时「改一次存一次」回写。各 UI 控件不直接读写配置文件,避免分散解析。
+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. 暂不做