Initial_commit_SecMPS_v2
This commit is contained in:
290
doc/整合方案/SecMPS_整合项目实施手册_v2.0.md
Normal file
290
doc/整合方案/SecMPS_整合项目实施手册_v2.0.md
Normal 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张)**
|
||||
|
||||
按顺序执行 DDL:Base_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 — SyncDevicesJob(Quartz)**
|
||||
|
||||
```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 1:Owl 适配器 + 视频设备页(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 2:MC4.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.ProcessTreeNode:type=1 节点 → MatchOrCreateRegion,type=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 3:warehouse 端 + 全链路联调(Day 12-17)
|
||||
|
||||
### Day 12-13 — 视频播放器集成
|
||||
|
||||
- Live.vue: 假数据→真实 API + Jessibuca
|
||||
- History.vue: 对接回放 API,HLS 播放
|
||||
- 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路视频墙≥15fps,100设备轮询<3s,500设备同步<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 |
|
||||
|
||||
---
|
||||
|
||||
> **文档结束**
|
||||
309
doc/整合方案/SecMPS_整合项目实施手册_v2.1.md
Normal file
309
doc/整合方案/SecMPS_整合项目实施手册_v2.1.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# SecMPS 整合项目实施手册
|
||||
|
||||
> **版本**: v2.1
|
||||
> **日期**: 2026-05-15
|
||||
> **基于**: SecMPS_最终整合方案_v2.0.md
|
||||
> **工期**: 18-20 个工作日
|
||||
> **开发模式**: 单人 + Agent,Squash 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 1:Owl 适配器 + 视频设备页(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 2:MC4.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 3:warehouse 端 + 全链路联调(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
|
||||
296
doc/整合方案/SecMPS_最终整合方案_v2.0.md
Normal file
296
doc/整合方案/SecMPS_最终整合方案_v2.0.md
Normal 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
|
||||
1163
doc/整合方案/Vol.Pro_MC4.0_整合方案_v1.0.md
Normal file
1163
doc/整合方案/Vol.Pro_MC4.0_整合方案_v1.0.md
Normal file
File diff suppressed because it is too large
Load Diff
878
doc/整合方案/Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0.md
Normal file
878
doc/整合方案/Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0.md
Normal 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) | ✅ | 源系统设备ID(OwlDeviceId或Mc4DeviceId) |
|
||||
| IpAddress | nvarchar(50) | | IP地址 |
|
||||
| Port | int | | 端口 |
|
||||
| IsOnline | int | | 是否在线:0=离线, 1=在线 |
|
||||
| Location | nvarchar(200) | | 安装位置描述 |
|
||||
| Lat | float | | 纬度(WGS84坐标系) |
|
||||
| Lng | float | | 经度(WGS84坐标系) |
|
||||
| **MapModelId** | **nvarchar(100)** | | **三维地图模型ID(VgoMap中对应模型的唯一标识)** |
|
||||
| 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系统设备ID(GB28181的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, -- 源系统设备ID(OwlDeviceId或Mc4DeviceId)
|
||||
IpAddress NVARCHAR(50),
|
||||
Port INT,
|
||||
IsOnline INT DEFAULT 0,
|
||||
Location NVARCHAR(200), -- 安装位置描述
|
||||
Lat FLOAT, -- 纬度
|
||||
Lng FLOAT, -- 经度
|
||||
MapModelId NVARCHAR(100), -- 三维地图模型ID(VgoMap)
|
||||
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设备直接注册到Owl),Vol.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/WebRTC,wasm解码
|
||||
- [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 Token(3天有效期)需要安全存储,建议用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
|
||||
> **状态**: 待主人确认后实施
|
||||
314
doc/整合方案/Vol.Pro_整合项目_实施方案_v1.0.md
Normal file
314
doc/整合方案/Vol.Pro_整合项目_实施方案_v1.0.md
Normal 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.0,API可调用 |
|
||||
| 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-FLV,WebRTC作为可选优化 |
|
||||
| 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
|
||||
> **状态**: 待主人确认后实施
|
||||
183
doc/整合方案/Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0.md
Normal file
183
doc/整合方案/Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0.md
Normal 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? | 所属叶子区域ID(FK→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
|
||||
Reference in New Issue
Block a user