3588AdminBackend/docs/P0实施计划.md

8.8 KiB
Raw Permalink Blame History

P0 功能实施计划

计划日期2026-05-06 基于:产品化评估与规划.md 中的 P0 优先级


总览

功能 依赖链 工作量估计
告警中心 media-server → agent → 后端 最大
人脸库管理 agent → 后端
视频监控 agent → 后端
Dashboard 改造 后端(依赖以上三项)

一、告警中心(最大的缺口)

1.1 当前问题

media-server 的 alarm 节点触发告警后直接发送给第三方HTTP 回调、MinIO 等),不在本地保存告警记录。agent 无法查询历史告警,后端自然也无法展示。

1.2 架构设计

media-server alarm 节点触发
    ├── 截图/视频片段上传 MinIO已有
    ├── HTTP 回调通知第三方(已有)
    └── 写入本地告警日志(新增)──→ agent 查询 ──→ 后端收集展示

1.3 告警记录格式

{
  "id": "alarm_20260506_143021_a1b2c3",
  "timestamp": "2026-05-06T14:30:21+08:00",
  "device_id": "d12a4719c91641df",
  "channel": "cam1",
  "rule_name": "intrusion_zone_a",
  "rule_type": "intrusion",
  "object_label": "person",
  "confidence": 0.87,
  "snapshot_url": "http://minio:9000/alarms/xxx.jpg",
  "clip_url": "http://minio:9000/clips/xxx.mp4",
  "duration_ms": 3500
}

1.4 任务分解

Task A1media-server 增加本地告警存储C++

文件plugins/alarm/alarm_node.cpp

在 alarm 节点触发告警动作时,追加写入本地 SQLite 数据库:

表结构:
CREATE TABLE alarm_records (
  id TEXT PRIMARY KEY,
  timestamp TEXT NOT NULL,
  channel TEXT NOT NULL,
  rule_name TEXT NOT NULL,
  rule_type TEXT NOT NULL,
  object_label TEXT,
  confidence REAL,
  snapshot_url TEXT,
  clip_url TEXT,
  duration_ms INTEGER,
  created_at TEXT NOT NULL
);

位置:${modelsDir}/../resources/alarms/alarm_records.db

Task A2agent 增加告警查询端点Go

文件agent/internal/httpapi/alarms.go(新建)

GET /v1/alarms/recent?limit=50&since=2026-05-06T00:00:00

返回最近 N 条告警记录。可选时间范围过滤。

Task A3后端定时收集设备告警Go

文件internal/service/alarm_collector.go(新建)

  • RegistryService 增加 goroutine每 10 秒遍历在线设备
  • 对每个设备调用 agent.Do("GET", dev.IP, dev.AgentPort, "/v1/alarms/recent?limit=100", nil)
  • 新告警写入后端 SQLitealarm_records 表)
  • 前端 SSE 推送新告警

数据库internal/storage/migrate.go 新增表

CREATE TABLE IF NOT EXISTS alarm_records (
  id TEXT PRIMARY KEY,
  device_id TEXT NOT NULL,
  channel TEXT NOT NULL,
  timestamp TEXT NOT NULL,
  rule_name TEXT NOT NULL,
  rule_type TEXT NOT NULL,
  object_label TEXT,
  confidence REAL,
  snapshot_url TEXT,
  clip_url TEXT,
  duration_ms INTEGER,
  collected_at TEXT NOT NULL
);

Task A4告警中心页面Go + HTML

路由GET /ui/alarms

布局

  • 上半部分:告警筛选(设备/通道/规则类型/时间范围)
  • 下半部分:告警列表(时间、设备、通道、规则、对象标签、截图缩略图、视频链接)
  • 点击进入告警详情(大图、视频片段播放)

Task A5Dashboard 告警信息流HTML + JS

在 Dashboard 顶部增加一个告警信息流卡片SSE 实时推送最近 5 条告警。


二、人脸库管理

2.1 当前问题

只能整文件上传/替换 .db,无法增删改单个人物。

2.2 架构设计

