package main // update_api.go — 「版本與更新」頁的後端(t193) // // 🔴 leo 2026-08-04:「檢查更新連到 docs 的檢查更新,**不正確**, // 是**直接在這裡進行檢查更新**,應該是跳到一個頁面顯示**現在版本與最新版本**, // 然後**下載可以進行安裝**」 // // ⇒ 三段式,全部在 App 內完成,不把人丟去網頁: // ① CheckUpdate 查最新版 → 前端顯示「現在版本 vs 最新版本」 // ② DownloadUpdate 下載+sha256 校驗 → 備妥 // ③ ApplyUpdate 覆蓋正在跑的 .app 並重啟 import ( "runtime" "strings" ) // UpdateInfo 是「版本與更新」頁要顯示的一切。 type UpdateInfo struct { Current string `json:"current"` Latest string `json:"latest"` Available bool `json:"available"` Notes string `json:"notes,omitempty"` Staged bool `json:"staged"` // 已下載備妥、等重啟套用 Err string `json:"err,omitempty"` // 誠實回報,不假裝成功 } func (a *App) CheckUpdate() UpdateInfo { info := UpdateInfo{Current: version} rel, err := fetchLatestRelease() if err != nil { info.Err = "暫時連不上更新伺服器:" + err.Error() return info } info.Latest = rel.Version info.Notes = rel.Notes info.Available = newerThanCurrent(rel.Version) if s := loadStaged(); s.Ready && s.Version == rel.Version { info.Staged = true } return info } func (a *App) DownloadUpdate() UpdateInfo { info := UpdateInfo{Current: version} rel, err := fetchLatestRelease() if err != nil { info.Err = "暫時連不上更新伺服器:" + err.Error() return info } info.Latest, info.Notes = rel.Version, rel.Notes info.Available = newerThanCurrent(rel.Version) zip, err := downloadUpdate(rel) if err != nil { // 誠實:下載/校驗失敗就說失敗,不留下半個檔假裝好了 info.Err = "下載失敗:" + err.Error() return info } currentStaged = stagedUpdate{Version: rel.Version, ZipPath: zip, Ready: true} saveStaged(currentStaged) info.Staged = true return info } func (a *App) ApplyUpdate() error { if err := applyStagedAndRestart(); err != nil { return err } return nil } // isWindows 供 selfupdate.go 使用(原本在 arcrun-tray 的 main.go)。 func isWindows() bool { return strings.EqualFold(runtime.GOOS, "windows") }