From aeccc9946be8c7d19f63eaabae4d33bc59a1ef69 Mon Sep 17 00:00:00 2001 From: qian Date: Fri, 14 Aug 2026 22:50:13 +0800 Subject: [PATCH] =?UTF-8?q?fix(sys):=E4=BF=AE=E5=A4=8D=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E4=B8=8D=E8=83=BD=E5=8F=8A=E6=97=B6=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=9C=80=E6=96=B0=E7=89=88=E6=9C=AC=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/logic/update/checker.go | 19 ++++++++++++------- web/admin/src/views/AdminLayout.vue | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/internal/logic/update/checker.go b/internal/logic/update/checker.go index 75c9a8b..25a4e11 100644 --- a/internal/logic/update/checker.go +++ b/internal/logic/update/checker.go @@ -35,8 +35,8 @@ func CheckForUpdate(ctx context.Context, force bool) (*CheckResult, error) { } } - // Call GitHub API - release, etag, err := fetchLatestRelease(ctx) + // Call GitHub API(force 时不带 ETag 条件请求,见 fetchLatestRelease 注释) + release, etag, err := fetchLatestRelease(ctx, !force) if err != nil { return nil, fmt.Errorf("failed to fetch latest release: %w", err) } @@ -120,8 +120,11 @@ func CheckForUpdate(ctx context.Context, force bool) (*CheckResult, error) { return result, nil } -// fetchLatestRelease calls the GitHub Releases API with conditional request support -func fetchLatestRelease(ctx context.Context) (*GitHubRelease, string, error) { +// fetchLatestRelease calls the GitHub Releases API. +// conditional 为 true 时携带 If-None-Match ETag 做条件请求(省配额); +// 强制检测(force)必须传 false:GitHub /releases/latest 有 CDN 缓存,刚发布新版本后 +// 条件请求可能返回过期的 304 Not Modified,导致强制检测仍拿不到最新发行版。 +func fetchLatestRelease(ctx context.Context, conditional bool) (*GitHubRelease, string, error) { url := githubAPIBase + "/releases/latest" req, err := http.NewRequestWithContext(ctx, "GET", url, nil) @@ -133,9 +136,11 @@ func fetchLatestRelease(ctx context.Context) (*GitHubRelease, string, error) { req.Header.Set("X-GitHub-Api-Version", "2022-11-28") // Add ETag for conditional request - if etagVal := manager.lastETag.Load(); etagVal != nil { - if etag, ok := etagVal.(string); ok && etag != "" { - req.Header.Set("If-None-Match", etag) + if conditional { + if etagVal := manager.lastETag.Load(); etagVal != nil { + if etag, ok := etagVal.(string); ok && etag != "" { + req.Header.Set("If-None-Match", etag) + } } } diff --git a/web/admin/src/views/AdminLayout.vue b/web/admin/src/views/AdminLayout.vue index 6d93f7f..8b79d79 100644 --- a/web/admin/src/views/AdminLayout.vue +++ b/web/admin/src/views/AdminLayout.vue @@ -58,6 +58,7 @@ const updateModalVisible = ref(false) const updateLoading = ref(false) const executing = ref(false) const rollingBack = ref(false) +const checking = ref(false) const updateStatus = ref(null) const releaseNotes = ref('') const releaseUrl = ref('') @@ -129,6 +130,16 @@ function openUpdateModal() { checkUpdate() // 打开弹窗时刷新版本检查,确保当前版本/最新版本为最新 } +// 立即检测:force=true 跳过后端检查缓存,强制向上游拉取最新版本信息 +async function manualCheck() { + checking.value = true + try { + await Promise.all([fetchUpdateStatus(), checkUpdate(true)]) + } finally { + checking.value = false + } +} + function closeUpdateModal() { updateModalVisible.value = false stopPolling() @@ -717,6 +728,9 @@ onUnmounted(() => { +