From 1cb3077b807803f81bd3b937873a5d934df81152 Mon Sep 17 00:00:00 2001
From: tian <11429339@qq.com>
Date: Sun, 19 Apr 2026 13:42:01 +0800
Subject: [PATCH] Show config apply result summary
---
internal/web/ui/templates/config_preview.html | 24 +++++++
internal/web/ui_test.go | 65 +++++++++++++++++++
2 files changed, 89 insertions(+)
diff --git a/internal/web/ui/templates/config_preview.html b/internal/web/ui/templates/config_preview.html
index 3bba19d..993aed1 100644
--- a/internal/web/ui/templates/config_preview.html
+++ b/internal/web/ui/templates/config_preview.html
@@ -102,6 +102,30 @@
{{end}}
+{{if and (eq .ResultTitle "应用候选配置结果") .ConfigStatus}}
+
+
应用结果摘要
+
+
+
当前运行
+
{{if .ConfigStatus.Metadata.ConfigID}}{{.ConfigStatus.Metadata.ConfigID}} / {{if .ConfigStatus.Metadata.ConfigVersion}}{{.ConfigStatus.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}未标记{{end}}
+
+
+
last_good
+
{{if and .ConfigStatus.LastGood .ConfigStatus.LastGood.Exists .ConfigStatus.LastGood.Metadata.ConfigID}}{{.ConfigStatus.LastGood.Metadata.ConfigID}} / {{if .ConfigStatus.LastGood.Metadata.ConfigVersion}}{{.ConfigStatus.LastGood.Metadata.ConfigVersion}}{{else}}未标记{{end}}{{else}}-{{end}}
+
+
+
candidate
+
{{if and .ConfigStatus.Candidate .ConfigStatus.Candidate.Exists}}仍存在{{else}}已清空{{end}}
+
+
+
media-server
+
{{if .ConfigStatus.MediaServer.Running}}运行中{{else}}未运行{{end}}
+
+
+
+{{end}}
+
{{if .RawText}}
{{if .ResultTitle}}{{.ResultTitle}}{{else}}执行结果{{end}}
diff --git a/internal/web/ui_test.go b/internal/web/ui_test.go
index 82373bc..2dfa268 100644
--- a/internal/web/ui_test.go
+++ b/internal/web/ui_test.go
@@ -505,6 +505,71 @@ func TestUI_ConfigPreviewCollapsesJSONAfterActionResult(t *testing.T) {
}
}
+func TestUI_ConfigPreviewShowsApplySummaryAfterApplyResult(t *testing.T) {
+ ui := newTestUI(t)
+ req := httptest.NewRequest(http.MethodGet, "/ui/devices/edge-01/config-preview", nil)
+ rr := httptest.NewRecorder()
+
+ ui.render(rr, req, "config_preview", PageData{
+ Title: "配置预览",
+ Device: &models.Device{DeviceID: "edge-01", DeviceName: "入口识别节点", IP: "127.0.0.1", AgentPort: 9100},
+ SelectedTemplate: "workshop_face_shoe_alarm",
+ SelectedProfile: "local_3588_test",
+ SelectedOverlays: []string{"face_debug"},
+ SelectedConfigID: "preview_edge-01",
+ ConfigPreview: &service.ConfigPreviewResult{
+ JSON: `{"templates":{"tpl":{"nodes":[],"edges":[]}},"instances":[],"metadata":{"config_id":"preview_edge-01","config_version":"v2"}}`,
+ Metadata: map[string]any{
+ "config_id": "preview_edge-01",
+ "config_version": "v2",
+ },
+ Size: 64,
+ },
+ ConfigStatus: &ConfigStatusView{
+ OK: true,
+ Metadata: ConfigStatusMetadata{
+ ConfigID: "preview_edge-01",
+ ConfigVersion: "v2",
+ },
+ Candidate: &ConfigStatusLastGoodFile{
+ Exists: false,
+ Path: "/opt/rk3588-media-server/etc/media-server.json.candidate.json",
+ },
+ LastGood: &ConfigStatusLastGoodFile{
+ Exists: true,
+ Path: "/opt/rk3588-media-server/etc/media-server.json.last_good.json",
+ Metadata: ConfigStatusMetadata{
+ ConfigID: "local_3588_face_debug",
+ ConfigVersion: "20260419.120246",
+ },
+ },
+ MediaServer: ConfigStatusMediaServer{
+ Running: true,
+ PID: 1810489,
+ },
+ },
+ ResultTitle: "应用候选配置结果",
+ RawText: `{"ok":true}`,
+ })
+
+ body := rr.Body.String()
+ for _, want := range []string{
+ "应用结果摘要",
+ "当前运行",
+ "preview_edge-01 / v2",
+ "last_good",
+ "local_3588_face_debug / 20260419.120246",
+ "candidate",
+ "已清空",
+ "media-server",
+ "运行中",
+ } {
+ if !strings.Contains(body, want) {
+ t.Fatalf("expected apply summary HTML to contain %q, got:\n%s", want, body)
+ }
+ }
+}
+
func TestUI_ModelDeploymentPageRendersDeviceActions(t *testing.T) {
ui := newTestUI(t)
req := httptest.NewRequest(http.MethodGet, "/ui/models", nil)