feat: face gallery reload as task; device page model/resource status; task completion time fix

This commit is contained in:
tian 2026-07-20 16:56:36 +08:00
parent 29db6be66d
commit 4443440f0f
3 changed files with 33 additions and 10 deletions

View File

@ -9,6 +9,7 @@ import (
"path/filepath"
"strings"
"sync"
"time"
"safesight-control/internal/config"
"safesight-control/internal/models"
@ -209,6 +210,7 @@ func (s *TaskService) runTask(task *models.Task) {
} else {
task.Status = models.TaskFailed
}
task.CompletedAt = time.Now().Format(time.RFC3339)
task.Mu.Unlock()
s.persistTask(task)
}
@ -427,6 +429,19 @@ func (s *TaskService) executeOnDevice(task *models.Task, did string) {
s.updateDeviceStatus(task.ID, did, models.TaskSuccess, 1.0, "")
s.appendAuditLog(task, did, models.TaskSuccess, "")
case "face_gallery_reload":
_, code, err := s.agent.Do("POST", dev.IP, dev.AgentPort, "/v1/face-gallery/reload", nil)
if err != nil {
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, err.Error())
return
}
if code >= 400 {
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, fmt.Sprintf("agent error: %d", code))
return
}
s.updateDeviceStatus(task.ID, did, models.TaskSuccess, 1.0, "")
s.appendAuditLog(task, did, models.TaskSuccess, "")
default:
s.updateDeviceStatus(task.ID, did, models.TaskFailed, 0, "unsupported task type")
}

View File

@ -329,6 +329,8 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "设备操作"
case "resource_sync_one", "resource_sync_all":
return "资源同步"
case "face_gallery_reload":
return "人脸库操作"
default:
return "其他任务"
}
@ -345,6 +347,8 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "同步单个资源"
case "resource_sync_all":
return "同步全部资源"
case "face_gallery_reload":
return "重载人脸库"
case "reload":
return "重载识别服务"
case "rollback":
@ -367,6 +371,8 @@ func NewUI(discovery *service.DiscoveryService, registry *service.RegistryServic
return "pill warn"
case "resource_sync_one", "resource_sync_all":
return "pill warn"
case "face_gallery_reload":
return "pill ok"
case "media_start", "media_restart", "media_stop":
return "pill ok"
case "reload", "rollback":
@ -5205,19 +5211,17 @@ func (u *UI) actionDeviceFaceGalleryUpload(w http.ResponseWriter, r *http.Reques
func (u *UI) actionDeviceFaceGalleryReload(w http.ResponseWriter, r *http.Request) {
id := chi.URLParam(r, "id")
dev, ok := u.findDevice(id)
_, ok := u.findDevice(id)
if !ok {
http.NotFound(w, r)
return
}
resp, code, err := u.agent.Do("POST", dev.IP, dev.AgentPort, "/v1/face-gallery/reload", nil)
data := u.loadConfigUIData(dev)
data.Message = fmt.Sprintf("POST /v1/face-gallery/reload -> %d", code)
data.RawText = prettyJSON(resp)
task, err := u.tasks.CreateTask("face_gallery_reload", []string{id}, nil)
if err != nil {
data.Error = err.Error()
http.Redirect(w, r, "/devices/"+url.PathEscape(id)+"?error="+url.QueryEscape(err.Error()), http.StatusFound)
return
}
u.render(w, r, "config_ui", data)
http.Redirect(w, r, "/tasks/"+url.PathEscape(task.ID), http.StatusFound)
}
func (u *UI) pageMonitor(w http.ResponseWriter, r *http.Request) {

View File

@ -197,11 +197,15 @@
<div><span>人脸库</span><strong>通过资源管理与基础配置维护</strong></div>
</div>
{{end}}
<div class="actions">
{{$fgSynced := true}}
{{range $r := .StandardResources}}{{if eq $r.ResourceType "face_gallery"}}
{{$fgSynced = false}}
{{range $d := $.DeviceResourceStatuses}}{{if and (eq $d.Name $r.Name) (eq $d.SHA256 $r.SHA256)}}{{$fgSynced = true}}{{end}}{{end}}
{{end}}{{end}}
<div class="actions service-actions-row">
<form method="post" action="/devices/{{.Device.DeviceID}}/face-gallery/reload">
<button type="submit" class="secondary">重载人脸库</button>
<button type="submit" class="{{if $fgSynced}}secondary{{else}}primary{{end}}">{{if $fgSynced}}重载人脸库{{else}}⚠ 重载人脸库(待同步){{end}}</button>
</form>
<a class="btn ghost" href="/assets">查看基础配置</a>
</div>
</section>