Initial_commit_SecMPS_v2

This commit is contained in:
2026-05-15 23:22:48 +08:00
commit 23ea4fe05f
13830 changed files with 298675 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
# SecMPS 整合项目实施手册
> **版本**: v2.0
> **日期**: 2026-05-15
> **基于**: SecMPS_最终整合方案_v2.0.md
> **工期**: 18-20 个工作日
---
## 前置检查清单Day 0
| # | 检查项 | 验证方式 | 阻塞阶段 |
|---|--------|----------|----------|
| 1 | Owl+ZLM 部署运行 | 浏览器访问 Owl 管理端,确认可登录 | Phase 1 |
| 2 | 至少1台 GB28181 设备注册到 Owl | Owl 管理端 `/devices` 有数据 | Phase 1 |
| 3 | MC4.0 网关可访问 | `curl http://mc4_ip:3000/api/central/auth/conf/get` | Phase 2 |
| 4 | MC4.0 有设备接入 | 调对象树接口有 type=2 节点 | Phase 2 |
| 5 | Vol.Pro 代码生成器可用 | 新建测试表→运行生成器→确认生成 | Phase 0 |
| 6 | MySQL 有建表权限 | 直接执行 CREATE TABLE | Phase 0 |
| 7 | Node.js >= 20.19 | `node -v` | Phase 3 |
---
## Phase 0基础设施搭建Day 1-2
### Day 1 — Gateway 骨架 + 数据库
**任务 1.1 — 创建 Gateway 解决方案**
```
dotnet new sln -n IntegrationGateway
dotnet new webapi -n IntegrationGateway.Host -f net8.0
dotnet new classlib -n IntegrationGateway.Core -f net8.0
```
**验证**: `dotnet build` 成功。
**任务 1.2 — Core 层接口**
创建 `Abstractions/`7个接口文件`Models/`8个模型文件`Infrastructure/`AdapterRegistry/TokenManager/RateLimiter
**验证**: `dotnet build` 成功。编写单元测试:注册 mock 适配器,验证 Get() 返回非 null。
**任务 1.3 — Host 层 Controller**
创建 HealthController (`GET /api/gateway/health`)、DevicesController、PointsController、StreamsController、AlarmsController、SyncController。
**验证**: 启动 Host`GET /api/gateway/health` 返回 200。
**任务 1.4 — 数据库建表8张**
按顺序执行 DDLBase_Device → Device_Video_Ext → Video_Channel → Video_Record → Device_IoT_Ext → IoT_DevicePoint → IoT_DeviceData → IoT_Alarm。
**验证**:
```
SELECT COUNT(*) FROM Base_Device; → 0
SHOW INDEX FROM Base_Device WHERE Key_name LIKE '%Adapter%'; → 唯一索引存在
```
**任务 1.5 — 运行代码生成器**
对8张表运行 Vol.Pro 代码生成器。
**验证**: 管理端可看到8个新菜单分别能正常 CRUD。
### Day 2 — Vol.Pro 侧 GatewayClient
**任务 2.1 — GatewayClient.cs**
实现 `IGatewayClient : IDependency`,封装对 Gateway 的 HTTP 调用。`appsettings.json` 添加 `"Gateway": {"BaseUrl": "http://localhost:5100"}`
**验证**: 注入 IGatewayClient调用 HealthCheckAsync() 返回 true。
**任务 2.2 — DeviceManagerController.cs**
创建 `Controllers/Warehouse/Partial/DeviceManagerController.cs`
- `GET GetRegionTree` — 区域树+设备数量
- `GET GetDevicesByRegion?regionId=` — 设备列表含子设备
- `PUT {deviceId}` — 更新设备含地图绑定
**验证**: Postman 调 `GET /api/DeviceManager/GetRegionTree` 返回 JSON。
**任务 2.3 — SyncDevicesJobQuartz**
```csharp
public class SyncDevicesJob : IJob {
public async Task Execute(IJobExecutionContext ctx) {
var gw = ctx.GetService<IGatewayClient>();
var r = await gw.SyncDevicesAsync("mc4");
}
}
```
**验证**: Quartz 管理面板看到已注册 Job。
---
## Phase 1Owl 适配器 + 视频设备页Day 3-6
### Day 3 — OwlAdapter
**任务 3.1**: 创建 `IntegrationGateway.Adapters.Owl` 项目。
**任务 3.2**: 实现 OwlAdapter`IHasFlatDevices + IHasStreams + IAcceptsMetadataPush`)。
**验证Postman 调 Gateway**:
```
GET /api/gateway/health → {"owl": true}
GET /api/gateway/devices?adapter=owl&page=1 → 返回 Owl 设备列表
GET /api/gateway/streams/owl/{channelId}/live → 返回 WS-FLV 地址
```
**任务 3.3**: 端到端同步。调 `GET /api/gateway/devices/sync?adapter=owl`,查库 `SELECT * FROM Base_Device WHERE AdapterCode='owl'`,确认设备入库。
### Day 4 — 管理端设备页面框架
**任务 4.1**: 创建 `web.vite/src/views/warehouse/DeviceManager/` 目录。
**任务 4.2**: `index.vue` — 左右分栏布局(`el-container``el-aside` 280px + `el-main`)。
**任务 4.3**: `RegionTree.vue` — 调 `GetRegionTree`,渲染 `el-tree`,点击 emit `select(regionId)`
**任务 4.4**: `DeviceTable.vue` — 调 `GetDevicesByRegion``el-table``tree-props` 展开子设备。
**验证**: 浏览器访问 `/device-manager`,左侧区域树+右侧设备表可用。
### Day 5 — 视频操作按钮 + 播放器
**任务 5.1**: `VideoDeviceActions.vue` — 实时预览/云台控制/查看回放 按钮。
**任务 5.2**: 安装 Jessibuca创建 `DeviceLivePreview.vue` 弹窗+播放器。
**验证**: 点视频设备的「实时预览」→ 弹窗播放画面。
**任务 5.3**: 云台控制面板 — 方向键+停止,调 Gateway PTZ 接口。
**验证**: 点方向键 → 摄像机转动。
### Day 6 — 视频联调 + 边界测试
| 测试 | 预期 |
|------|------|
| 设备同步 | 表格数据刷新,不重复 |
| 实时预览 | Jessibuca 播放正常 |
| 云台控制 | 摄像机转动 |
| 多路播放(4路) | 不卡顿 |
| 离线设备 | 状态显示「离线」 |
| 框架隔离 | 重跑生成器DeviceManager/ 文件未丢失 |
---
## Phase 2MC4.0 适配器 + IoT 管理Day 7-11
### Day 7 — Mc4Adapter
创建 `IntegrationGateway.Adapters.MC4`,实现 `IHasOwnDeviceTree + IHasPoints + IHasAlarms`
**验证Postman 调 Gateway**:
```
GET /api/gateway/health → {"mc4": true}
GET /api/gateway/devices/sync?adapter=mc4 → 同步报告
GET /api/gateway/realtime/mc4/{deviceId} → 点位值数组
POST /api/gateway/realtime/mc4/control {id,index,value} → 200
GET /api/gateway/alarms/mc4?from=...&to=... → 告警列表
POST /api/gateway/alarms/mc4/{id}/confirm → 确认成功
```
### Day 8 — 区域自动匹配 + 全量同步
实现 SyncEngine.ProcessTreeNodetype=1 节点 → MatchOrCreateRegiontype=2 节点 → UpsertDevice。
**验证**: 同步后 `warehouse_regions` 有 MC4.0 区域,`Base_Device.RegionId` 正确。
### Day 9 — IoT 操作按钮 + 实时数据
**任务 9.1**: `IoTDeviceActions.vue` — 实时数据/设备控制/告警记录 按钮。
**任务 9.2**: 实时数据弹窗 — 点位名称/当前值/单位/更新时间/控制控件。
**任务 9.3**: 设备控制 — 开关 `el-switch`,模拟量 `el-input-number`
**验证**: 拖动滑块 → 设备实际值改变。
### Day 10 — 告警管理 + 地图绑定
**任务 10.1**: 编辑弹窗增加「告警记录」tab。
**任务 10.2**: `MapBindingPanel.vue` — MapModelId 选择、缩放/旋转、经纬度。
**验证**: 编辑设备 → 地图绑定 → 保存 → 值持久化。
### Day 11 — SignalR Hub + Quartz 轮询
**任务 11.1**: `IoTDataHub.cs` — SubscribeDevice/SubscribeAlarms。
**任务 11.2**: `RealtimePollJob.cs` (5s) + `AlarmPollJob.cs` (10s)。
**验证**: warehouse 端 SignalR 连接收到实时数据和告警推送。
---
## Phase 3warehouse 端 + 全链路联调Day 12-17
### Day 12-13 — 视频播放器集成
- Live.vue: 假数据→真实 API + Jessibuca
- History.vue: 对接回放 APIHLS 播放
- VideoWall.vue: 9 路 WS-FLV
**验证**: Live/History/VideoWall 全功能可用。
### Day 14-15 — IoT 面板
- 实时数据看板SignalR 订阅每5秒更新
- 控制面板:开关/滑块,调控制 API
- 告警面板:实时弹窗+声音
**验证**: warehouse IoT 功能可用。
### Day 16-17 — 全链路联调
| 链路 | 预期 |
|------|------|
| 设备同步→入库 | Base_Device 有数据 |
| 区域树→el-tree | 层级正确 |
| 实时预览→播放 | 画面正常 |
| 云台→摄像机转动 | 方向正确 |
| 实时数据→面板 | 值更新 |
| 设备控制→设备响应 | 值改变 |
| 告警触发→弹窗 | <15秒 |
| 告警确认→MC4.0 | 状态变更 |
**性能指标**: 9路视频墙≥15fps100设备轮询<3s500设备同步<30s。
---
## Phase 4验证 + 缓冲Day 18-20
### Day 18 — 代码隔离验证
1. 重跑代码生成器(对 Base_Device
2. 检查 Partial/、extension/、DeviceManager/ 目录文件未覆盖
3. 检查生成文件已更新(新字段在编辑表单中出现)
### Day 19 — 异常场景
| 场景 | 预期 |
|------|------|
| Owl 宕机 | 不影响 MC4.0 同步 |
| MC4.0 宕机 | 页面不崩溃 |
| Gateway 宕机 | 前端错误提示 |
| Token 过期 | 自动刷新 |
| 并发同步 | 互不干扰 |
### Day 20 — 文档收尾
- [ ] API 文档Swagger
- [ ] 部署手册更新
- [ ] 组件使用说明
- [ ] 已知问题修复
---
## 附录:每日检查清单
```
□ 所有新增 C# 服务实现 IDependency
□ Controller 写在 Partial/ 目录
□ 前端扩展在 extension/ 目录
□ 未修改自动生成文件
□ MC4.0 调用经 RateLimiter
□ Owl Token 使用 TokenManager 缓存
□ 实时数据未写入 IoT_DeviceData
□ dotnet build 零错误
```
## 附录:端口分配
| 服务 | 端口 |
|------|------|
| IntegrationGateway | 5100 |
| VolPro.WebApi | 9100 |
| web.vite | 9000 |
| warehouse | 9200 |
| Owl | 80 |
| MC4.0 | 3000 |
---
> **文档结束**

View File

@@ -0,0 +1,309 @@
# SecMPS 整合项目实施手册
> **版本**: v2.1
> **日期**: 2026-05-15
> **基于**: SecMPS_最终整合方案_v2.0.md
> **工期**: 18-20 个工作日
> **开发模式**: 单人 + AgentSquash Merge 主线策略
---
## 分支管理策略
```
master ──────────────────────────────────────────────→ v2.0.0
│ ┌─ squash ─┐ ┌─ squash ─┐ ┌─ squash ─┐
├── phase/0 ├── phase/1 ├── phase/2 ├── ...
└── infrastructure └── owl-video └── mc4-iot └──
```
**规则**:每个 Phase 从 `master` 切分支 → 开发完成 → `git merge --squash` 合并回 `master`(一个提交)。出错直接删分支重切,零代价。
### 项目约定
```
SecMPS/
├── api_sqlsugar/ ← Vol.Pro 后端
├── web.vite/ ← 管理端
├── warehouse/ ← 用户大屏端
├── owl_zlmediakit/ ← Owl+ZLM 部署包
├── doc/ ← 文档
└── gateway/ ← IntegrationGateway★ 独立顶层文件夹)
```
> 整个网关项目放在 `gateway/` 目录下,与 Vol.Pro 物理隔离。新建适配器时同样在此目录下添加项目。
### 初始化
```bash
git remote -v # 确认 origin → gitea.1vs5.top
```
### 每个 Phase 标准流程
```bash
# 开始
git checkout master
git checkout -b phase/{n}-{name}
# 开发(随时提交)
git add -A && git commit -m "具体改动描述"
# 完成后合并
git checkout master
git merge --squash phase/{n}-{name}
git commit -m "Phase {n}: {标题}"
git push
git tag phase-{n}-done
```
---
## 前置检查清单Day 0
| # | 检查项 | 验证方式 | 阻塞 |
|---|--------|----------|------|
| 1 | Owl+ZLM 部署运行 | 浏览器访问 Owl 管理端 | Phase 1 |
| 2 | 至少1台 GB28181 设备注册 | Owl `/devices` 有数据 | Phase 1 |
| 3 | MC4.0 网关可访问 | curl :3000 /api/central/auth/conf/get | Phase 2 |
| 4 | MC4.0 有设备接入 | 对象树有 type=2 节点 | Phase 2 |
| 5 | 代码生成器可用 | 新建测试表→生成→确认 | Phase 0 |
| 6 | MySQL 建表权限 | 执行 CREATE TABLE | Phase 0 |
| 7 | Node.js >= 20.19 | node -v | Phase 3 |
---
## Phase 0基础设施Day 1-2
```bash
git checkout master && git checkout -b phase/0-infrastructure
```
### Day 1 — Gateway 骨架 + 数据库
**任务 1.1**: 在 `gateway/` 目录下创建 IntegrationGateway 解决方案 (`dotnet new sln` + `Host` webapi + `Core` classlib)。验证: `dotnet build`
**任务 1.2**: Core 层 7 接口 + 8 模型 + AdapterRegistry/TokenManager/RateLimiter。验证: 单元测试 mock 适配器。
**任务 1.3**: Host 层 HealthController/DevicesController/PointsController/StreamsController/AlarmsController/SyncController。验证: `GET /api/gateway/health` → 200。
**任务 1.4**: 8 张表 DDL 执行。验证: `SELECT COUNT(*) FROM Base_Device` → 0唯一索引存在。
**任务 1.5**: 代码生成器跑 8 张表。验证: 管理端 8 个新菜单可 CRUD。
### Day 2 — Vol.Pro 侧
**任务 2.1**: `GatewayClient.cs` (IDependency)。验证: 注入后 HealthCheckAsync() → true。
**任务 2.2**: `DeviceManagerController.cs` (Partial/) — GetRegionTree / GetDevicesByRegion / PUT。验证: Postman 返回 JSON。
**任务 2.3**: `SyncDevicesJob` (Quartz)。验证: Quartz 面板看到 Job。
### 合并
```bash
git add -A && git commit -m "Phase 0 完成"
git checkout master && git merge --squash phase/0-infrastructure
git commit -m "Phase 0: Gateway骨架 + 8张表 + GatewayClient + DeviceManagerController"
git push && git tag phase-0-done
```
---
## Phase 1Owl 适配器 + 视频设备页Day 3-6
```bash
git checkout master && git checkout -b phase/1-owl-video
```
### Day 3 — OwlAdapter
创建 `Adapters.Owl` 项目,实现 `IHasFlatDevices+IHasStreams+IAcceptsMetadataPush`
验证Postman → Gateway:
```
GET /health → {"owl":true}
GET /devices?adapter=owl → Owl设备列表
GET /streams/owl/{id}/live → WS-FLV地址
```
端到端同步 → `SELECT * FROM Base_Device WHERE AdapterCode='owl'` 有数据。
### Day 4 — 管理端页面框架
`DeviceManager/index.vue`(左右分栏) + `RegionTree.vue`el-tree + `DeviceTable.vue`el-table 可展开)。
验证: `/device-manager` 左侧区域树+右侧设备表。
### Day 5 — 视频操作 + Jessibuca
`VideoDeviceActions.vue` + `DeviceLivePreview.vue`Jessibuca 弹窗)+ 云台控制面板。
验证: 实时预览播放画面、云台方向键控制。
### Day 6 — 联调 + 边界测试
设备同步不重复、4路播放不卡顿、离线设备状态正确、生成器重跑文件不丢失。
### 合并
```bash
git add -A && git commit -m "Phase 1 完成"
git checkout master && git merge --squash phase/1-owl-video
git commit -m "Phase 1: OwlAdapter + 管理端视频设备页 (RegionTree+DeviceTable+Jessibuca)"
git push && git tag phase-1-done
```
---
## Phase 2MC4.0 适配器 + IoT 管理Day 7-11
```bash
git checkout master && git checkout -b phase/2-mc4-iot
```
### Day 7 — Mc4Adapter
实现 `IHasOwnDeviceTree+IHasPoints+IHasAlarms`。验证: Postman 调 Gateway `/health``/sync``/realtime``/control``/alarms``/confirm` 全部通过。
### Day 8 — 区域自动匹配
SyncEngine.ProcessTreeNode: type=1 → MatchOrCreateRegion, type=2 → UpsertDevice。
验证: 同步后 `warehouse_regions` 有 MC4.0 区域,`Base_Device.RegionId` 正确。
### Day 9 — IoT 操作 + 实时数据
`IoTDeviceActions.vue` + 实时数据弹窗(含开关/滑块控件)。
验证: 拖动滑块 → 设备实际值改变。
### Day 10 — 告警 + 地图绑定
编辑弹窗告警 tab + `MapBindingPanel.vue`
验证: 地图绑定保存后值持久化。
### Day 11 — SignalR + Quartz
`IoTDataHub.cs` + `RealtimePollJob`(5s) + `AlarmPollJob`(10s)。
验证: warehouse 端 SignalR 收到实时数据和告警。
### 合并
```bash
git add -A && git commit -m "Phase 2 完成"
git checkout master && git merge --squash phase/2-mc4-iot
git commit -m "Phase 2: Mc4Adapter + SyncEngine + SignalR + Quartz + 地图绑定"
git push && git tag phase-2-done
```
---
## Phase 3warehouse 端 + 全链路联调Day 12-17
```bash
git checkout master && git checkout -b phase/3-warehouse
```
### Day 12-13 — 视频播放器
Live.vue / History.vue / VideoWall.vue 假数据→真实 API + Jessibuca。
验证: 全功能可用。
### Day 14-15 — IoT 面板
实时数据看板(SignalR) / 控制面板 / 告警面板。
验证: warehouse IoT 功能可用。
### Day 16-17 — 全链路联调
设备同步→入库、区域树→el-tree、实时预览→播放、云台→转动、实时数据→更新、控制→响应、告警→弹窗(<15s)、确认→MC4.0。
性能: 9路视频≥15fps, 100设备轮询<3s, 500设备同步<30s。
### 合并
```bash
git add -A && git commit -m "Phase 3 完成"
git checkout master && git merge --squash phase/3-warehouse
git commit -m "Phase 3: warehouse视频+IoT面板 + 全链路联调"
git push && git tag phase-3-done
```
---
## Phase 4验证 + 发布Day 18-20
```bash
git checkout master && git checkout -b phase/4-verify
```
### Day 18 — 代码隔离验证
重跑生成器 → Partial/extension/DeviceManager 目录未被覆盖。
### Day 19 — 异常场景
Owl/MC4.0/Gateway 宕机不崩溃Token 过期自动刷新,并发同步互不干扰。
### Day 20 — 文档收尾
API 文档、部署手册、组件说明。
### 合并 + 发布
```bash
git add -A && git commit -m "Phase 4 完成"
git checkout master && git merge --squash phase/4-verify
git commit -m "Phase 4: 代码隔离验证 + 异常测试 + 文档"
git push && git tag phase-4-done
git tag -a v2.0.0 -m "SecMPS v2.0: IntegrationGateway + 统一设备管理"
git push origin v2.0.0
```
---
## 附录 A每日检查清单
```
□ 新增 C# 服务实现 IDependency
□ Controller 写在 Partial/ 目录
□ 前端在 extension/ 目录
□ 未修改自动生成文件
□ MC4.0 经 RateLimiter
□ Owl Token 用 TokenManager
□ 实时数据未写 IoT_DeviceData
□ dotnet build 零错误
```
## 附录 B端口分配
| 服务 | 端口 |
|------|------|
| IntegrationGateway | 5100 |
| VolPro.WebApi | 9100 |
| web.vite | 9000 |
| warehouse | 9200 |
| Owl | 80 |
| MC4.0 | 3000 |
## 附录 C里程碑标签
| 标签 | 指向 |
|------|------|
| `phase-0-done` | Gateway 骨架 + 建表 |
| `phase-1-done` | Owl + 视频设备页 |
| `phase-2-done` | MC4 + IoT + SignalR |
| `phase-3-done` | warehouse + 联调 |
| `phase-4-done` | 验证 + 文档 |
| `v2.0.0` | 正式发布 |
---
> **文档结束**
> **取代**: SecMPS_整合项目实施手册_v2.0.md

