From 9e6842015a97fe925804b63335a870661655f6a3 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Fri, 24 Jul 2026 19:33:53 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BB=AA=E8=A1=A8=E6=9D=BF=E6=A8=AA?= =?UTF-8?q?=E5=B9=85+=E5=90=91=E5=AF=BC=E8=A7=92=E6=A0=87=E6=8F=90?= =?UTF-8?q?=E9=86=92=E9=9B=86=E6=88=90=E6=9C=8D=E5=8A=A1=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=9C=80=E9=87=8D=E6=96=B0=E4=B8=8B=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/web/ui.go | 69 ++++++++++++++++-------- internal/web/ui/templates/dashboard.html | 6 +++ internal/web/ui/templates/wizard.html | 2 +- 3 files changed, 54 insertions(+), 23 deletions(-) diff --git a/internal/web/ui.go b/internal/web/ui.go index 56d1836..923536e 100644 --- a/internal/web/ui.go +++ b/internal/web/ui.go @@ -70,6 +70,7 @@ type PageData struct { Devices []*models.Device DeviceRows []DeviceOverviewRow + WizardStale map[string]bool AttentionDevices []*models.Device Found []*models.Device Device *models.Device @@ -109,6 +110,7 @@ type PageData struct { TodayAlarmCount int UnacknowledgedAlarmCount int DetectionChannelCount int + StaleCount int AlarmFilterDevices []string AlarmFilterRuleTypes []string SelectedAlarmDevice string @@ -971,6 +973,12 @@ func (u *UI) pageDashboard(w http.ResponseWriter, r *http.Request) { data.DetectionChannelCount = len(units) } } + // Count stale integration devices + for _, row := range data.DeviceRows { + if row.IntegrationStale { + data.StaleCount++ + } + } // Load device metrics if u.agent != nil { for _, dev := range data.Devices { @@ -1380,6 +1388,7 @@ func (u *UI) pageWizard(w http.ResponseWriter, r *http.Request) { u.ensureDevicesLoaded() data := PageData{Title: "部署向导"} data.Devices = u.registry.GetDevices() + data.WizardStale = u.integrationStaleMap() if u.preview != nil { if sources, err := u.preview.ListVideoSources(); err == nil { data.ConsoleAllVideoSources = sources @@ -5114,28 +5123,11 @@ func (u *UI) deviceOverviewPageData(r *http.Request, selectedIDs []string, errMs } selectedIDs = filterSelectedDeviceIDs(devices, selectedIDs) - // Check if integrations were updated after device's last deployment - if u.preview != nil { - if svcs, _ := u.preview.ListIntegrationServices(); len(svcs) > 0 { - maxUpdated := "" - for _, s := range svcs { - if s.UpdatedAt > maxUpdated { - maxUpdated = s.UpdatedAt - } - } - if maxUpdated != "" { - for i := range rows { - dev := rows[i].Device - if dev == nil || !dev.Online { - continue - } - status, _, _ := u.loadConfigStatus(dev) - if status == nil || status.Metadata.RenderedAt == "" { - continue - } - rows[i].IntegrationStale = maxUpdated > status.Metadata.RenderedAt - } - } + // Check integrations staleness + staleMap := u.integrationStaleMap() + for i := range rows { + if rows[i].Device != nil { + rows[i].IntegrationStale = staleMap[rows[i].Device.DeviceID] } } @@ -5279,6 +5271,39 @@ func profileAssetBusinessName(asset *service.ConfigProfileAsset) string { return strings.TrimSpace(asset.Name) } +func (u *UI) integrationStaleMap() map[string]bool { + stale := map[string]bool{} + if u.preview == nil { + return stale + } + svcs, _ := u.preview.ListIntegrationServices() + if len(svcs) == 0 { + return stale + } + maxUpdated := "" + for _, s := range svcs { + if s.UpdatedAt > maxUpdated { + maxUpdated = s.UpdatedAt + } + } + if maxUpdated == "" { + return stale + } + for _, dev := range u.registry.GetDevices() { + if dev == nil || !dev.Online { + continue + } + status, _, _ := u.loadConfigStatus(dev) + if status == nil || status.Metadata.RenderedAt == "" { + continue + } + if maxUpdated > status.Metadata.RenderedAt { + stale[dev.DeviceID] = true + } + } + return stale +} + func batchActionSummary(rows []DeviceOverviewRow, selectedIDs []string, action string) string { if len(selectedIDs) == 0 { return "" diff --git a/internal/web/ui/templates/dashboard.html b/internal/web/ui/templates/dashboard.html index 693558e..0e6e631 100644 --- a/internal/web/ui/templates/dashboard.html +++ b/internal/web/ui/templates/dashboard.html @@ -1,4 +1,10 @@ {{define "dashboard"}} +{{if gt .StaleCount 0}} +
+ ⚠ 第三方服务已更新,{{.StaleCount}} 台在线设备需重新下发配置以生效 + 前往部署向导 → +
+{{end}}
{{icon "bell"}}今日告警
diff --git a/internal/web/ui/templates/wizard.html b/internal/web/ui/templates/wizard.html index 045d06b..5f32d6f 100644 --- a/internal/web/ui/templates/wizard.html +++ b/internal/web/ui/templates/wizard.html @@ -32,7 +32,7 @@ {{if .Online}} {{$hasOnline = true}}
-
在线
+
在线{{if index $.WizardStale .DeviceID}}⚠ 需更新{{end}}
{{.DeviceName}}
{{.IP}}