后端人脸库页面 ──CRUD──▶ agent /v1/face-gallery/persons/* ──▶ media-server face_gallery.db

2.3 任务分解

Task B1agent 增加人脸库 CRUD APIGo

文件agent/internal/httpapi/face_gallery.go(修改)

新增端点:

  • GET /v1/face-gallery/persons — 返回人物列表 {id, name, photo_count, created_at}
  • POST /v1/face-gallery/persons — 新增人物 {name, photo_bytes}agent 调用 media-server 接口提取 embedding 并写入 DB
  • DELETE /v1/face-gallery/persons/{id} — 删除人物及其 embeddings
  • PUT /v1/face-gallery/persons/{id}/name — 修改人物姓名
  • POST /v1/face-gallery/persons/{id}/photo — 追加人脸照片,提取 embedding

Task B2后端人脸库管理页面Go + HTML

路由GET /ui/face-gallery

布局

  • 人员列表(姓名、照片缩略图、注册时间、操作按钮)
  • 搜索框(按姓名搜索)
  • 新增按钮 → 弹出表单(姓名 + 上传照片)
  • 编辑/删除确认

三、视频监控

3.1 当前问题

后台看不到摄像头画面。只能通过 http://设备IP:9000/hls_player.html 在设备上查看。

3.2 架构设计

后端视频监控页 ──iframe──▶ agent 返回 HLS 播放页面 URL
                └──img──▶ agent /v1/preview/snapshot?channel=X 返回 JPEG

3.3 任务分解

Task C1agent 增加预览端点Go

文件agent/internal/httpapi/preview.go(新建)

  • GET /v1/preview/channels — 返回各通道信息 {name, hls_url, rtsp_url, resolution, fps}
  • GET /v1/preview/snapshot/:channel — 从 media-server 请求当前帧,返回 JPEG

HLS URL 格式:代理转发到 media-server 的 /hls/{channel}/index.m3u8

Task C2后端视频监控页面Go + HTML

路由GET /ui/monitor

布局

  • 左侧:设备通道列表(可多选)
  • 右侧多路画面网格4/9/16 宫格)
  • 每个画面HLS 播放器 iframe + 通道名称标签
  • 单击画面可全屏

四、Dashboard 改造

4.1 当前问题

只有静态统计(设备数、任务数),缺乏实时信息。

4.2 目标布局

┌─────────────────────────────────────┐
│  实时告警5条滚动                │ ← 告警中心对接
├──────────┬──────────┬───────────────┤
│ 设备状态  │ NPU/CPU  │ 今日告警统计  │ ← agent metrics
│ 在线 3/3 │ ████░░░░ │ 告警: 12     │
├──────────┴──────────┴───────────────┤
│  关键通道预览1-4路 snapshot      │ ← 视频监控对接
├─────────────────────────────────────┤
│  最近任务                           │ ← 已有
└─────────────────────────────────────┘

4.3 任务分解

Task D1Dashboard 实时数据 APIGo

文件internal/web/ui.go(修改 pageDashboard

func (u *UI) pageDashboard(w http.ResponseWriter, r *http.Request) {
    u.ensureDevicesLoaded()
    data := ...现有逻辑...
    
    // 新增:最近告警
    data.RecentAlarms = alarmService.GetRecent(5)
    
    // 新增:设备 metrics聚合
    data.DeviceMetrics = collectDeviceMetrics(u.agent, u.registry)
    
    u.render(w, r, "dashboard", data)
}

Task D2Dashboard 模板改造HTML

文件internal/web/ui/templates/dashboard.html

  • 告警信息流SSE 实时更新)
  • 设备状态卡片在线数、CPU、内存
  • 快照预览(定时刷新 img src
  • 最近任务(已有,保留)

五、实施顺序

第一阶段(打通告警链路):
  Task A1media-server→ Task A2agent→ Task A3后端收集→ Task A4告警页面

第二阶段(人脸库 + 视频):
  Task B1 + C1agent→ Task B2 + C2后端页面

第三阶段Dashboard整合
  Task A5 + D1 + D2Dashboard 改造)

六、涉及文件清单

项目 文件 操作
media-server plugins/alarm/alarm_node.cpp 修改:追加本地告警存储
agent internal/httpapi/alarms.go 新建:告警查询端点
agent internal/httpapi/face_gallery.go 修改:人脸库 CRUD
agent internal/httpapi/preview.go 新建:视频预览端点
agent internal/httpapi/server.go 修改:注册新路由
后端 internal/service/alarm_collector.go 新建:告警收集服务
后端 internal/storage/migrate.go 修改alarm_records 表
后端 internal/web/ui/templates/alarms.html 新建:告警中心页面
后端 internal/web/ui/templates/face_gallery.html 新建:人脸库管理页面
后端 internal/web/ui/templates/monitor.html 新建:视频监控页面
后端 internal/web/ui/templates/dashboard.html 修改:实时化改造
后端 internal/web/ui.go 修改:新页面 handler + 路由
后端 cmd/managerd/main.go 修改:注入新服务