feat: 告警列表显示设备名+IP和视频源,CSV时间移到首位
This commit is contained in:
parent
ca7be71f90
commit
55f235b23b
@ -119,6 +119,9 @@ type PageData struct {
|
||||
SystemCompanyName string
|
||||
AlarmFilterDevices []string
|
||||
AlarmFilterRuleTypes []string
|
||||
AlarmDeviceNames map[string]string
|
||||
AlarmDeviceIPs map[string]string
|
||||
AlarmChannelSources map[string]string
|
||||
SelectedAlarmDevice string
|
||||
SelectedAlarmRuleType string
|
||||
DeviceMetrics []DeviceMetric
|
||||
@ -2573,6 +2576,27 @@ func (u *UI) pageAlarms(w http.ResponseWriter, r *http.Request) {
|
||||
data.AlarmFilterDevices = u.alarmCollector.GetDistinctDeviceIDs()
|
||||
data.AlarmFilterRuleTypes = u.alarmCollector.GetDistinctRuleTypes()
|
||||
}
|
||||
// Build device name/IP maps and channel→source map for template
|
||||
data.AlarmDeviceNames = map[string]string{}
|
||||
data.AlarmDeviceIPs = map[string]string{}
|
||||
data.AlarmChannelSources = map[string]string{}
|
||||
for _, dev := range data.Devices {
|
||||
if dev != nil {
|
||||
data.AlarmDeviceNames[dev.DeviceID] = dev.DisplayName()
|
||||
data.AlarmDeviceIPs[dev.DeviceID] = dev.IP
|
||||
}
|
||||
}
|
||||
if u.preview != nil {
|
||||
if assignments, err := u.preview.ListDeviceAssignments(); err == nil {
|
||||
for _, a := range assignments {
|
||||
for _, ref := range a.RecognitionUnits {
|
||||
if unit, err := u.preview.GetRecognitionUnit(ref); err == nil && unit != nil && unit.VideoSourceRef != "" {
|
||||
data.AlarmChannelSources[unit.Name] = unit.VideoSourceRef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Calculate total pages and build page list: 1, ..., cur-2, cur-1, cur, cur+1, cur+2, ..., N
|
||||
if data.TotalAlarmCount > 0 {
|
||||
data.TotalAlarmPages = (data.TotalAlarmCount + perPage - 1) / perPage
|
||||
@ -2722,7 +2746,7 @@ func (u *UI) apiAlarmExport(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Disposition", fmt.Sprintf(`attachment; filename="alarms_%s_%s.csv"`, from, to))
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
w.Write([]byte("\xef\xbb\xbf"))
|
||||
w.Write([]byte("设备名,IP,视频源,规则,目标,状态,时间\n"))
|
||||
w.Write([]byte("时间,设备名,IP,视频源,规则,目标,状态\n"))
|
||||
for _, a := range records {
|
||||
devName := a.DeviceID
|
||||
devIP := ""
|
||||
@ -2745,9 +2769,9 @@ func (u *UI) apiAlarmExport(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(w, "%s,%s,%s,%s,%s,%s,%s\n",
|
||||
escapeCSV(devName), escapeCSV(devIP), escapeCSV(sourceName),
|
||||
escapeCSV(a.Timestamp), escapeCSV(devName), escapeCSV(devIP), escapeCSV(sourceName),
|
||||
escapeCSV(alarmRuleLabel(a.RuleName)), escapeCSV(a.ObjectLabel),
|
||||
escapeCSV(alarmStatusLabel(a.Status)), escapeCSV(a.Timestamp))
|
||||
escapeCSV(alarmStatusLabel(a.Status)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<select name="device" onchange="this.form.submit()" style="font-size:11px;padding:2px 4px;width:130px;flex-shrink:0">
|
||||
<option value="">全部设备</option>
|
||||
{{range .AlarmFilterDevices}}
|
||||
<option value="{{.}}" {{if eq . $.SelectedAlarmDevice}}selected{{end}}>{{shortID .}}</option>
|
||||
<option value="{{.}}" {{if eq . $.SelectedAlarmDevice}}selected{{end}}>{{index $.AlarmDeviceNames .}}</option>
|
||||
{{end}}
|
||||
</select>
|
||||
{{end}}
|
||||
@ -59,9 +59,10 @@
|
||||
<tr id="alarm-{{.ID}}">
|
||||
<td class="mono small">{{.Timestamp}}</td>
|
||||
<td>
|
||||
<a href="/devices/{{.DeviceID}}">{{shortID .DeviceID}}</a>
|
||||
<a href="/devices/{{.DeviceID}}">{{index $.AlarmDeviceNames .DeviceID}}</a>
|
||||
<div class="muted small mono">{{index $.AlarmDeviceIPs .DeviceID}}</div>
|
||||
</td>
|
||||
<td>{{.Channel}}</td>
|
||||
<td>{{index $.AlarmChannelSources .Channel}}</td>
|
||||
<td>
|
||||
<span class="pill warn">{{ruleLabel .RuleName}}</span>
|
||||
</td>
|
||||
|
||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user