View File

@@ -0,0 +1,296 @@
# SecMPS 整合方案最终版IntegrationGateway + 统一设备管理
> **版本**: v2.0
> **日期**: 2026-05-15
> **状态**: 待实施
> **替代**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0
---
## 一、总体架构
```
前端层
web.vite 管理端(设备管理页+标准CRUD warehouse 大屏Map/Live/IoT/Alarm
│ HTTP REST │ HTTP REST + SignalR
▼ ▼
Vol.Pro 后端 (api_sqlsugar)
DeviceManagerController / GatewayClient / SignalR Hubs
Quartz: SyncDevicesJob / RealtimePollJob / AlarmPollJob
数据库: Base_Device / warehouse_regions / Device_Video_Ext / Device_IoT_Ext / IoT_DevicePoint / IoT_Alarm
│ HTTP REST
IntegrationGateway (独立服务 :5100)
Adapters.Owl (IHasFlatDevices+IHasStreams+IAcceptsMetadataPush)
Adapters.MC4 (IHasOwnDeviceTree+IHasPoints+IHasAlarms)
Core: AdapterRegistry / SyncEngine / TokenManager / RateLimiter
│ HTTP │ HTTP
▼ ▼
Owl + ZLMediaKit MC4.0 采集网关
Docker Compose HTTP API :3000
```
---
## 二、IntegrationGateway 设计
### 2.1 项目结构
```
IntegrationGateway/
├── src/
│ ├── Host/Controllers/ → Devices / Points / Streams / Alarms / Sync / Health
│ ├── Core/Abstractions/ → 分型接口
│ │ ├── IIntegrationAdapter
│ │ ├── IHasOwnDeviceTree (MC4.0)
│ │ ├── IHasFlatDevices (Owl)
│ │ ├── IHasPoints (MC4.0)
│ │ ├── IHasStreams (Owl)
│ │ ├── IHasAlarms (通用)
│ │ └── IAcceptsMetadataPush (Owl)
│ ├── Core/Infrastructure/ → SyncEngine / AdapterRegistry / TokenManager / RateLimiter
│ ├── Adapters.Owl/ → OwlAdapter
│ └── Adapters.MC4/ → Mc4Adapter
```
### 2.2 适配器能力矩阵
| 接口 | Owl | MC4.0 | 门禁(未来) |
|------|:---:|:-----:|:----------:|
| IHasOwnDeviceTree | ❌ | ✅ | ❌ |
| IHasFlatDevices | ✅ | ❌ | ✅ |
| IHasPoints | ❌ | ✅ | ❌ |
| IHasStreams | ✅ | ❌ | ❌ |
| IHasAlarms | ⚠️ | ✅ | ✅ |
| IAcceptsMetadataPush | ✅ | ❌ | ⚠️ |
### 2.3 双向同步引擎
| 方向 | 说明 | MC4.0 | Owl |
|------|------|-------|-----|
| PullToVolPro | 第三方→Vol.Pro | FullReplace | Merge |
| PushToSource | Vol.Pro→第三方 | 告警确认/控制 | 元数据/PTZ |
| Bidirectional | 先写第三方再更新本地 | 告警确认 | — |
### 2.4 Gateway API
```
GET /api/gateway/health
GET /api/gateway/devices?adapter=&page=&size=
GET /api/gateway/devices/sync?adapter=
GET /api/gateway/realtime/{adapter}/{deviceId}
POST /api/gateway/realtime/{adapter}/control
GET /api/gateway/streams/{adapter}/{id}/live
POST /api/gateway/streams/{adapter}/{id}/ptz
GET /api/gateway/alarms/{adapter}?from=&to=
POST /api/gateway/alarms/{adapter}/{id}/confirm
```
---
## 三、数据模型
### 3.1 区域表 warehouse_regions现有
| 字段 | 说明 |
|------|------|
| Id | int PK |
| RegionName | nvarchar(255) |
| ParentId | int? (自引用树) |
### 3.2 统一设备主表 Base_Device新建
| 字段 | 类型 | 说明 |
|------|------|------|
| DeviceId | uniqueidentifier PK | Vol.Pro内部ID |
| DeviceName | nvarchar(100) | 本地名称 |
| **AdapterCode** | nvarchar(50) | owl/mc4/hikvision_access |
| **SourceId** | nvarchar(100) | 第三方原始ID |
| DeviceCategory | int | 1=视频 2=IoT 3=门禁 4=道闸 5=报警 |
| DeviceType | nvarchar(50) | GB28181/TempSensor... |
| **RegionId** | int? | FK→warehouse_regions.Id |
| **IsParent** | bit | 是否父设备 |
| **ParentDeviceId** | uniqueidentifier? | 父设备自引用 |
| IsOnline | int | 0/1 |
| **MapModelId** | nvarchar(100) | VgoMap模型ID |
| MapModelScale | float | |
| MapModelRotation | nvarchar(100) | |
| Lat/Lng | float | WGS84 |
| ExtraData | nvarchar(max) | 适配器原始JSON |
| LocalOverrides | nvarchar(max) | 本地覆盖JSON |
| SyncVersion | bigint | 乐观锁 |
| LastSyncTime | datetime | |
唯一约束: (AdapterCode, SourceId)
### 3.3 扩展表
- **Device_Video_Ext**: 视频设备扩展OwlDeviceId, Protocol, ChannelCount
- **Device_IoT_Ext**: IoT设备扩展Mc4DeviceId, ObjectType, Tag
- **Video_Channel**: 视频通道OwlChannelId, DeviceId, HasPtz
- **Video_Record**: 录像记录
- **IoT_DevicePoint**: 点位表PointIndex, PointName, Unit, IsControlPoint
- **IoT_DeviceData**: 历史归档(仅存快照,实时不入库)
- **IoT_Alarm**: 告警记录Mc4AlarmId, AlarmLevel, State
### 3.4 层级示例
```
warehouse_regions: 厂区 → 新库区 → 31号库房
Base_Device (RegionId=3):
东北角高位摄像机 (Category=1)
人员计数摄像机 (Category=1)
动环采集器 (Category=2, IsParent=1)
├── 温湿度探头 (ParentDeviceId=采集器)
├── 空调控制器 (ParentDeviceId=采集器)
├── 除湿机 (ParentDeviceId=采集器)
└── 紧急报警按钮 (ParentDeviceId=采集器)
```
---
## 四、管理端统一设备页面
### 4.1 布局
```
┌──────────────────┬───────────────────────────────────────┐
│ 顶部工具栏 │ │
├──────────────────┼───────────────────────────────────────┤
│ 左侧区域树 │ 右侧设备列表 │
│ │ │
│ 📁 厂区 │ 区域:31号库房 最后同步:05-15 │
│ 📁 新库区 │ ┌──────────────────────────────┐ │
│ 📁 31号库房 ● │ │ ▸动环采集器 MC4.0 █在线 │ │
│ 📁 11号库房 │ │ 东北角摄像机 Owl █在线 │ │
│ │ └──────────────────────────────┘ │
│ [+新建区域] │ │
└──────────────────┴───────────────────────────────────────┘
```
### 4.2 前端文件
```
web.vite/src/views/warehouse/DeviceManager/
├── index.vue # 主页面(左树右表)
├── components/
│ ├── RegionTree.vue # el-tree 区域树
│ ├── DeviceTable.vue # el-table 可展开行
│ ├── DeviceEditDialog.vue # 编辑弹框
│ ├── MapBindingPanel.vue # 地图绑定面板
│ ├── VideoDeviceActions.vue # 视频操作按钮组
│ └── IoTDeviceActions.vue # IoT操作按钮组
└── api/deviceManager.js
路由: /device-manager
```
### 4.3 后端 API
| 接口 | 说明 |
|------|------|
| GET `/api/DeviceManager/GetRegionTree` | 区域树+设备数量 |
| GET `/api/DeviceManager/GetDevicesByRegion?regionId=3` | 区域设备列表(含子设备) |
| PUT `/api/DeviceManager/{deviceId}` | 更新设备(含地图绑定) |
| POST `/api/DeviceManager/SyncFromGateway` | 手动同步 |
Controller 路径: `Controllers/Warehouse/Partial/DeviceManagerController.cs`
### 4.4 操作按钮矩阵
| Category | 按钮 |
|----------|------|
| 1-视频 | 实时预览/云台控制/查看回放/获取快照/同步通道 |
| 2-IoT | 查看实时数据/设备控制/刷新点位/查看告警 |
| 3-门禁 | 远程开门/查看记录/查看告警 |
| 4-道闸 | 抬杆/落杆/查看记录 |
---
## 五、同步策略
### MC4.0 → 区域树+设备
- `type=1` 节点 → 名称匹配 warehouse_regions → 绑区或新建
- `type=2` 节点 → Upsert Base_Device, RegionId=叶子区域
- 模式: FullReplace, 频率限制: 2次/秒
### Owl → 设备
- `GET /devices` → Upsert Base_Device (Category=1, IsParent=1)
- `GET /channels` → Upsert Base_Device (ParentDeviceId=NVR)
- Owl 无区域概念 → RegionId=NULL, 管理员手动分配
- 模式: Merge
### 反方向写回
| 操作 | Owl | MC4.0 |
|------|:---:|:-----:|
| 设备改名 | ✅ PUT /devices/:id | ❌ |
| 告警确认 | ⚠️ | ✅ |
| 设备控制 | ✅ PTZ | ✅ 点位写值 |
---
## 六、部署拓扑
```
Docker: Owl+ZLM (:80,:5060) │ Docker: MC4.0 (:3000)
┌──────────────┴──────────────┐
│ IntegrationGateway :5100 │
└──────────────┬──────────────┘
┌──────────────┴──────────────┐
│ VolPro.WebApi :9100 │
│ MySQL / Redis │
└──────────────┬──────────────┘
┌──────────────────┴──────────────────┐
│ web.vite :9000 warehouse :9200 │
└─────────────────────────────────────┘
```
---
## 七、实施路线
| 阶段 | 工期 | 内容 |
|------|------|------|
| Phase 0 | Day 1-2 | Gateway骨架 + Base_Device建表 + 代码生成 |
| Phase 1 | Day 3-6 | OwlAdapter + 管理端视频设备页 |
| Phase 2 | Day 7-11 | Mc4Adapter + IoT管理 + 区域树匹配 + SignalR |
| Phase 3 | Day 12-17 | warehouse端改造 + 全链路联调 |
| Phase 4 | Day 18-20 | 验证 + 缓冲 |
**总计: 18-20 个工作日**
---
## 八、新增整合流程
以接入「海康门禁」为例:
1. 新建 `IntegrationGateway.Adapters.HikvisionAccess` 项目
2. 实现 `IHasFlatDevices + IHasAlarms`
3. 注册到 Host
4. 前端新增 `AccessDeviceActions.vue` (~80行)
5. DeviceTable.vue 加 `v-else-if (Category===3)`
6. Vol.Pro 后端零改动
**总工作量: 1-2 天**
---
## 九、代码组织规范
| 代码类型 | 路径 | 被覆盖? |
|----------|------|:---:|
| 第三方对接 | IntegrationGateway/ | ❌ |
| 扩展Controller | Controllers/*/Partial/ | ❌ |
| Entity扩展 | DomainModels/*/partial/ | ❌ |
| 前端业务逻辑 | extension/warehouse/*.jsx | ❌ |
| 自定义页面 | views/warehouse/DeviceManager/ | ❌ |
| 自动生成代码 | 生成器默认路径 | ✅ |
---
> **文档结束**
> **取代**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0、Vol.Pro_整合项目_实施方案_v1.0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,878 @@
# Vol.Pro + Owl + ZLMediaKit 视频监控整合方案
> **版本**: v1.0
> **日期**: 2026-04-29
> **编制**: 浮浮酱
> **状态**: 待确认(未实施)
---
## 一、项目概述
### 1.1 需求背景
现有项目包含四个模块:
| 模块 | 技术栈 | 用途 |
|------|--------|------|
| **api_sqlsugar** | .NET 8 + SqlSugar + Vol.Pro框架 | 后端API服务 |
| **web.vite** | Vue3 + Vite + TypeScript | Vol.Pro管理端管理后台 |
| **warehouse** | Vue3 + 自定义前端 | 用户端(大屏展示/业务端) |
| **owl_zlmediakit** | Docker + Owl + ZLMediaKit | GB28181视频监控平台 |
**目标**: 在Vol.Pro管理端中管理NVR和摄像机增删改查通过Vol.Pro后端对接Owl获取实时流/回放流地址,向两个前端(管理端+用户端)提供播放接口,实现浏览器中的实时监控、历史回放和云台控制。
### 1.2 核心问题
1. warehouse已有视频UI框架`Live.vue``History.vue``VideoWall.vue`),但**无实际播放器集成**,数据为硬编码模拟数据
2. Vol.Pro后端**尚无摄像机/NVR相关实体和控制器**
3. Owl与Vol.Pro的**数据模型不兼容**,需要中间层转换
4. 播放器选型浏览器播放GB28181流的方案
### 1.3 关键前提:所有修改独立于框架代码
> **经过对Vol.Pro框架源码和文档的调研确认所有自定义代码均可完全独立于框架自动生成代码进行开发和维护。**
Vol.Pro框架的设计核心原则是**"自动生成代码不修改自定义代码写Partial/扩展文件"**。具体体现在:
| 层级 | 自动生成文件位置 | 扩展文件位置 | 扩展方式 |
|------|-----------------|-------------|----------|
| **Controller** | `Controllers/模块/表名Controller.cs` | `Controllers/模块/Partial/表名Controller.cs` | `partial class` |
| **Service** | `Services/模块/表名Service.cs` | `Services/模块/Partial/表名Service.cs` | `partial class` + override/委托钩子 |
| **Entity** | `DomainModels/模块/表名.cs` | `DomainModels/模块/partial/表名.cs` | `partial class` + `[NotMapped]` |
| **前端(Vue)** | `views/模块/表名.vue` + `options.js` | `extension/模块/表名.jsx``.vue` | 扩展组件/自定义逻辑 |
| **独立服务** | — | 新建文件,实现`IDependency` | Autofac自动IOC注入 |
**框架生成的文件中明确注释**
> *"代码由框架生成任何更改都可能导致被代码生成器覆盖。如果要增加方法请在当前目录下Partial文件夹编写。"*
**结论**
- 代码生成器重新生成时,**只会覆盖自动生成的文件**,不会触碰`Partial/``partial/``extension/`目录下的自定义代码
- 所有视频监控相关的业务代码Owl对接、取流、回放、云台将写在扩展文件中与框架代码完全隔离
- 新增的服务(如`OwlApiService`)通过实现`IDependency`接口由Autofac自动注册无需修改框架的任何配置
- **框架升级时只需重新运行代码生成器覆盖自动生成的CRUD文件所有自定义业务逻辑完全保留**
---
## 二、系统架构设计
### 2.1 整体架构
```
┌─────────────────────────────────────────────────────────────────────────┐
│ 客户端层 │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ web.vite 管理端 │ │ warehouse 用户端 │ │
│ │ (设备管理+视频查看) │ │ (大屏+实时监控墙) │ │
│ └──────────┬──────────┘ └──────────┬──────────┘ │
└─────────────┼──────────────────────────┼────────────────────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ Vol.Pro 后端 (api_sqlsugar) │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 自动生成CRUD模块 (VideoDevice / VideoChannel / VideoRecord) │ │
│ │ ├─ 设备管理 (增删改查) │ │
│ │ ├─ 通道管理 (增删改查) │ │
│ │ └─ 录像管理 (查询) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ 扩展API模块 (VideoStreamController) │ │
│ │ ├─ POST /api/VideoStream/live → 获取实时流地址 │ │
│ │ ├─ POST /api/VideoStream/playback → 获取回放流地址 │ │
│ │ ├─ POST /api/VideoStream/ptz → 云台控制 │ │
│ │ ├─ POST /api/VideoStream/snapshot → 获取快照 │ │
│ │ └─ POST /api/VideoStream/stop → 停止播放 │ │
│ └─────────────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ Owl对接服务 (OwlApiService) │ │
│ │ ├─ 设备同步 (定时从Owl拉取设备列表) │ │
│ │ ├─ JWT Token管理 (缓存/刷新) │ │
│ │ ├─ 流地址获取 (调用Owl /channels/:id/play) │ │
│ │ ├─ 回放查询 (调用Owl /recordings) │ │
│ │ └─ 云台控制 (调用Owl /channels/:id/ptz/control) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│ HTTP API
┌─────────────────────────────────────────────────────────────────────────┐
│ Owl (GoWVP) 平台 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ SIP信令层 (GB28181设备注册/心跳/控制) │ │
│ │ HTTP API层 (设备/通道/播放/回放/云台) │ │
│ │ WebHook层 (接收ZLM事件回调) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└──────────────────────────────┬──────────────────────────────────────────┘
│ HTTP API / WebHook
┌─────────────────────────────────────────────────────────────────────────┐
│ ZLMediaKit 流媒体服务器 │
│ ┌─────────────────────────────────────────────────────────────────┐ │
│ │ RTP收流 / RTMP推流 / RTSP拉流 │ │
│ │ 协议转换 (HLS/FLV/WebRTC/RTMP/RTSP) │ │
│ │ 录像存储 (MP4切片) │ │
│ └─────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 2.2 关键设计原则
1. **Owl作为主设备源**: Owl负责GB28181设备接入、SIP信令、流管理Vol.Pro不直接对接设备只对接Owl的HTTP API
2. **数据双写**: 设备在Owl中注册后通过同步机制将设备信息写入Vol.Pro数据库实现Vol.Pro管理端对设备的CRUD管理
3. **播放地址代理**: Vol.Pro后端作为统一入口前端不直接访问Owl所有取流请求经Vol.Pro转发便于权限控制和日志记录
4. **播放器统一**: 两个前端使用同一套播放器组件支持FLV/HLS/WebRTC多协议
---
## 三、数据库表设计
### 3.1 表结构说明
> **设备统一管理设计**本方案与MC4.0采集网关方案共用统一设备主表 `Base_Device`,实现视频监控设备和采集网关设备的统一管理,并支持在三维地图上统一标记展示。
#### 3.1.0 统一设备主表 (Base_Device) 【与MC4.0方案共用】
| 字段名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| DeviceId | uniqueidentifier | ✅ | 主键Vol.Pro系统内部ID |
| DeviceName | nvarchar(100) | ✅ | 设备名称 |
| DeviceCategory | int | ✅ | 设备大类1=视频监控, 2=采集网关 |
| DeviceType | int | | 设备细分类型根据Category解释不同值 |
| SourceId | nvarchar(64) | ✅ | 源系统设备IDOwlDeviceId或Mc4DeviceId |
| IpAddress | nvarchar(50) | | IP地址 |
| Port | int | | 端口 |
| IsOnline | int | | 是否在线0=离线, 1=在线 |
| Location | nvarchar(200) | | 安装位置描述 |
| Lat | float | | 纬度WGS84坐标系 |
| Lng | float | | 经度WGS84坐标系 |
| **MapModelId** | **nvarchar(100)** | | **三维地图模型IDVgoMap中对应模型的唯一标识** |
| MapModelScale | float | | 三维模型缩放比例默认1.0 |
| MapModelRotation | nvarchar(100) | | 三维模型旋转角度JSON格式{"x":0,"y":0,"z":0} |
| Enable | int | | 启用状态0=禁用, 1=启用 |
| Remark | nvarchar(500) | | 备注 |
| CreateID / Creator / CreateDate | | | Vol.Pro标准审计字段 |
| ModifyID / Modifier / ModifyDate | | | Vol.Pro标准审计字段 |
> **MapModelId 字段说明**
> - 用于在warehouse前端三维地图VgoMap中标记设备位置
> - 值由三维地图系统提供标识对应三维模型的唯一ID
> - 管理端可在设备编辑页面中配置/修改此字段
> - 三维地图加载时根据MapModelId将设备图标/模型绑定到地图对应位置
#### 3.1.1 视频设备扩展表 (Device_Video_Ext)
> 存储视频监控设备特有的扩展信息通过DeviceId关联Base_Device主表。
| 字段名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ExtId | uniqueidentifier | ✅ | 主键 |
| DeviceId | uniqueidentifier | ✅ | 关联Base_Device.DeviceId |
| OwlDeviceId | nvarchar(64) | ✅ | Owl系统设备IDGB28181的DeviceID |
| Protocol | int | | 接入协议1=GB28181, 2=ONVIF, 3=RTMP, 4=RTSP |
| Manufacturer | nvarchar(100) | | 厂商 |
| Model | nvarchar(100) | | 型号 |
| ChannelCount | int | | 通道数量 |
| OwlStatus | nvarchar(50) | | Owl中的原始状态JSON |
#### 3.1.2 视频通道表 (Video_Channel)
| 字段名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| ChannelId | uniqueidentifier | ✅ | 主键Vol.Pro系统内部ID |
| OwlChannelId | nvarchar(64) | ✅ | Owl系统通道ID |
| DeviceId | uniqueidentifier | ✅ | 关联Video_Device.DeviceId |
| ChannelName | nvarchar(100) | ✅ | 通道名称 |
| ChannelNo | int | | 通道编号 |
| OwlStreamApp | nvarchar(50) | | Owl中的stream app如rtp |
| OwlStreamName | nvarchar(100) | | Owl中的stream name |
| HasPtz | int | | 是否支持云台0=否, 1=是 |
| HasRecording | int | | 是否支持录像0=否, 1=是 |
| RecordMode | int | | 录像模式0=不录像, 1=设备录像(SD卡), 2=中心录像(Owl云录像) |
| IsOnline | int | | 是否在线 |
| SnapshotUrl | nvarchar(500) | | 快照图片URL |
| Location | nvarchar(200) | | 安装位置 |
| Lat | float | | 纬度 |
| Lng | float | | 经度 |
| Enable | int | | 启用状态 |
| Remark | nvarchar(500) | | 备注 |
| CreateID / Creator / CreateDate | | | 标准审计字段 |
| ModifyID / Modifier / ModifyDate | | | 标准审计字段 |
#### 3.1.3 云录像记录表 (Video_Record)
| 字段名 | 类型 | 必填 | 说明 |
|--------|------|------|------|
| RecordId | uniqueidentifier | ✅ | 主键 |
| OwlRecordId | nvarchar(64) | ✅ | Owl录像记录ID |
| ChannelId | uniqueidentifier | ✅ | 关联Video_Channel.ChannelId |
| StartTime | datetime | ✅ | 开始时间 |
| EndTime | datetime | ✅ | 结束时间 |
| Duration | int | | 时长(秒) |
| FileSize | bigint | | 文件大小(字节) |
| FilePath | nvarchar(500) | | 文件路径 |
| RecordType | int | | 录像类型1=定时录像, 2=告警录像, 3=手动录像 |
| ThumbUrl | nvarchar(500) | | 缩略图URL |
| CreateDate | datetime | | 创建时间 |
### 3.2 建表SQL (SQL Server)
```sql
-- ============================================
-- 统一设备主表与MC4.0采集网关方案共用)
-- ============================================
CREATE TABLE Base_Device (
DeviceId UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
DeviceName NVARCHAR(100) NOT NULL,
DeviceCategory INT NOT NULL, -- 1=视频监控, 2=采集网关
DeviceType INT, -- 细分类型根据Category解释
SourceId NVARCHAR(64) NOT NULL, -- 源系统设备IDOwlDeviceId或Mc4DeviceId
IpAddress NVARCHAR(50),
Port INT,
IsOnline INT DEFAULT 0,
Location NVARCHAR(200), -- 安装位置描述
Lat FLOAT, -- 纬度
Lng FLOAT, -- 经度
MapModelId NVARCHAR(100), -- 三维地图模型IDVgoMap
MapModelScale FLOAT DEFAULT 1.0, -- 三维模型缩放比例
MapModelRotation NVARCHAR(100), -- 三维模型旋转角度JSON
Enable INT DEFAULT 1,
Remark NVARCHAR(500),
CreateID INT,
Creator NVARCHAR(30),
CreateDate DATETIME DEFAULT GETDATE(),
ModifyID INT,
Modifier NVARCHAR(30),
ModifyDate DATETIME
);
CREATE INDEX IX_Base_Device_Category ON Base_Device(DeviceCategory);
CREATE INDEX IX_Base_Device_SourceId ON Base_Device(SourceId);
CREATE INDEX IX_Base_Device_IsOnline ON Base_Device(IsOnline);
CREATE INDEX IX_Base_Device_MapModelId ON Base_Device(MapModelId);
-- ============================================
-- 视频监控设备扩展表
-- ============================================
CREATE TABLE Device_Video_Ext (
ExtId UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
DeviceId UNIQUEIDENTIFIER NOT NULL,
OwlDeviceId NVARCHAR(64) NOT NULL,
Protocol INT DEFAULT 1, -- 1=GB28181, 2=ONVIF, 3=RTMP, 4=RTSP
Manufacturer NVARCHAR(100),
Model NVARCHAR(100),
ChannelCount INT DEFAULT 0,
OwlStatus NVARCHAR(50),
FOREIGN KEY (DeviceId) REFERENCES Base_Device(DeviceId)
);
CREATE INDEX IX_Device_Video_Ext_DeviceId ON Device_Video_Ext(DeviceId);
CREATE INDEX IX_Device_Video_Ext_OwlDeviceId ON Device_Video_Ext(OwlDeviceId);
-- 视频通道表
CREATE TABLE Video_Channel (
ChannelId UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
OwlChannelId NVARCHAR(64) NOT NULL,
DeviceId UNIQUEIDENTIFIER NOT NULL,
ChannelName NVARCHAR(100) NOT NULL,
ChannelNo INT DEFAULT 1,
OwlStreamApp NVARCHAR(50),
OwlStreamName NVARCHAR(100),
HasPtz INT DEFAULT 0,
HasRecording INT DEFAULT 0,
RecordMode INT DEFAULT 0,
IsOnline INT DEFAULT 0,
SnapshotUrl NVARCHAR(500),
Enable INT DEFAULT 1,
Remark NVARCHAR(500),
CreateID INT,
Creator NVARCHAR(30),
CreateDate DATETIME DEFAULT GETDATE(),
ModifyID INT,
Modifier NVARCHAR(30),
ModifyDate DATETIME,
FOREIGN KEY (DeviceId) REFERENCES Base_Device(DeviceId)
);
CREATE INDEX IX_Video_Channel_DeviceId ON Video_Channel(DeviceId);
CREATE INDEX IX_Video_Channel_OwlChannelId ON Video_Channel(OwlChannelId);
CREATE INDEX IX_Video_Channel_IsOnline ON Video_Channel(IsOnline);
-- 云录像记录表
CREATE TABLE Video_Record (
RecordId UNIQUEIDENTIFIER PRIMARY KEY DEFAULT NEWID(),
OwlRecordId NVARCHAR(64) NOT NULL,
ChannelId UNIQUEIDENTIFIER NOT NULL,
StartTime DATETIME NOT NULL,
EndTime DATETIME NOT NULL,
Duration INT,
FileSize BIGINT,
FilePath NVARCHAR(500),
RecordType INT DEFAULT 1,
ThumbUrl NVARCHAR(500),
CreateDate DATETIME DEFAULT GETDATE()
);
CREATE INDEX IX_Video_Record_ChannelId ON Video_Record(ChannelId);
CREATE INDEX IX_Video_Record_StartTime ON Video_Record(StartTime);
CREATE INDEX IX_Video_Record_EndTime ON Video_Record(EndTime);
```
---
## 四、Vol.Pro后端扩展方案
### 4.1 代码生成步骤
使用Vol.Pro代码生成器自动生成3个模块的CRUD代码
1. **Base_Device**统一设备主表DeviceCategory=1表示视频监控设备
2. **Device_Video_Ext**(视频设备扩展信息)
3. **Video_Channel**(视频通道)
4. **Video_Record**(云录像)
生成后获得:
- `Base_DeviceController` / `Base_DeviceService` / `IBase_DeviceService` / `Base_Device`实体
- `Device_Video_ExtController` / `Device_Video_ExtService` / `IDevice_Video_ExtService` / `Device_Video_Ext`实体
- `Video_ChannelController` / `Video_ChannelService` / `IVideo_ChannelService` / `Video_Channel`实体
- `Video_RecordController` / `Video_RecordService` / `IVideo_RecordService` / `Video_Record`实体
### 4.2 Owl对接服务 (OwlApiService)
在Vol.Pro后端创建**完全独立**的自定义服务封装对Owl的所有HTTP调用
```csharp
// 文件位置api_sqlsugar/Warehouse/Services/Owl/OwlApiService.cs
// (新建文件,不修改任何框架代码)
/// <summary>
/// Owl API 对接服务
/// </summary>
public interface IOwlApiService : IDependency
{
/// <summary>获取Owl JWT Token带缓存</summary>
Task<string> GetTokenAsync();
/// <summary>同步Owl设备列表到本地</summary>
Task<WebResponseContent> SyncDevicesAsync();
/// <summary>同步Owl通道列表到本地</summary>
Task<WebResponseContent> SyncChannelsAsync();
/// <summary>获取实时流播放地址</summary>
Task<StreamPlayResult> GetLiveUrlAsync(string owlChannelId, string protocol = "ws_flv");
/// <summary>获取回放流地址</summary>
Task<StreamPlaybackResult> GetPlaybackUrlAsync(string owlChannelId, DateTime start, DateTime end);
/// <summary>云台控制</summary>
Task<WebResponseContent> PtzControlAsync(string owlChannelId, PtzCommand command);
/// <summary>获取快照</summary>
Task<byte[]> GetSnapshotAsync(string owlChannelId);
/// <summary>停止播放</summary>
Task<WebResponseContent> StopPlayAsync(string owlChannelId);
}
```
**实现要点**
1. **新建文件**实现`IOwlApiService`,不修改任何框架代码
2. 实现`IDependency`接口Autofac自动注册到IOC容器
3. 使用 `IHttpClientFactory` 创建HTTP客户端
4. Token缓存到内存/Redis过期前自动刷新
5. 所有方法内部处理Owl的JWT认证自动附加Authorization header
6. 返回值统一转换为Vol.Pro的 `WebResponseContent` 格式
### 4.3 扩展API控制器 (VideoStreamController)
在Vol.Pro中**新增独立的Controller文件**(不修改任何框架代码),提供取流、回放、云台等扩展接口:
```csharp
// 文件位置api_sqlsugar/Warehouse/Controllers/VideoStreamController.cs
// (全新文件,与框架代码无任何耦合)
namespace Warehouse.Controllers
{
[Route("api/VideoStream")]
[JWTAuthorize]
public class VideoStreamController : VolController
{
private readonly IOwlApiService _owlApi;
private readonly IVideo_ChannelService _channelService;
public VideoStreamController(
IOwlApiService owlApi,
IVideo_ChannelService channelService)
{
_owlApi = owlApi;
_channelService = channelService;
}
/// <summary>
/// 获取实时流播放地址
/// </summary>
[HttpPost, Route("GetLiveUrl")]
public async Task<ActionResult> GetLiveUrl([FromBody] LiveUrlInput input)
{
var channel = await _channelService.GetChannelByIdAsync(input.ChannelId);
if (channel == null) return Json(new WebResponseContent().Error("通道不存在"));
var result = await _owlApi.GetLiveUrlAsync(channel.OwlChannelId, input.Protocol);
return Json(new WebResponseContent().OK(null, result));
}
/// <summary>
/// 获取回放流地址
/// </summary>
[HttpPost, Route("GetPlaybackUrl")]
public async Task<ActionResult> GetPlaybackUrl([FromBody] PlaybackUrlInput input)
{
var channel = await _channelService.GetChannelByIdAsync(input.ChannelId);
if (channel == null) return Json(new WebResponseContent().Error("通道不存在"));
var result = await _owlApi.GetPlaybackUrlAsync(
channel.OwlChannelId, input.StartTime, input.EndTime);
return Json(new WebResponseContent().OK(null, result));
}
/// <summary>
/// 云台控制
/// </summary>
[HttpPost, Route("PtzControl")]
public async Task<ActionResult> PtzControl([FromBody] PtzInput input)
{
var channel = await _channelService.GetChannelByIdAsync(input.ChannelId);
if (channel == null) return Json(new WebResponseContent().Error("通道不存在"));
if (channel.HasPtz != 1) return Json(new WebResponseContent().Error("该通道不支持云台"));
var result = await _owlApi.PtzControlAsync(channel.OwlChannelId, new PtzCommand
{
Action = input.Action,
Direction = input.Direction,
Speed = input.Speed
});
return Json(result);
}
/// <summary>
/// 获取通道快照
/// </summary>
[HttpGet, Route("GetSnapshot")]
public async Task<IActionResult> GetSnapshot(Guid channelId)
{
var channel = await _channelService.GetChannelByIdAsync(channelId);
if (channel == null) return Json(new WebResponseContent().Error("通道不存在"));
var bytes = await _owlApi.GetSnapshotAsync(channel.OwlChannelId);
return File(bytes, "image/jpeg");
}
/// <summary>
/// 停止播放
/// </summary>
[HttpPost, Route("StopPlay")]
public async Task<ActionResult> StopPlay([FromBody] StopPlayInput input)
{
var channel = await _channelService.GetChannelByIdAsync(input.ChannelId);
if (channel == null) return Json(new WebResponseContent().Error("通道不存在"));
var result = await _owlApi.StopPlayAsync(channel.OwlChannelId);
return Json(result);
}
}
}
```
> **独立性说明**`VideoStreamController`是**全新创建的文件**,不继承任何自动生成的控制器,也不修改任何框架文件。它通过构造函数注入`IOwlApiService`和`IVideo_ChannelService`完全依赖IOC容器解耦。
### 4.4 设备同步机制
由于Owl是设备的真实数据源GB28181设备直接注册到OwlVol.Pro数据库中的设备需要通过**定时同步**或**手动同步**保持与Owl一致。
**同步方案**
1. **定时同步**推荐使用Vol.Pro内置的Quartz定时任务每5分钟执行一次设备同步
2. **手动同步**:管理端提供"同步设备"按钮点击后立即拉取Owl设备列表
3. **Webhook同步**可选高级方案Owl支持Webhook回调当设备注册/注销时回调Vol.Pro接口
**同步逻辑**
```
1. 调用 Owl GET /devices 获取设备列表
2. 调用 Owl GET /channels 获取通道列表
3. 对比本地数据库,执行增删改
4. 更新 Video_Device 和 Video_Channel 表
```
---
## 五、前端对接方案
### 5.1 播放器选型
浏览器播放GB28181视频流需要支持以下协议
| 协议 | 延迟 | 浏览器兼容性 | 推荐场景 |
|------|------|-------------|----------|
| **WebRTC** | < 500ms | Chrome/Firefox/Edge | **实时监控首选** |
| **WS-FLV** | 1-3s | 全浏览器 | 监控备用 |
| **HTTP-FLV** | 1-3s | 全浏览器 | 简单场景 |
| **HLS** | 5-10s | 全浏览器 | 回放首选 |
| **RTMP** | 2-5s | 需Flash/插件 | 不推荐浏览器 |
**推荐方案**
- **实时监控**: WebRTC延迟最低+ WS-FLV兼容性备用
- **历史回放**: HLS (m3u8)
- **播放器库**:
- [mpegts.js](https://github.com/xqq/mpegts.js) - 腾讯开源支持FLV/HLS纯JavaScript
- [Jessibuca](https://github.com/langhuihui/jessibuca) - 纯H5播放器支持FLV/HLS/WebRTCwasm解码
- [webrtc-streamer](https://github.com/mpromonet/webrtc-streamer) - WebRTC专用
**最终推荐**:使用 **Jessibuca****mpegts.js**(两者都是纯前端,无需插件,支持多协议切换)
> **⚠️ WebRTC配置前置条件**
> ZLMediaKit默认**不开启WebRTC**,需在`zlm-config.ini`中配置:
> ```ini
> [rtc]
> port=8000
> ```
> 同时需要配置DTLS证书。如果部署环境不满足WebRTC条件**默认使用WS-FLV**。
>
> **建议**联调阶段先验证WS-FLV可用再按需开启WebRTC。
### 5.2 管理端 (web.vite) 对接
在Vol.Pro管理端中通过代码生成器生成设备/通道/录像的CRUD页面后需要扩展以下功能。所有扩展均写在**独立的扩展文件**中,不修改代码生成器生成的文件:
**Vol.Pro前端扩展机制**
- 自动生成的代码:`views/模块/表名.vue` + `views/模块/表名/options.js`
- 自定义业务代码:`extension/模块/表名.jsx``.vue`(通过`import extend from "@/extension/..."`引入)
- **代码生成器重新生成时,不会覆盖`extension/`目录下的扩展文件**
1. **设备列表页扩展**(写在`extension/warehouse/Base_Device.jsx`
- 添加"同步设备"按钮调用后端同步接口仅对DeviceCategory=1显示
- 添加"在线状态"实时显示
- 添加"查看通道"操作列
- 添加`DeviceCategory`筛选条件(默认筛选视频监控设备)
2. **通道列表页扩展**(写在`extension/warehouse/Video_Channel.jsx`
- 添加"实时预览"按钮(弹窗播放视频)
- 添加"云台控制"按钮(在弹窗中显示云台面板)
- 添加"回放"按钮(跳转回放页面)
3. **新增视频播放页面**`views/video/VideoPlayer.vue`,全新文件):
- 使用Jessibuca播放器组件
- 支持协议切换WebRTC/FLV/HLS
- 集成云台控制面板
4. **新增回放查询页面**`views/video/VideoPlayback.vue`,全新文件):
- 日期时间选择器
- 时间轴组件
- HLS播放器
**扩展方式**:在代码生成后的 `.jsx` 扩展文件中编写自定义逻辑参考Vol.Pro文档的 `view-grid` 扩展方式。
### 5.3 用户端 (warehouse) 对接
warehouse已有 `Live.vue``History.vue``VideoWall.vue`,但均为占位符。需要:
1. **Live.vue 改造**
- 替换硬编码数据为真实API调用
- 集成Jessibuca播放器替换"正在加载..."占位符
- 摄像头列表从 `Video_Channel` API获取
- 点击摄像头获取流地址并播放
2. **History.vue 改造**
- 集成日期范围选择查询录像列表
- 调用回放API获取HLS地址
- 使用HLS播放器播放
3. **VideoWall.vue 改造**(最复杂):
- 将随机图片替换为真实视频播放器实例
- 每个格子是一个独立的Jessibuca实例
- 布局切换时动态创建/销毁播放器
- 云台控制按钮调用Vol.Pro后端PTZ API
**API调用示例**warehouse前端
```typescript
// 获取通道列表
import http from '@/api/http'
// 获取通道列表Vol.Pro标准分页接口
const getChannels = () => {
return http.post('/api/Video_Channel/GetPageData', {
page: 1,
rows: 100,
sort: 'CreateDate',
order: 'desc'
})
}
// 获取实时流地址
const getLiveUrl = (channelId: string, protocol = 'ws_flv') => {
return http.post('/api/VideoStream/GetLiveUrl', {
channelId,
protocol
})
}
// 云台控制
const ptzControl = (channelId: string, direction: string, speed = 0.5) => {
return http.post('/api/VideoStream/PtzControl', {
channelId,
action: 'continuous',
direction,
speed
})
}
// 获取回放地址
const getPlaybackUrl = (channelId: string, startTime: string, endTime: string) => {
return http.post('/api/VideoStream/GetPlaybackUrl', {
channelId,
startTime,
endTime
})
}
```
---
## 六、关键API接口文档
### 6.1 Vol.Pro后端对外接口
#### 6.1.1 获取实时流地址
```
POST /api/VideoStream/GetLiveUrl
Authorization: Bearer <Vol.Pro JWT Token>
Request:
{
"channelId": "guid", // Vol.Pro通道ID
"protocol": "ws_flv" // 可选: webrtc / ws_flv / http_flv / hls / rtmp / rtsp
}
Response:
{
"status": true,
"message": "ok",
"data": {
"channelId": "guid",
"channelName": "仓库入口",
"protocol": "ws_flv",
"url": "ws://192.168.3.108/proxy/sms/rtp/gb_xxx.live.flv",
"backupUrls": {
"webrtc": "webrtc://192.168.3.108/proxy/sms/...",
"hls": "http://192.168.3.108/proxy/sms/..."
}
}
}
```
#### 6.1.2 获取回放流地址
```
POST /api/VideoStream/GetPlaybackUrl
Authorization: Bearer <Vol.Pro JWT Token>
Request:
{
"channelId": "guid",
"startTime": "2026-04-28 08:00:00",
"endTime": "2026-04-28 18:00:00"
}
Response:
{
"status": true,
"message": "ok",
"data": {
"channelId": "guid",
"playlistUrl": "http://192.168.3.108/api/VideoStream/playback.m3u8?cid=xxx&start=...",
"recordCount": 12,
"totalDuration": 36000
}
}
```
#### 6.1.3 云台控制
```
POST /api/VideoStream/PtzControl
Authorization: Bearer <Vol.Pro JWT Token>
Request:
{
"channelId": "guid",
"action": "continuous", // continuous / stop
"direction": "up", // up / down / left / right / zoom_in / zoom_out
"speed": 0.5 // 0.0 ~ 1.0
}
Response:
{
"status": true,
"message": "ok"
}
```
#### 6.1.4 获取快照
```
GET /api/VideoStream/GetSnapshot?channelId=guid
Authorization: Bearer <Vol.Pro JWT Token>
Response: image/jpeg (二进制图片数据)
```
### 6.2 Owl内部接口Vol.Pro后端调用不暴露给前端
| 接口 | 说明 | 用途 |
|------|------|------|
| `GET /devices` | 设备列表 | 同步设备 |
| `GET /channels` | 通道列表 | 同步通道 |
| `POST /channels/:id/play` | 获取流地址 | 取流 |
| `POST /channels/:id/stop` | 停止播放 | 停止 |
| `POST /channels/:id/ptz/control` | 云台控制 | PTZ |
| `GET /recordings?cid=xxx` | 录像查询 | 回放 |
| `GET /channels/:id/snapshot` | 获取快照 | 截图 |
---
## 七、实施计划
> **所有代码均写在独立文件中,不修改任何框架自动生成的代码。框架升级时只需重新运行代码生成器,自定义业务完全保留。**
### 阶段一数据库与代码生成2天
1. 执行建表SQL创建4张表`Base_Device``Device_Video_Ext``Video_Channel``Video_Record`
2. 使用Vol.Pro代码生成器生成4个模块的CRUD代码实体、Service、Controller、前端页面
3. 验证生成后的增删改查功能正常
4. **验证**:确认`Partial/``extension/`目录未被覆盖
### 阶段二Owl对接服务3天
**新建文件(完全不触碰框架代码)**
1. 创建 `Warehouse/Services/Owl/IOwlApiService.cs`(接口)
2. 创建 `Warehouse/Services/Owl/OwlApiService.cs`(实现)
3. 实现JWT Token获取与缓存内存/Redis
4. 实现设备/通道同步逻辑调用Owl `/devices``/channels`
5. 实现取流、回放、云台、快照接口
6. 创建 `Warehouse/Controllers/VideoStreamController.cs`全新Controller
7. 添加Quartz定时同步任务写在`Partial`中扩展或新建Job
### 阶段三管理端前端扩展2天
**扩展文件(不修改生成的.vue/options.js**
1. 引入Jessibuca播放器组件npm install全局注册
2. 创建 `web.vite/src/extension/warehouse/Base_Device.jsx`扩展设备列表页添加DeviceCategory=1筛选
3. 创建 `web.vite/src/extension/warehouse/Video_Channel.jsx`(扩展通道列表页)
4. 创建 `web.vite/src/views/video/VideoPlayer.vue`(视频播放弹窗,全新文件)
5. 创建 `web.vite/src/views/video/VideoPlayback.vue`(回放查询页面,全新文件)
### 阶段四warehouse用户端改造3天
**修改warehouse自有代码与Vol.Pro框架无关**
1. 修改 `warehouse/src/view/video/Live.vue`替换模拟数据为真实API调用集成Jessibuca播放器
2. 修改 `warehouse/src/view/video/History.vue`实现回放查询和HLS播放
3. 修改 `warehouse/src/view/video/VideoWall.vue`:将图片占位符替换为真实视频播放器实例
4. 对接云台控制API调用Vol.Pro后端的`/api/VideoStream/PtzControl`
### 阶段五联调测试2天
1. 设备注册到Owl后同步到Vol.Pro
2. 实时播放测试WebRTC/FLV
3. 回放功能测试
4. 云台控制测试
5. 多路视频墙测试
6. **框架升级测试**:重新运行代码生成器,验证所有自定义代码未被覆盖
**总计预计工期**: 15个工作日含3天联调缓冲
### 代码独立性检查清单
实施过程中每完成一个模块,对照以下清单确认无框架代码被修改:
| 检查项 | 通过标准 |
|--------|----------|
| Controller扩展 | 新增接口写在`Partial/`或全新Controller文件中 |
| Service扩展 | 业务逻辑写在`Services/模块/Partial/`中 |
| Entity扩展 | 新增字段写在`DomainModels/模块/partial/`中,加`[NotMapped]` |
| 前端扩展 | 自定义逻辑写在`extension/`目录下的`.jsx``.vue`中 |
| 独立服务 | `OwlApiService`等新建服务实现`IDependency`,不修改框架文件 |
| 配置修改 | 仅在`appsettings.json`中添加Owl相关配置不修改框架其他配置 |
---
## 八、风险与注意事项
### 8.1 已知限制
1. **Owl云台控制不完整**: 仅支持 `continuous``stop`,预置位/绝对位置未实现
2. **GB28181首次播放延迟**: SIP信令协商需要1-3秒首次播放有延迟
3. **WebRTC兼容性**: 旧版浏览器不支持WebRTC必须准备FLV备用方案
4. **HLS回放延迟**: HLS切片默认2秒端到端延迟约5-10秒不适合实时监控
### 8.2 安全建议
1. Owl的JWT Token3天有效期需要安全存储建议用Redis缓存
2. 播放地址应通过Vol.Pro后端代理不要暴露Owl直连地址给前端
3. ZLMediaKit的 `secret` 在生产环境必须修改
4. 云台控制接口需要权限校验Vol.Pro的 `[ApiActionPermission]`
### 8.3 性能建议
1. 视频墙多路播放时建议限制同时播放路数如最大16路
2. 使用 `stop` 接口及时释放不再观看的流,减少服务器压力
3. 快照图片可做CDN缓存
4. 录像查询建议分页,避免大时间范围查询
---
## 附录A统一设备管理与三维地图标记
### A.1 统一设备管理设计
本方案与MC4.0采集网关方案共用 **`Base_Device` 统一设备主表**,实现视频监控设备和采集网关设备的统一管理:
| 设备大类 (DeviceCategory) | 细分类型 (DeviceType) | 扩展表 | 对接系统 |
|--------------------------|----------------------|--------|----------|
| 1 = 视频监控 | 1=IPC, 2=NVR, 3=Platform | `Device_Video_Ext` | Owl + ZLMediaKit |
| 2 = 采集网关 | 1=区域, 2=设备 | `Device_IoT_Ext` | MC4.0 采集网关 |
**原 `Video_Device` 表已拆分为**
- `Base_Device`公共字段设备名称、IP、位置、经纬度、MapModelId等
- `Device_Video_Ext`视频特有字段OwlDeviceId、Protocol、ChannelCount等
### A.2 三维地图标记 (VgoMap)
所有设备通过 `Base_Device` 表中的 `MapModelId` 字段,在 warehouse 前端的 VgoMap 三维地图上进行统一标记。
| 字段 | 类型 | 说明 |
|------|------|------|
| **MapModelId** | nvarchar(100) | 三维地图模型唯一标识 |
| **MapModelScale** | float | 模型缩放比例 |
| **MapModelRotation** | nvarchar(100) | 模型旋转角度JSON |
**前端集成要点**
```typescript
// 加载所有设备到三维地图
const devices = await http.post('/api/Base_Device/GetPageData', { ... });
devices.forEach(d => {
if (d.MapModelId) {
window.$map.setModelData(d.MapModelId, {
deviceId: d.DeviceId,
deviceName: d.DeviceName,
isOnline: d.IsOnline
});
window.$map.setModelColor(d.MapModelId,
d.IsOnline === 1 ? '#67c23a' : '#f56c6c');
}
});
```
详见《Vol.Pro_MC4.0_整合方案_v1.0.md》附录A.2完整说明。
---
> **文档结束**
> **版本**: v1.0
> **最后更新**: 2026-04-29
> **状态**: 待主人确认后实施

View File

@@ -0,0 +1,314 @@
# Vol.Pro 整合项目实施方案
> **版本**: v1.0
> **日期**: 2026-04-29
> **编制**: 浮浮酱
> **状态**: 待实施
---
## 一、项目概述
本项目包含两个子方案:
1. **视频监控方案**: Vol.Pro + Owl + ZLMediaKit浏览器实时监控、回放、云台控制
2. **采集网关方案**: Vol.Pro + MC4.0(设备管理、实时数据、反向控制、告警)
两个方案共用 **`Base_Device` 统一设备主表**,实现所有设备的集中管理和三维地图标记。
---
## 二、实施前提条件
### 2.1 环境准备(实施前必须完成)
| # | 检查项 | 通过标准 |
|---|--------|----------|
| 1 | Owl + ZLMediaKit 部署 | Docker运行正常Web管理端可访问 |
| 2 | MC4.0 采集网关接入 | 设备已接入MC4.0API可调用 |
| 3 | Vol.Pro 开发环境 | api_sqlsugar/web.vite/warehouse 均可编译运行 |
| 4 | 数据库权限 | 可执行建表SQL代码生成器可用 |
| 5 | 三维地图模型 | VgoMap中已为设备位置放置模型并记录MapModelId |
### 2.2 必须确认的技术点实施Day 1前完成
| # | 确认项 | 确认方式 | 影响 |
|---|--------|----------|------|
| 1 | Owl API完整路径 | 访问Owl Swagger文档 | 所有Owl对接接口 |
| 2 | ZLM播放地址格式 | 调用Owl play接口查看返回URL | 前端播放器配置 |
| 3 | MC4.0 Token机制 | 实测登录接口确认Header和有效期 | MC4.0所有接口 |
| 4 | MC4.0接口频率限制 | 高频调用测试是否限流 | 轮询任务设计 |
---
## 三、实施策略
### 3.1 分阶段实施
```
Phase 1: 视频监控方案15个工作日
├─ 优先实施,技术成熟度更高
├─ 不依赖MC4.0方案
└─ 验证Vol.Pro扩展机制的可行性
Phase 2: 采集网关方案16个工作日
├─ 在视频监控方案完成后实施
├─ 可复用Phase 1积累的Vol.Pro扩展经验
└─ 共用Base_Device主表Phase 1已创建
```
### 3.2 实施顺序
| 顺序 | 方案 | 工期 | 前置依赖 |
|------|------|------|----------|
| 1 | 视频监控方案 | 15天 | 无 |
| 2 | 采集网关方案 | 16天 | 视频监控方案完成复用Base_Device表 |
| **合计** | | **31天** | |
> **可并行优化**:如果人手充足,采集网关方案可在视频监控方案的阶段四/五时并行启动,总工期可缩短至 **20-22天**。
---
## 四、视频监控方案实施计划15天
### Week 1: 基础搭建Day 1-5
#### Day 1: 数据库与代码生成
- [ ] 执行建表SQL创建4张表`Base_Device``Device_Video_Ext``Video_Channel``Video_Record`
- [ ] 使用Vol.Pro代码生成器生成4个模块的CRUD代码
- [ ] 验证生成后的增删改查功能正常
- [ ] **验收点**: 管理端可正常增删改查设备/通道/录像
#### Day 2: Owl对接服务搭建
- [ ] 创建 `Warehouse/Services/Owl/IOwlApiService.cs`
- [ ] 创建 `Warehouse/Services/Owl/OwlApiService.cs`
- [ ] 实现JWT Token获取与缓存内存/Redis
- [ ] **验收点**: 可成功获取Owl Token并缓存
#### Day 3: Owl设备同步
- [ ] 实现设备同步逻辑调用Owl `/devices`
- [ ] 实现通道同步逻辑调用Owl `/channels`
- [ ] 实现数据写入Base_Device + Device_Video_Ext + Video_Channel
- [ ] **验收点**: 执行同步后Vol.Pro数据库中有Owl设备数据
#### Day 4: 取流与回放接口
- [ ] 实现 `GetLiveUrl` 接口调用Owl play
- [ ] 实现 `GetPlaybackUrl` 接口调用Owl recordings
- [ ] 实现 `StopPlay` 接口
- [ ] **验收点**: Postman可调用获取流地址
#### Day 5: 云台与快照接口
- [ ] 实现 `PtzControl` 接口
- [ ] 实现 `GetSnapshot` 接口
- [ ] 创建 `VideoStreamController.cs`
- [ ] **验收点**: Postman可调用云台控制和获取快照
### Week 2: 前端与管理端Day 6-10
#### Day 6: 管理端设备列表扩展
- [ ] 创建 `extension/warehouse/Base_Device.jsx`
- [ ] 添加"同步设备"按钮
- [ ] 添加DeviceCategory=1筛选默认显示视频监控设备
- [ ] 添加"查看通道"操作列
- [ ] **验收点**: 管理端设备列表有同步按钮和通道查看
#### Day 7: 管理端通道列表扩展
- [ ] 创建 `extension/warehouse/Video_Channel.jsx`
- [ ] 添加"实时预览"按钮(弹窗播放)
- [ ] 添加"云台控制"按钮
- [ ] 添加"回放"按钮
- [ ] **验收点**: 管理端通道列表可播放视频
#### Day 8: 播放器集成
- [ ] 引入Jessibuca/mpegts.js播放器组件
- [ ] 创建 `VideoPlayer.vue`(实时播放弹窗)
- [ ] 创建 `VideoPlayback.vue`(回放查询页面)
- [ ] **验收点**: 浏览器可播放实时视频和回放
#### Day 9: warehouse用户端改造 - Live.vue
- [ ] 替换硬编码数据为真实API调用
- [ ] 集成Jessibuca播放器
- [ ] 摄像头列表从Video_Channel API获取
- [ ] **验收点**: warehouse Live.vue可播放实时视频
#### Day 10: warehouse用户端改造 - History.vue + VideoWall.vue
- [ ] 改造History.vue实现回放查询和HLS播放
- [ ] 改造VideoWall.vue图片→真实播放器
- [ ] 对接云台控制API
- [ ] **验收点**: 回放和视频墙功能正常
### Week 3: 联调与优化Day 11-15
#### Day 11-12: 联调测试
- [ ] 设备注册到Owl后同步到Vol.Pro
- [ ] 实时播放测试WebRTC/FLV
- [ ] 回放功能测试
- [ ] 云台控制测试
- [ ] 多路视频墙测试
- [ ] **验收点**: 所有功能端到端可用
#### Day 13: 框架升级测试
- [ ] 重新运行代码生成器
- [ ] 验证所有自定义代码Partial/extension未被覆盖
- [ ] **验收点**: 代码生成器不覆盖自定义代码
#### Day 14-15: 缓冲优化
- [ ] 性能优化(视频墙路数限制、流释放)
- [ ] 安全加固(播放地址代理、权限校验)
- [ ] 文档补充
---
## 五、采集网关方案实施计划16天
### Week 1: 基础搭建Day 1-5
#### Day 1: 数据库与代码生成
- [ ] 执行建表SQL`Device_IoT_Ext``IoT_DevicePoint``IoT_DeviceData``IoT_Alarm`
- [ ] 使用Vol.Pro代码生成器生成CRUD代码
- [ ] **注意**: Base_Device表已在视频监控方案中创建无需重复创建
- [ ] **验收点**: 管理端可正常增删改查
#### Day 2: MC4.0对接服务搭建
- [ ] 创建 `IMc4ApiService.cs` / `Mc4ApiService.cs`
- [ ] 实现Token管理登录/缓存/刷新)
- [ ] 实现请求频率控制SemaphoreSlim每秒最多2次
- [ ] **验收点**: 可成功获取MC4.0 Token
#### Day 3: 对象树与点表同步
- [ ] 实现对象树同步(`/object/tree`
- [ ] 实现点表同步(`/device/point/get`
- [ ] 数据写入Base_Device + Device_IoT_Ext + IoT_DevicePoint
- [ ] **验收点**: 执行同步后Vol.Pro中有MC4.0设备数据
#### Day 4: 实时数据与控制接口
- [ ] 实现 `GetRealtime` 接口调用MC4.0读数据)
- [ ] 实现 `Control` 接口(反向控制)
- [ ] **验收点**: Postman可读取实时数据和控制设备
#### Day 5: 告警接口
- [ ] 实现 `GetAlarms` 接口
- [ ] 实现 `ConfirmAlarm` / `EndAlarm` 接口
- [ ] 创建 `IoTStreamController.cs`
- [ ] **验收点**: Postman可查询和确认告警
### Week 2: 实时推送与管理端Day 6-10
#### Day 6: SignalR Hub搭建
- [ ] 创建 `IoTDataHub.cs`
- [ ] 实现设备分组订阅SubscribeDevice/UnsubscribeDevice
- [ ] 实现告警管理员组订阅SubscribeAlarmAdmin
- [ ] **验收点**: 前端可连接SignalR并订阅设备
#### Day 7: 实时数据轮询Job
- [ ] 创建 `RealtimeDataPollJob.cs`
- [ ] 每5秒轮询MC4.0实时数据
- [ ] **不入库直接SignalR推送给前端**
- [ ] **验收点**: 前端实时收到数据更新
#### Day 8: 告警轮询Job
- [ ] 创建 `AlarmPollJob.cs`
- [ ] 每10秒轮询MC4.0告警
- [ ] 新告警写入IoT_Alarm表
- [ ] 按设备分组SignalR推送
- [ ] **验收点**: 新告警实时推送到前端
#### Day 9: 管理端设备列表扩展
- [ ] 扩展 `Base_Device.jsx`(添加采集设备相关按钮)
- [ ] 添加"同步对象树"按钮仅DeviceCategory=2显示
- [ ] 添加"同步点表"操作列
- [ ] 添加"查看实时数据"按钮
- [ ] **验收点**: 管理端可同步和查看采集设备
#### Day 10: 管理端告警列表扩展
- [ ] 扩展告警列表页
- [ ] 添加"确认"和"结束"操作按钮
- [ ] 告警等级颜色标识(紧急=红色,重要=橙色)
- [ ] **验收点**: 管理端可处理告警
### Week 3: warehouse用户端与联调Day 11-16
#### Day 11-12: warehouse用户端开发
- [ ] 开发实时数据看板(设备列表+实时数值+SignalR接收
- [ ] 开发设备控制面板(开关/滑块/输入框)
- [ ] 开发告警信息面板(实时告警+历史查询)
- [ ] **验收点**: warehouse可查看实时数据和控制设备
#### Day 13-14: 联调测试
- [ ] MC4.0设备接入测试
- [ ] 实时数据读取测试验证SignalR推送不入库
- [ ] 反向控制测试
- [ ] 告警轮询与推送测试10秒轮询+分组推送)
- [ ] 请求频率控制测试每秒不超过2次
- [ ] 多设备并发测试
- [ ] **验收点**: 所有功能端到端可用
#### Day 15: 框架升级测试
- [ ] 重新运行代码生成器
- [ ] 验证自定义代码未被覆盖
- [ ] **验收点**: 代码独立性验证通过
#### Day 16: 缓冲优化
- [ ] 性能优化
- [ ] 文档补充
- [ ] 问题修复
---
## 六、关键里程碑与验收标准
| 里程碑 | 时间 | 验收标准 |
|--------|------|----------|
| M1: 视频监控后端完成 | Day 5 | Owl对接服务所有接口Postman测试通过 |
| M2: 视频监控前端完成 | Day 10 | warehouse Live/History/VideoWall功能可用 |
| M3: 视频监控联调完成 | Day 15 | 所有功能端到端可用,框架升级测试通过 |
| M4: 采集网关后端完成 | Day 5 | MC4.0对接服务所有接口Postman测试通过 |
| M5: 采集网关前端完成 | Day 12 | warehouse实时数据/控制/告警功能可用 |
| M6: 采集网关联调完成 | Day 16 | 所有功能端到端可用,框架升级测试通过 |
---
## 七、风险控制
| 风险 | 影响 | 应对措施 |
|------|------|----------|
| Owl API路径不准确 | 所有取流/云台接口404 | Day 1实测Swagger确认路径 |
| MC4.0 Token快速过期 | 频繁重新登录 | Day 1实测Token有效期设计自动刷新 |
| ZLM WebRTC配置失败 | 无法使用WebRTC | 默认使用WS-FLVWebRTC作为可选优化 |
| MC4.0接口限流 | 轮询任务失败 | SemaphoreSlim频率控制失败时告警 |
| 数据量爆炸 | SQL Server性能下降 | 实时数据不入库仅SignalR推送 |
| 前端播放器兼容性 | 部分浏览器无法播放 | 提供FLV/HLS多协议降级 |
---
## 八、实施检查清单
### 每日检查项
- [ ] 今日代码是否写在独立文件(不修改框架代码)
- [ ] 新服务是否实现IDependency接口
- [ ] Controller是否使用partial或全新文件
- [ ] 前端扩展是否写在extension目录
### 阶段验收检查项
- [ ] 重新运行代码生成器,确认自定义代码未被覆盖
- [ ] 所有API接口Postman测试通过
- [ ] 前端功能在Chrome/Firefox/Edge测试通过
- [ ] 性能测试视频墙最大路数、MC4.0轮询频率)
---
## 九、相关文档索引
| 文档 | 路径 | 说明 |
|------|------|------|
| 视频监控整合方案 | `doc/整合方案/Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0.md` | 详细技术方案 |
| 采集网关整合方案 | `doc/整合方案/Vol.Pro_MC4.0_整合方案_v1.0.md` | 详细技术方案 |
| MC4.0 API文档 | `doc/对接文档/MC4.0对外API.md` | MC4.0接口定义 |
| 联网部署手册 | `owl_zlmediakit/联网部署手册.md` | Owl+ZLM部署指南 |
| 超时排查手册 | `owl_zlmediakit/排查手册-访问超时.md` | 网络问题排查 |
---
> **文档结束**
> **版本**: v1.0
> **最后更新**: 2026-04-29
> **状态**: 待主人确认后实施

View File

@@ -0,0 +1,183 @@
# Vol.Pro 统一设备管理:区域树 + 设备层级 + 地图绑定方案
> **版本**: v1.0
> **日期**: 2026-05-15
> **状态**: 待确认
> **前置方案**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、IntegrationGateway 方案 A
---
## 一、需求定义
### 1.1 管理端呈现目标
在 web.vite 实现统一设备管理界面,形态为左侧区域树 + 右侧设备列表的左右分栏布局。
```
┌──────────────────┬───────────────────────────────────────┐
│ 左侧:区域树 │ 右侧:设备列表(选中区域下的设备) │
│ │ │
│ 📁 厂区 │ ┌ 东北角高位摄像机 █在线 操作↓ ┐ │
│ 📁 新库区 │ ├ 人员计数摄像机 █在线 操作↓ ┤ │
│ 📁 31号库房 ← 选中 ├ 动环采集器 █在线 [展开▸] ┤ │
│ │ │ ├ 温湿度探头 26.5℃ █在线 ┤ │
│ │ │ ├ 空调控制器 制冷 █在线 ┤ │
│ │ │ ├ 除湿机 关闭 █在线 ┤ │
│ │ │ └ 紧急报警按钮 正常 █在线 ┤ │
│ │ └ 电表监测 235V █在线 ┤ │
└──────────────────┴───────────────────────────────────────┘
```
### 1.2 核心需求
1. **多级区域树**:利用现有 `warehouse_regions` 表(已有 `Id/RegionName/ParentId`
2. **设备绑定区域**:每个设备通过 `RegionId` 归属到叶子区域
3. **设备父子层级**:采集网关作为父设备,探头/控制器作为子设备展开
4. **地图模型绑定**:每个设备 `MapModelId` 字段供 warehouse 三维地图标记
5. **不同设备不同操作**:视频设备显示播放/云台按钮IoT 设备显示实时值/控制
---
## 二、数据模型设计
### 2.1 区域表 `warehouse_regions`(现有,不变)
| 字段 | 类型 | 说明 |
|------|------|------|
| Id | int (PK) | 区域ID |
| RegionName | nvarchar(255) | 区域名称 |
| ParentId | int? | 父级区域ID自引用树 |
### 2.2 统一设备主表 `Base_Device`(修订后新增字段)
| 字段 | 类型 | 说明 |
|------|------|------|
| AdapterCode | nvarchar(50) | 来源适配器owl/mc4/hikvision_access |
| SourceId | nvarchar(100) | 源系统设备ID |
| IsParent | bit | 是否父设备0=叶子, 1=可展开(采集器/NVR |
| ParentDeviceId | uniqueidentifier? | 父设备ID自引用 |
| **RegionId** | int? | 所属叶子区域IDFK→warehouse_regions.Id |
| **MapModelId** | nvarchar(100) | 三维地图模型ID |
| MapModelScale | float | 模型缩放比例 |
| MapModelRotation | nvarchar(100) | 旋转角度JSON |
| ExtraData | nvarchar(max) | 源系统原始数据JSON |
| LocalOverrides | nvarchar(max) | 本地覆盖字段JSON |
| SyncVersion | bigint | 乐观锁版本号 |
| LastSyncTime | datetime | 上次同步时间 |
### 2.3 层级关系示例
```
warehouse_regions:
Id=1, RegionName="厂区", ParentId=null
Id=2, RegionName="新库区", ParentId=1
Id=3, RegionName="31号库房", ParentId=2
Base_Device:
DeviceId=A, RegionId=3, IsParent=0 → 东北角高位摄像机
DeviceId=B, RegionId=3, IsParent=0 → 人员计数摄像机
DeviceId=C, RegionId=3, IsParent=1 → 动环采集器(父设备)
DeviceId=D, RegionId=3, ParentDeviceId=C → 温湿度探头
DeviceId=E, RegionId=3, ParentDeviceId=C → 空调控制器
DeviceId=F, RegionId=3, ParentDeviceId=C → 除湿机
```
---
## 三、MC4.0 同步到区域树
MC4.0 对象树中 `type=1`(区域节点)→ 与 `warehouse_regions` 名称匹配后自动绑区。`type=2`(设备节点)→ 写入 `Base_Device``RegionId` 设为所属叶子区域。
**关键决策**Vol.Pro 区域不由 MC4.0 全量控制。管理员可手动创建区域同步不覆盖。Owl 设备无区域概念,同步后 `RegionId=NULL`,由管理员手动分配。
---
## 四、前端实现方案
### 4.1 文件结构
```
web.vite/src/views/warehouse/
└── DeviceManager/ ★ 新建目录
├── index.vue # 主页面(左树右表)
├── components/
│ ├── RegionTree.vue # el-tree 区域树
│ ├── DeviceTable.vue # el-table 可展开设备列表
│ ├── DeviceEditDialog.vue # 编辑弹出框
│ ├── MapBindingPanel.vue # 地图模型绑定面板
│ ├── VideoDeviceActions.vue
│ ├── IoTDeviceActions.vue
│ └── DeviceSyncToolbar.vue
└── api/deviceManager.js
web.vite/src/router/index.js # 新增 /device-manager 路由
```
### 4.2 关键组件逻辑
**RegionTree.vue** — el-tree 加载 `/api/DeviceManager/GetRegionTree`,每个节点显示设备数量徽标。
**DeviceTable.vue** — el-table 使用 `tree-props="{ children: 'subDevices', hasChildren: 'IsParent' }"` 实现可展开行。操作列按 `DeviceCategory` 分发不同按钮组件。
**MapBindingPanel.vue** — 编辑弹出框的一个 Tab含 MapModelId 下拉选择、缩放/旋转输入、经纬度输入。
### 4.3 与生成页面关系
`Base_Device` 的标准 CRUD 生成页面保留作为兜底(数据批量维护)。在其 extension 中加跳转按钮:
```jsx
// extension/warehouse/Base_Device/Base_Device.jsx
onInit() {
this.buttons.unshift({
name: '设备管理',
icon: 'el-icon-s-grid',
type: 'primary',
onClick: () => this.$router.push('/device-manager')
});
}
```
---
## 五、后端 API
| 接口 | 说明 |
|------|------|
| GET `/api/DeviceManager/GetRegionTree` | 区域树(含设备数量) |
| GET `/api/DeviceManager/GetDevicesByRegion?regionId=3` | 区域下设备列表(含子设备) |
| PUT `/api/DeviceManager/{deviceId}` | 更新设备(含地图绑定字段) |
Controller 写在 `Controllers/Warehouse/Partial/DeviceManagerController.cs`(扩展目录,不被代码生成器覆盖)。
---
## 六、操作按钮矩阵
| DeviceCategory | 操作按钮 |
|---------------|----------|
| 1-视频监控 | 实时预览、云台控制、查看回放、获取快照、同步通道 |
| 2-IoT采集 | 查看实时数据、设备控制、刷新点位、查看告警 |
| 3-门禁 | 远程开门、查看记录、查看告警 |
| 4-道闸 | 抬杆、落杆、查看记录 |
| 5-报警 | 查看告警、布防/撤防 |
父设备IsParent=1额外显示展开/收起子设备。
---
## 七、实施变更汇总
| 层级 | 变更项 | 复杂度 |
|------|--------|--------|
| 数据库 | Base_Device 新增8个字段 | 中 |
| 后端 | DeviceManagerController 新建 | 中 |
| 后端 | SyncEngine 区域匹配逻辑 | 高 |
| 前端 | 6个新Vue组件 + 路由 | 高 |
| Gateway | Mc4Adapter 对象树区域提取 | 中 |
**预计工期**5-7 个工作日前后端各2-3天联调1天
---
> **文档结束**
> **关联**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、Vol.Pro_整合项目_实施方案_v1.0