From 8947bdc8d84959e02106f5c632adb66e03e0e174 Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 26 May 2026 09:56:18 +0800 Subject: [PATCH] =?UTF-8?q?[=E4=BC=98=E5=8C=96]=20=E6=9B=B4=E6=96=B0=20Pub?= =?UTF-8?q?lishConfigVersion=20=E5=87=BD=E6=95=B0=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=BC=BA=E5=88=B6=E5=8F=91=E5=B8=83=E9=80=89=E9=A1=B9?= =?UTF-8?q?=EF=BC=8C=E5=B9=B6=E8=B0=83=E6=95=B4=E7=9B=B8=E5=85=B3=E8=B0=83?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- openflare_server/controller/config_version.go | 3 +- openflare_server/service/agent_test.go | 4 +-- openflare_server/service/config_version.go | 4 +-- openflare_server/service/https_phase1_test.go | 34 +++++++++---------- .../config-versions/api/config-versions.ts | 5 +-- .../components/config-versions-page.tsx | 31 ++++++++++++----- .../components/proxy-routes-page.tsx | 2 +- 7 files changed, 49 insertions(+), 34 deletions(-) diff --git a/openflare_server/controller/config_version.go b/openflare_server/controller/config_version.go index e2acd99c..dfd7d177 100644 --- a/openflare_server/controller/config_version.go +++ b/openflare_server/controller/config_version.go @@ -142,7 +142,8 @@ func DiffConfigVersion(c *gin.Context) { // @Router /api/config-versions/publish [post] func PublishConfigVersion(c *gin.Context) { username := c.GetString("username") - result, err := service.PublishConfigVersion(username) + force := c.Query("force") == "true" + result, err := service.PublishConfigVersion(username, force) if err != nil { c.JSON(http.StatusOK, gin.H{ "success": false, diff --git a/openflare_server/service/agent_test.go b/openflare_server/service/agent_test.go index f021673b..a7126050 100644 --- a/openflare_server/service/agent_test.go +++ b/openflare_server/service/agent_test.go @@ -19,7 +19,7 @@ func TestGetActiveConfigForAgentIncludesPoWConfig(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - if _, err := PublishConfigVersion("root"); err != nil { + if _, err := PublishConfigVersion("root", false); err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -57,7 +57,7 @@ func TestGetActiveConfigForAgentUsesTenMinutePoWSessionDefault(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - if _, err := PublishConfigVersion("root"); err != nil { + if _, err := PublishConfigVersion("root", false); err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } diff --git a/openflare_server/service/config_version.go b/openflare_server/service/config_version.go index 3f52ec8a..a8556ff2 100644 --- a/openflare_server/service/config_version.go +++ b/openflare_server/service/config_version.go @@ -333,7 +333,7 @@ func HasConfigChanges() (bool, error) { return activeVersion.Checksum != bundle.Checksum, nil } -func PublishConfigVersion(createdBy string) (*ReleaseResult, error) { +func PublishConfigVersion(createdBy string, force bool) (*ReleaseResult, error) { bundle, err := buildCurrentConfigBundle(true) if err != nil { return nil, err @@ -342,7 +342,7 @@ func PublishConfigVersion(createdBy string) (*ReleaseResult, error) { return nil, errors.New("没有可发布的启用规则") } activeVersion, err := model.GetActiveConfigVersion() - if err == nil && activeVersion.Checksum == bundle.Checksum { + if !force && err == nil && activeVersion.Checksum == bundle.Checksum { return nil, errors.New("当前规则没有变更,不能重复发布") } if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/openflare_server/service/https_phase1_test.go b/openflare_server/service/https_phase1_test.go index 20b79783..8fdd7f16 100644 --- a/openflare_server/service/https_phase1_test.go +++ b/openflare_server/service/https_phase1_test.go @@ -48,7 +48,7 @@ func TestCreateTLSCertificateAndRenderHTTPSConfig(t *testing.T) { t.Fatal("expected https fields to be persisted") } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -158,7 +158,7 @@ func TestPublishConfigVersionRendersCustomHeaders(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -238,7 +238,7 @@ func TestPublishConfigVersionRendersRouteLevelCachePolicy(t *testing.T) { t.Fatalf("CreateProxyRoute uncached failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -297,7 +297,7 @@ func TestPublishConfigVersionRendersMultipleUpstreams(t *testing.T) { t.Fatalf("expected route upstreams to persist, got %s", route.Upstreams) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -354,7 +354,7 @@ func TestPublishConfigVersionRendersMultiDomainWebsite(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -424,7 +424,7 @@ func TestPublishConfigVersionRendersMultipleCertificatesForMultiDomainWebsite(t t.Fatalf("expected domain_cert_ids to persist per domain, got %#v", route.DomainCertIDs) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -480,7 +480,7 @@ func TestPublishConfigVersionSkipsHTTPSForDomainsWithoutCertificate(t *testing.T t.Fatalf("expected domain_cert_ids to preserve unassigned domains, got %#v", route.DomainCertIDs) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -510,7 +510,7 @@ func TestDiffConfigVersionTracksAddedDomainWithinWebsite(t *testing.T) { if err != nil { t.Fatalf("CreateProxyRoute failed: %v", err) } - if _, err := PublishConfigVersion("root"); err != nil { + if _, err := PublishConfigVersion("root", false); err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -578,7 +578,7 @@ func TestPublishConfigVersionRendersRouteRateLimits(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -615,7 +615,7 @@ func TestPublishConfigVersionRendersHostnameLoadBalancingUpstream(t *testing.T) t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -649,7 +649,7 @@ func TestPublishConfigVersionOverridesOriginHostHeader(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -685,7 +685,7 @@ func TestPublishConfigVersionUsesNamedUpstreamForOriginBasePath(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -709,7 +709,7 @@ func TestPublishConfigVersionUsesNamedUpstreamForHostnameOrigins(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -736,7 +736,7 @@ func TestPublishConfigVersionUsesNamedUpstreamForIPOrigins(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - result, err := PublishConfigVersion("root") + result, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion failed: %v", err) } @@ -810,7 +810,7 @@ func TestPreviewAndDiffConfigVersion(t *testing.T) { if err != nil { t.Fatalf("CreateProxyRoute removed failed: %v", err) } - if _, err = PublishConfigVersion("root"); err != nil { + if _, err = PublishConfigVersion("root", false); err != nil { t.Fatalf("initial PublishConfigVersion failed: %v", err) } @@ -936,7 +936,7 @@ func TestPublishConfigVersionDetectsPoWChanges(t *testing.T) { t.Fatalf("CreateProxyRoute failed: %v", err) } - firstRelease, err := PublishConfigVersion("root") + firstRelease, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("initial PublishConfigVersion failed: %v", err) } @@ -967,7 +967,7 @@ func TestPublishConfigVersionDetectsPoWChanges(t *testing.T) { t.Fatalf("expected PoW change to mark site as modified, got %#v", diff.ModifiedSites) } - secondRelease, err := PublishConfigVersion("root") + secondRelease, err := PublishConfigVersion("root", false) if err != nil { t.Fatalf("PublishConfigVersion after PoW change failed: %v", err) } diff --git a/openflare_server/web/features/config-versions/api/config-versions.ts b/openflare_server/web/features/config-versions/api/config-versions.ts index 374bb301..e3e954ff 100644 --- a/openflare_server/web/features/config-versions/api/config-versions.ts +++ b/openflare_server/web/features/config-versions/api/config-versions.ts @@ -27,8 +27,9 @@ export function getConfigVersionDiff() { return apiRequest('/config-versions/diff'); } -export function publishConfigVersion() { - return apiRequest('/config-versions/publish', { +export function publishConfigVersion(force?: boolean) { + const query = force ? '?force=true' : ''; + return apiRequest(`/config-versions/publish${query}`, { method: 'POST', }); } diff --git a/openflare_server/web/features/config-versions/components/config-versions-page.tsx b/openflare_server/web/features/config-versions/components/config-versions-page.tsx index 7fb6a89e..d86d92f3 100644 --- a/openflare_server/web/features/config-versions/components/config-versions-page.tsx +++ b/openflare_server/web/features/config-versions/components/config-versions-page.tsx @@ -435,7 +435,7 @@ export function ConfigVersionsPage() { }); const publishMutation = useMutation({ - mutationFn: publishConfigVersion, + mutationFn: (force?: boolean) => publishConfigVersion(force), onSuccess: async (version) => { setFeedback({ tone: 'success', @@ -517,13 +517,26 @@ export function ConfigVersionsPage() { title="配置版本" description="查看历史快照、预览待发布配置差异,并在需要时重新激活旧版本。" action={ - - {isPreviewLoading ? '加载预览中...' : '预览并发布'} - +
+ { + if (window.confirm('确认强制重新发布吗?这会忽略配置变化检查并立即生成一个新版本。')) { + publishMutation.mutate(true); + } + }} + disabled={publishMutation.isPending} + > + 重新发布 + + + {isPreviewLoading ? '加载预览中...' : '预览并发布'} + +
} /> @@ -544,7 +557,7 @@ export function ConfigVersionsPage() { : null } isPublishing={publishMutation.isPending} - onConfirm={() => publishMutation.mutate()} + onConfirm={() => publishMutation.mutate(false)} onCancel={() => setPublishPreview(null)} /> ) : null} diff --git a/openflare_server/web/features/proxy-routes/components/proxy-routes-page.tsx b/openflare_server/web/features/proxy-routes/components/proxy-routes-page.tsx index 5b9539a3..51cdf43c 100644 --- a/openflare_server/web/features/proxy-routes/components/proxy-routes-page.tsx +++ b/openflare_server/web/features/proxy-routes/components/proxy-routes-page.tsx @@ -167,7 +167,7 @@ export function ProxyRoutesPage() { } setFeedback(null); - publishMutation.mutate(); + publishMutation.mutate(false); }; if (routesQuery.isLoading) {