From 002b082faa64095287153bf68e865331efdd2f41 Mon Sep 17 00:00:00 2001 From: tian <11429339@qq.com> Date: Thu, 7 May 2026 10:12:43 +0800 Subject: [PATCH] docs: P0 implementation plan - alarm center, face gallery, video monitor, dashboard --- docs/P0实施计划.md | 289 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 docs/P0实施计划.md diff --git a/docs/P0实施计划.md b/docs/P0实施计划.md new file mode 100644 index 0000000..4ee21d5 --- /dev/null +++ b/docs/P0实施计划.md @@ -0,0 +1,289 @@ +# 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 告警记录格式 + +```json +{ + "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 A1:media-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 A2:agent 增加告警查询端点(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)` +- 新告警写入后端 SQLite(`alarm_records` 表) +- 前端 SSE 推送新告警 + +**数据库**:`internal/storage/migrate.go` 新增表 + +```sql +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 A5:Dashboard 告警信息流(HTML + JS) + +在 Dashboard 顶部增加一个告警信息流卡片,SSE 实时推送最近 5 条告警。 + +--- + +## 二、人脸库管理 + +### 2.1 当前问题 + +只能整文件上传/替换 `.db`,无法增删改单个人物。 + +### 2.2 架构设计 + +``` +后端人脸库页面 ──CRUD──▶ agent /v1/face-gallery/persons/* ──▶ media-server face_gallery.db +``` + +### 2.3 任务分解 + +#### Task B1:agent 增加人脸库 CRUD API(Go) + +**文件**:`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 C1:agent 增加预览端点(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 D1:Dashboard 实时数据 API(Go) + +**文件**:`internal/web/ui.go`(修改 `pageDashboard`) + +```go +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 D2:Dashboard 模板改造(HTML) + +**文件**:`internal/web/ui/templates/dashboard.html` + +- 告警信息流(SSE 实时更新) +- 设备状态卡片(在线数、CPU、内存) +- 快照预览(定时刷新 img src) +- 最近任务(已有,保留) + +--- + +## 五、实施顺序 + +``` +第一阶段(打通告警链路): + Task A1(media-server)→ Task A2(agent)→ Task A3(后端收集)→ Task A4(告警页面) + +第二阶段(人脸库 + 视频): + Task B1 + C1(agent)→ Task B2 + C2(后端页面) + +第三阶段(Dashboard整合): + Task A5 + D1 + D2(Dashboard 改造) +``` + +--- + +## 六、涉及文件清单 + +| 项目 | 文件 | 操作 | +|------|------|------| +| 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` | 修改:注入新服务 |