把设备性能移到管控台

This commit is contained in:
tian 2026-05-12 11:26:36 +08:00
parent 57b9ec3523
commit 59de94bfae
3 changed files with 33 additions and 51 deletions

View File

@ -1014,19 +1014,18 @@ func (u *UI) pageConsole(w http.ResponseWriter, r *http.Request) {
features = append(features, f)
}
npu := 0.0
npu, diskUsage, temp, cpuUsage, memUsage := 0.0, 0.0, 0.0, 0.0, 0.0
if m, ok := metrics[dev.DeviceID]; ok {
cpuUsage = m.CPU
memUsage = m.Mem
npu = m.NPU
}
diskUsage := 0.0
temp := 0.0
if m, ok := metrics[dev.DeviceID]; ok {
diskUsage = m.Disk
temp = m.Temperature
}
consoleDevices = append(consoleDevices, ConsoleDeviceData{
Device: dev,
CPUUsage: cpuUsage,
MemUsage: memUsage,
NPUUsage: npu,
DiskUsage: diskUsage,
Temperature: temp,
@ -4585,6 +4584,8 @@ type DeviceMetric struct {
type ConsoleDeviceData struct {
Device *models.Device
CPUUsage float64
MemUsage float64
NPUUsage float64
DiskUsage float64
Temperature float64

View File

@ -30,6 +30,7 @@
<span class="status-dot {{if $cd.Device.Online}}ok{{else}}bad{{end}}"></span>
<span class="console-device-name">{{$cd.Device.DisplayName}}</span>
<span class="console-device-meta">{{$cd.Device.IP}} | {{len $cd.Channels}}/{{$cd.MaxUnits}} 路</span>
<span class="console-cam-add" style="margin-top:0;padding-top:0;font-size:11px"> 从未分配添加</span>
</div>
<div class="console-body">
<!-- LEFT: Preview tiles in one row -->
@ -67,15 +68,19 @@
</table>
</div>
<div class="console-section">
<div class="console-section-title">已分配视频源({{len $cd.Cameras}}路)</div>
<div class="console-cameras">
{{range $cam := $cd.Cameras}}
<span class="console-cam-chip">{{$cam}}</span>
{{else}}
<span class="muted small">暂无</span>
{{end}}
<div class="console-section-title">设备负载</div>
<div class="console-metrics">
<div class="metric-row" style="font-size:9px"><span>CPU</span><span>{{printf "%.0f%%" $cd.CPUUsage}}</span></div>
<div class="console-metric-bar"><div style="height:100%;border-radius:2px;width:{{printf "%.0f%%" $cd.CPUUsage}};background:{{if gt $cd.CPUUsage 80.0}}var(--bar-red){{else if gt $cd.CPUUsage 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div class="metric-row" style="font-size:9px"><span>内存</span><span>{{printf "%.0f%%" $cd.MemUsage}}</span></div>
<div class="console-metric-bar"><div style="height:100%;border-radius:2px;width:{{printf "%.0f%%" $cd.MemUsage}};background:{{if gt $cd.MemUsage 80.0}}var(--bar-red){{else if gt $cd.MemUsage 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div class="metric-row" style="font-size:9px"><span>NPU</span><span>{{printf "%.0f%%" $cd.NPUUsage}}</span></div>
<div class="console-metric-bar"><div style="height:100%;border-radius:2px;width:{{printf "%.0f%%" $cd.NPUUsage}};background:{{if gt $cd.NPUUsage 80.0}}var(--bar-red){{else if gt $cd.NPUUsage 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div class="metric-row" style="font-size:9px"><span>磁盘</span><span>{{printf "%.0f%%" $cd.DiskUsage}}</span></div>
<div class="console-metric-bar"><div style="height:100%;border-radius:2px;width:{{printf "%.0f%%" $cd.DiskUsage}};background:{{if gt $cd.DiskUsage 80.0}}var(--bar-red){{else if gt $cd.DiskUsage 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div class="metric-row" style="font-size:9px"><span>温度</span><span>{{printf "%.0f°C" $cd.Temperature}}</span></div>
<div class="console-metric-bar"><div style="height:100%;border-radius:2px;width:{{printf "%.0f%%" $cd.Temperature}};background:{{if gt $cd.Temperature 60.0}}var(--bar-red){{else if gt $cd.Temperature 40.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
</div>
<div class="console-cam-add"> 从未分配添加</div>
</div>
</div>
</div>
@ -210,6 +215,8 @@
})();
</script>
<style>
.console-section-title { font-size: 10px; color: var(--muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: .8px; font-weight: 600; }
.console-section { background: var(--surface-soft); border-radius: 6px; padding: 10px 12px; width: 50%; overflow: hidden; }
.console-device-row { background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--border); border-radius: 8px; padding: 14px; margin-bottom: 12px; }
.console-header { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.console-device-name { font-weight: 600; font-size: 14px; }
@ -225,20 +232,24 @@
/* Controls: side by side, 50/50 */
.console-controls { width: 460px; flex-shrink: 0; display: flex; gap: 10px; }
.console-section { background: var(--surface-soft); border-radius: 6px; padding: 10px 12px; width: 50%; display: flex; flex-direction: column; }
.console-section-title { font-size: 10px; color: var(--muted); margin-bottom: 8px; text-transform: uppercase; letter-spacing: .8px; font-weight: 600; }
.console-section { background: var(--surface-soft); border-radius: 6px; padding: 10px 12px; width: 50%; overflow: hidden; }
.console-feature-table { width: 100%; border-collapse: collapse; border: none; }
.console-feature-table { width: 100%; border-collapse: collapse; border: none; background: transparent; }
.console-feature-table tr { border: none; }
.console-feature-table td { border: none; padding: 2px 0; vertical-align: middle; }
.console-feature-table td { border: none; padding: 2px 0; vertical-align: middle; background: transparent; }
.console-feature-check { width: 18px; }
.console-feature-check input { margin: 0; display: block; }
.console-feature-label { font-size: 12px; white-space: nowrap; }
.console-cameras { display: flex; flex-wrap: wrap; gap: 5px; align-content: start; flex: 1; }
.console-cam-chip { display: inline-flex; align-items: center; gap: 4px; background: var(--surface); border: 1px solid var(--border); padding: 3px 10px; border-radius: 5px; font-size: 11px; color: var(--text); }
.console-cam-add { margin-top: auto; padding-top: 6px; font-size: 11px; color: var(--primary); cursor: pointer; display: inline-flex; align-items: center; gap: 3px; }
/* Metrics in console */
.console-metrics { display: flex; flex-direction: column; gap: 2px; }
.metric-row { display: flex; justify-content: space-between; font-size: 11px; padding: 1px 0; }
.console-controls { --bar-green: #66c98f; --bar-amber: #d8a657; --bar-red: #e46f72; }
.console-metric-bar { height: 3px; background: #c0c0c0; margin-bottom: 1px; border-radius: 2px; overflow: hidden; }
/* Console tabs flush */
.card-tabs.console-tabs-wrap .nav-tabs { margin-bottom: 0; }
.card-tabs.console-tabs-wrap .tab-content { padding: 0; }

View File

@ -23,37 +23,7 @@
<div class="stat"><div class="k">执行中任务</div><div class="v">{{.RunningTaskCount}}</div><div class="hint">正在下发或控制节点</div></div>
</div>
<div class="card" id="metrics-card">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
<h3 class="title-with-icon" style="margin:0">{{icon "heartbeat"}}<span>设备负载</span></h3>
<span class="muted small" id="metrics-time"></span>
</div>
<div id="metrics-body" style="display:flex;flex-wrap:wrap;gap:12px">
{{range .DeviceMetrics}}
<div style="padding:8px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--surface-soft);min-width:160px">
<div style="font-weight:500;font-size:12px;margin-bottom:8px">{{.Name}}</div>
<div style="display:flex;flex-direction:column;gap:4px;font-size:11px">
<div style="display:flex;justify-content:space-between"><span>CPU</span><span>{{printf "%.0f%%" .CPU}}</span></div>
<div class="progress"><div class="progress-bar" style="width:{{printf "%.0f%%" .CPU}};background:{{if gt .CPU 80.0}}var(--bar-red){{else if gt .CPU 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div style="display:flex;justify-content:space-between"><span>内存</span><span>{{printf "%.0f%%" .Mem}}</span></div>
<div class="progress"><div class="progress-bar" style="width:{{printf "%.0f%%" .Mem}};background:{{if gt .Mem 80.0}}var(--bar-red){{else if gt .Mem 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div style="display:flex;justify-content:space-between"><span>NPU</span><span>{{printf "%.0f%%" .NPU}}</span></div>
<div class="progress"><div class="progress-bar" style="width:{{printf "%.0f%%" .NPU}};background:{{if gt .NPU 80.0}}var(--bar-red){{else if gt .NPU 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div style="display:flex;justify-content:space-between"><span>磁盘</span><span>{{printf "%.0f%%" .Disk}}</span></div>
<div class="progress"><div class="progress-bar" style="width:{{printf "%.0f%%" .Disk}};background:{{if gt .Disk 80.0}}var(--bar-red){{else if gt .Disk 50.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
<div style="display:flex;justify-content:space-between"><span>温度</span><span>{{printf "%.0f°C" .Temperature}}</span></div>
<div class="progress"><div class="progress-bar" style="width:{{printf "%.0f%%" .Temperature}};background:{{if gt .Temperature 60.0}}var(--bar-red){{else if gt .Temperature 40.0}}var(--bar-amber){{else}}var(--bar-green){{end}}"></div></div>
</div>
</div>
{{else}}
<span class="muted">无在线设备</span>
{{end}}
</div>
</div>
<style>
#metrics-body { --bar-green: #66c98f; --bar-amber: #d8a657; --bar-red: #e46f72; }
#metrics-body .progress { background: #c0c0c0; }
</style>
<div class="card">
<h2>异常设备</h2>