v2.0_final_synced_with_db_and_gateway

This commit is contained in:
2026-05-16 10:45:20 +08:00
parent 7c69d9c55f
commit 906700e0fe

View File

@@ -1,9 +1,9 @@
# SecMPS 整合方案最终版IntegrationGateway + 统一设备管理 # SecMPS 整合方案最终版IntegrationGateway + 统一设备管理
> **版本**: v2.0 > **版本**: v2.0
> **日期**: 2026-05-15 > **日期**: 2026-05-16
> **状态**: 待实施 > **状态**: 待实施
> **替代**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0 > **替代**: v1.0 系列方案文档
--- ---
@@ -11,49 +11,88 @@
``` ```
前端层 前端层
web.vite 管理端(设备管理页+标准CRUD warehouse 大屏Map/Live/IoT/Alarm web.vite 管理端(设备管理+网关管理 warehouse 大屏Map/Live/IoT/Alarm
HTTP REST HTTP REST + SignalR | HTTP REST | HTTP REST + SignalR
v v
Vol.Pro 后端 (api_sqlsugar) Vol.Pro 后端 (api_sqlsugar)
DeviceManagerController / GatewayClient / SignalR Hubs DeviceManagerController / GatewayNodeController / SignalR Hubs
Quartz: SyncDevicesJob / RealtimePollJob / AlarmPollJob Quartz: SyncDevicesJob / RealtimePollJob / AlarmPollJob
数据库: Base_Device / warehouse_regions / Device_Video_Ext / Device_IoT_Ext / IoT_DevicePoint / IoT_Alarm 数据库: 8 张表 (base_device / gateway_nodes / 扩展表...)
│ HTTP REST | 注册/下发设备/心跳/同步数据
v
IntegrationGateway (独立服务 :5100) IntegrationGateway 实例A (:5100) IntegrationGateway 实例B (:5101)
Adapters.Owl (IHasFlatDevices+IHasStreams+IAcceptsMetadataPush) NodeCode: gw-31ku NodeCode: gw-11ku
Adapters.MC4 (IHasOwnDeviceTree+IHasPoints+IHasAlarms) Adapters: MC4 / Owl Adapters: MC4 / HikvisionISC
Core: AdapterRegistry / SyncEngine / TokenManager / RateLimiter | HTTP | HTTP
│ HTTP │ HTTP v v
MC4.0 (:3000) Owl (:80) MC4.0 (:3000) 海康ISC (:80)
Owl + ZLMediaKit MC4.0 采集网关
Docker Compose HTTP API :3000
``` ```
### 网关多实例架构(方案 C+
- Vol.Pro 管理网关实例gateway_nodes 表注册所有网关节点
- 网关启动时主动注册POST /api/gateway/register 上报 NodeCode/Token/AdapterTypes/BaseUrl
- Vol.Pro 下发顶层设备Base_Device.GatewayNodeId 关联设备归属
- 网关无状态:配置只有 3 个值NodeCode/Token/VolProUrl挂了重装即恢复
- AdapterCode 双段标识:"mc4:31号库房" 区分同类型多实例
- 心跳机制:网关每 15s 上报心跳Vol.Pro 超 30s 无心跳级联设备离线
--- ---
## 二、IntegrationGateway 设计 ## 二、IntegrationGateway 设计
### 2.1 项目结构 ### 2.1 项目结构(位于 gateway/ 独立文件夹)
``` ```
IntegrationGateway/ gateway/
├── src/ ├── IntegrationGateway.sln
│ ├── Host/Controllers/ → Devices / Points / Streams / Alarms / Sync / Health └── src/
├── Core/Abstractions/ → 分型接口 ├── IntegrationGateway.Host/ # WebAPI (:5100)
├── IIntegrationAdapter | ├── Controllers/
├── IHasOwnDeviceTree (MC4.0) | | ├── HealthController.cs
├── IHasFlatDevices (Owl) | | ├── DevicesController.cs
├── IHasPoints (MC4.0) | | ├── PointsController.cs
├── IHasStreams (Owl) | | ├── StreamsController.cs
├── IHasAlarms (通用) | | ├── AlarmsController.cs
│ └── IAcceptsMetadataPush (Owl) | | ├── SyncController.cs
├── Core/Infrastructure/ → SyncEngine / AdapterRegistry / TokenManager / RateLimiter | | └── RegisterController.cs # 网关注册/心跳
├── Adapters.Owl/ → OwlAdapter | ├── appsettings.json # { NodeCode, Token, VolProUrl }
└── Adapters.MC4/ → Mc4Adapter | └── Program.cs
├── IntegrationGateway.Core/
| ├── Abstractions/ → 7 个分型接口
| ├── Models/ → 10 个标准化模型
| └── Infrastructure/ → AdapterRegistry / TokenManager / RateLimiter
├── IntegrationGateway.Adapters.Owl/
└── IntegrationGateway.Adapters.MC4/
``` ```
### 2.2 适配器能力矩阵 ### 2.2 网关注册与心跳流程
```
管理端: gateway_nodes 表新增记录 → 生成 NodeCode + Token
网关配置: appsettings.json { NodeCode, Token, VolProUrl }
网关启动 → POST /api/gateway/register { nodeCode,token,adapterTypes,baseUrl }
Vol.Pro 校验 Token → 更新 AdapterTypes/BaseUrl/IsOnline=1
响应: { gatewayNodeId, devices: [Base_Device WHERE GatewayNodeId=当前网关] }
网关根据 AdapterCode 分流 → Adapter 连接第三方 → 发现子设备
网关 → POST /api/gateway/sync → Vol.Pro 写入 Base_Device 及子设备
网关每 15s → POST /api/gateway/heartbeat { nodeCode, token }
Vol.Pro 后台任务: IsOnline=1 且 LastHeartbeat < now-30s → IsOnline=0 → 级联设备离线
```
### 2.3 网关配置
```json
{
"VolProBaseUrl": "http://localhost:9100",
"NodeCode": "gw-31ku",
"NodeToken": "xxxxxxxxxx"
}
```
适配器类型由网关启动时扫描已注册的 Adapter 类自动获取,无需在配置中声明。
### 2.4 适配器能力矩阵
| 接口 | Owl | MC4.0 | 门禁(未来) | | 接口 | Owl | MC4.0 | 门禁(未来) |
|------|:---:|:-----:|:----------:| |------|:---:|:-----:|:----------:|
@@ -64,7 +103,7 @@ IntegrationGateway/
| IHasAlarms | ⚠️ | ✅ | ✅ | | IHasAlarms | ⚠️ | ✅ | ✅ |
| IAcceptsMetadataPush | ✅ | ❌ | ⚠️ | | IAcceptsMetadataPush | ✅ | ❌ | ⚠️ |
### 2.3 双向同步引擎 ### 2.5 双向同步引擎
| 方向 | 说明 | MC4.0 | Owl | | 方向 | 说明 | MC4.0 | Owl |
|------|------|-------|-----| |------|------|-------|-----|
@@ -72,10 +111,14 @@ IntegrationGateway/
| PushToSource | Vol.Pro→第三方 | 告警确认/控制 | 元数据/PTZ | | PushToSource | Vol.Pro→第三方 | 告警确认/控制 | 元数据/PTZ |
| Bidirectional | 先写第三方再更新本地 | 告警确认 | — | | Bidirectional | 先写第三方再更新本地 | 告警确认 | — |
### 2.4 Gateway API ### 2.6 Gateway API
``` ```
GET /api/gateway/health # 注册与心跳
POST /api/gateway/register { nodeCode, token, adapterTypes, baseUrl }
POST /api/gateway/heartbeat { nodeCode, token }
# 设备与数据
GET /api/gateway/devices?adapter=&page=&size= GET /api/gateway/devices?adapter=&page=&size=
GET /api/gateway/devices/sync?adapter= GET /api/gateway/devices/sync?adapter=
GET /api/gateway/realtime/{adapter}/{deviceId} GET /api/gateway/realtime/{adapter}/{deviceId}
@@ -84,11 +127,12 @@ GET /api/gateway/streams/{adapter}/{id}/live
POST /api/gateway/streams/{adapter}/{id}/ptz POST /api/gateway/streams/{adapter}/{id}/ptz
GET /api/gateway/alarms/{adapter}?from=&to= GET /api/gateway/alarms/{adapter}?from=&to=
POST /api/gateway/alarms/{adapter}/{id}/confirm POST /api/gateway/alarms/{adapter}/{id}/confirm
GET /api/gateway/health
``` ```
--- ---
## 三、数据模型 ## 三、数据模型8 张表)
### 3.1 区域表 warehouse_regions现有 ### 3.1 区域表 warehouse_regions现有
@@ -98,51 +142,67 @@ POST /api/gateway/alarms/{adapter}/{id}/confirm
| RegionName | nvarchar(255) | | RegionName | nvarchar(255) |
| ParentId | int? (自引用树) | | ParentId | int? (自引用树) |
### 3.2 统一设备主表 Base_Device(新建) ### 3.2 网关节点表 gateway_nodes(新建)
| 字段 | 类型 | 说明 | | 字段 | 类型 | 说明 |
|------|------|------| |------|------|------|
| DeviceId | uniqueidentifier PK | Vol.Pro内部ID | | NodeId | INT AUTO_INCREMENT | 网关节点ID |
| DeviceName | nvarchar(100) | 本地名称 | | NodeCode | NVARCHAR(50) | 网关唯一编码(管理端配置) |
| **AdapterCode** | nvarchar(50) | owl/mc4/hikvision_access | | NodeName | NVARCHAR(100) | 网关名称 |
| **SourceId** | nvarchar(100) | 第三方原始ID | | NodeToken | NVARCHAR(100) | 认证令牌(管理端生成) |
| DeviceCategory | int | 1=视频 2=IoT 3=门禁 4=道闸 5=报警 | | AdapterTypes | NVARCHAR(200) | 适配器类型(网关上报) |
| DeviceType | nvarchar(50) | GB28181/TempSensor... | | BaseUrl | NVARCHAR(200) | 网关地址(网关上报) |
| **RegionId** | int? | FK→warehouse_regions.Id | | LastHeartbeat | DATETIME | 上次心跳时间 |
| **IsParent** | bit | 是否父设备 | | IsOnline | TINYINT DEFAULT 0 | 在线状态 |
| **ParentDeviceId** | uniqueidentifier? | 父设备自引用 | | Enable | TINYINT DEFAULT 1 | 启用 |
| IsOnline | int | 0/1 |
| **MapModelId** | nvarchar(100) | VgoMap模型ID | ### 3.3 统一设备主表 Base_Device
| MapModelScale | float | |
| MapModelRotation | nvarchar(100) | | | 字段 | 类型 | 说明 |
| Lat/Lng | float | WGS84 | |------|------|------|
| ExtraData | nvarchar(max) | 适配器原始JSON | | DeviceId | INT AUTO_INCREMENT | Vol.Pro内部ID |
| LocalOverrides | nvarchar(max) | 本地覆盖JSON | | DeviceName | NVARCHAR(100) | 本地名称 |
| SyncVersion | bigint | 乐观锁 | | AdapterCode | NVARCHAR(50) | "mc4:31号库房"(类型:实例) |
| LastSyncTime | datetime | | | SourceId | NVARCHAR(100) | 第三方原始ID |
| DeviceCategory | INT | 1=视频 2=IoT 3=门禁 4=道闸 5=报警 |
| RegionId | INT? | 所属区域ID |
| GatewayNodeId | INT? | 所属网关节点ID |
| IsParent | TINYINT | 是否父设备 |
| ParentDeviceId | INT? | 父设备自引用 |
| IsOnline | TINYINT | 在线状态 |
| MapModelId | NVARCHAR(100) | VgoMap模型ID |
| MapModelScale | FLOAT | |
| MapModelRotation | NVARCHAR(100) | |
| Lat/Lng | DOUBLE | WGS84 |
| ExtraData | TEXT | 适配器原始JSON |
| LocalOverrides | TEXT | 本地覆盖JSON |
| SyncVersion | BIGINT | 乐观锁 |
| LastSyncTime | DATETIME | |
唯一约束: (AdapterCode, SourceId) 唯一约束: (AdapterCode, SourceId)
### 3.3 扩展表 ### 3.4 扩展表
- **Device_Video_Ext**: 视频设备扩展OwlDeviceId, Protocol, ChannelCount - Device_Video_Ext: 视频设备扩展OwlDeviceId, Protocol, ChannelCount
- **Device_IoT_Ext**: IoT设备扩展Mc4DeviceId, ObjectType, Tag - Video_Channel: 视频通道扩展OwlChannelId, DeviceId, OwlStreamApp/Name, HasPtz, SnapshotUrl
- **Video_Channel**: 视频通道OwlChannelId, DeviceId, HasPtz - Video_Record: 录像记录ChannelId, OwlRecordId, StartedAt, FilePath
- **Video_Record**: 录像记录 - Device_IoT_Ext: IoT设备扩展Mc4DeviceId, PointIndex, Unit, IsControlPoint, ObjectType
- **IoT_DevicePoint**: 点位表PointIndex, PointName, Unit, IsControlPoint - IoT_DeviceData: 历史归档DeviceId→子设备, PointValue, 仅存快照
- **IoT_DeviceData**: 历史归档(仅存快照,实时不入库 - IoT_Alarm: 通用告警SourceAlarmId, DeviceId, AlarmLevel, State
- **IoT_Alarm**: 告警记录Mc4AlarmId, AlarmLevel, State
### 3.4 层级示例 ### 3.5 层级示例
``` ```
gateway_nodes: gw-31ku (32号库房网关, MC4+Owl)
warehouse_regions: 厂区 → 新库区 → 31号库房 warehouse_regions: 厂区 → 新库区 → 31号库房
Base_Device (RegionId=3):
东北角高位摄像机 (Category=1) Base_Device (RegionId=3, GatewayNodeId=gw-31ku.NodeId):
人员计数摄像机 (Category=1) 东北角高位摄像机 (Category=1, Device_Video_Ext)
动环采集器 (Category=2, IsParent=1) 人员计数摄像机 (Category=1, Device_Video_Ext)
├── 温湿度探头 (ParentDeviceId=采集器) 动环采集器 (Category=2, IsParent=1, Device_IoT_Ext)
├── 空调控制器 (ParentDeviceId=采集器) ├── 温湿度探头 (ParentDeviceId=采集器, Device_IoT_Ext.PointIndex=0)
├── 空调控制器 (ParentDeviceId=采集器, Device_IoT_Ext.IsControlPoint=1)
├── 除湿机 (ParentDeviceId=采集器) ├── 除湿机 (ParentDeviceId=采集器)
└── 紧急报警按钮 (ParentDeviceId=采集器) └── 紧急报警按钮 (ParentDeviceId=采集器)
``` ```
@@ -154,47 +214,43 @@ Base_Device (RegionId=3):
### 4.1 布局 ### 4.1 布局
``` ```
┌──────────────────┬───────────────────────────────────────┐ +------------------+---------------------------------------+
顶部工具栏 | 顶部工具栏 | |
├──────────────────┼───────────────────────────────────────┤ +------------------+---------------------------------------+
左侧区域树 右侧设备列表 | 左侧区域树 | 右侧设备列表 |
| | |
📁 厂区 区域:31号库房 最后同步:05-15 | 📁 厂区 | 区域:31号库房 最后同步:05-15 |
📁 新库区 ┌──────────────────────────────┐ │ | 📁 新库区 | +---------------------------------+ |
📁 31号库房 ● ▸动环采集器 MC4.0 █在线 │ │ | 📁 31号库房 ● | | ▸动环采集器 MC4.0 █在线 | |
📁 11号库房 东北角摄像机 Owl █在线 │ │ | 📁 11号库房 | | 东北角摄像机 Owl █在线 | |
└──────────────────────────────┘ │ | | +---------------------------------+ |
[+新建区域] | [+新建区域] | |
└──────────────────┴───────────────────────────────────────┘ +------------------+---------------------------------------+
``` ```
### 4.2 前端文件 ### 4.2 前端文件
``` ```
web.vite/src/views/warehouse/DeviceManager/ web.vite/src/views/warehouse/DeviceManager/
├── index.vue # 主页面(左树右表) ├── index.vue # 主页面
├── components/ ├── components/
│ ├── RegionTree.vue # el-tree 区域树 │ ├── RegionTree.vue # el-tree 区域树
│ ├── DeviceTable.vue # el-table 可展开行 │ ├── DeviceTable.vue # el-table 可展开行
│ ├── DeviceEditDialog.vue # 编辑弹框 │ ├── DeviceEditDialog.vue # 编辑弹框
│ ├── MapBindingPanel.vue # 地图绑定面板 │ ├── MapBindingPanel.vue # 地图绑定面板
│ ├── VideoDeviceActions.vue # 视频操作按钮组 │ ├── VideoDeviceActions.vue # 视频按钮组
│ └── IoTDeviceActions.vue # IoT操作按钮组 │ └── IoTDeviceActions.vue # IoT按钮组
└── api/deviceManager.js └── api/deviceManager.js
路由: /device-manager
``` ```
### 4.3 后端 API ### 4.3 后端 API
| 接口 | 说明 | | 接口 | 说明 |
|------|------| |------|------|
| GET `/api/DeviceManager/GetRegionTree` | 区域树+设备数量 | | GET /api/DeviceManager/GetRegionTree | 区域树+设备数量 |
| GET `/api/DeviceManager/GetDevicesByRegion?regionId=3` | 区域设备列表(含子设备) | | GET /api/DeviceManager/GetDevicesByRegion | 区域设备列表(含子设备) |
| PUT `/api/DeviceManager/{deviceId}` | 更新设备(含地图绑定) | | PUT /api/DeviceManager/{deviceId} | 更新设备(含地图绑定) |
| POST `/api/DeviceManager/SyncFromGateway` | 手动同步 | | POST /api/DeviceManager/SyncFromGateway | 手动同步 |
Controller 路径: `Controllers/Warehouse/Partial/DeviceManagerController.cs`
### 4.4 操作按钮矩阵 ### 4.4 操作按钮矩阵
@@ -210,13 +266,13 @@ Controller 路径: `Controllers/Warehouse/Partial/DeviceManagerController.cs`
## 五、同步策略 ## 五、同步策略
### MC4.0 → 区域树+设备 ### MC4.0 → 区域树+设备
- `type=1` 节点 → 名称匹配 warehouse_regions → 绑区或新建 - type=1 节点 → 名称匹配 warehouse_regions → 绑区或新建
- `type=2` 节点 → Upsert Base_Device, RegionId=叶子区域 - type=2 节点 → Upsert Base_Device, RegionId=叶子区域, GatewayNodeId=当前网关
- 模式: FullReplace, 频率限制: 2次/秒 - 模式: FullReplace, 频率限制: 2次/秒
### Owl → 设备 ### Owl → 设备
- `GET /devices` → Upsert Base_Device (Category=1, IsParent=1) - GET /devices → Upsert Base_Device (Category=1, IsParent=1)
- `GET /channels` → Upsert Base_Device (ParentDeviceId=NVR) - GET /channels → Upsert Base_Device (ParentDeviceId=NVR)
- Owl 无区域概念 → RegionId=NULL, 管理员手动分配 - Owl 无区域概念 → RegionId=NULL, 管理员手动分配
- 模式: Merge - 模式: Merge
@@ -233,20 +289,24 @@ Controller 路径: `Controllers/Warehouse/Partial/DeviceManagerController.cs`
## 六、部署拓扑 ## 六、部署拓扑
``` ```
Docker: Owl+ZLM (:80,:5060) │ Docker: MC4.0 (:3000) Docker: Owl+ZLM (:80) MC4.0-1 (:3000) MC4.0-2 (:3000)
| | |
┌──────────────┴──────────────┐ +----------+-----------+-------------------+
IntegrationGateway :5100 │ |
└──────────────┬──────────────┘ +----------+-----------+
| Gateway gw-31ku | Gateway gw-11ku
┌──────────────┴──────────────┐ | :5100 | :5101
│ VolPro.WebApi :9100 │ +----------+-----------+
MySQL / Redis │ |
└──────────────┬──────────────┘ +----------+-----------+
| VolPro.WebApi |
┌──────────────────┴──────────────────┐ | :9100 |
│ web.vite :9000 warehouse :9200 | MySQL / Redis |
└─────────────────────────────────────┘ +----------+-----------+
|
+--------------+---------------+
| web.vite :9000 warehouse :9200 |
+--------------------------------+
``` ```
--- ---
@@ -255,27 +315,25 @@ Docker: Owl+ZLM (:80,:5060) │ Docker: MC4.0 (:3000)
| 阶段 | 工期 | 内容 | | 阶段 | 工期 | 内容 |
|------|------|------| |------|------|------|
| Phase 0 | Day 1-2 | Gateway骨架 + Base_Device建表 + 代码生成 | | Phase 0 | Day 1-2 | Gateway骨架 + 8张表建表 + 代码生成 |
| Phase 1 | Day 3-6 | OwlAdapter + 管理端视频设备页 | | Phase 1 | Day 3-6 | OwlAdapter + 管理端视频设备页 |
| Phase 2 | Day 7-11 | Mc4Adapter + IoT管理 + 区域树匹配 + SignalR | | Phase 2 | Day 7-11 | Mc4Adapter + IoT管理 + 区域树匹配 + SignalR |
| Phase 3 | Day 12-17 | warehouse端改造 + 全链路联调 | | Phase 3 | Day 12-17 | warehouse端改造 + 全链路联调 |
| Phase 4 | Day 18-20 | 验证 + 缓冲 | | Phase 4 | Day 18-20 | 验证 + 缓冲 |
**总计: 18-20 个工作日** 总计: 18-20 个工作日
--- ---
## 八、新增整合流程 ## 八、新增整合流程
以接入「海康门禁」为例: 以接入「海康门禁」为例:
1. 新建 `IntegrationGateway.Adapters.HikvisionAccess` 项目 1. 新建 IntegrationGateway.Adapters.HikvisionAccess 项目
2. 实现 `IHasFlatDevices + IHasAlarms` 2. 实现 IHasFlatDevices + IHasAlarms
3. 注册到 Host 3. 注册到 Host → 网关启动时自动上报到 Vol.Pro
4. 前端新增 `AccessDeviceActions.vue` (~80行) 4. 前端新增 AccessDeviceActions.vue (~80行)
5. DeviceTable.vue 加 `v-else-if (Category===3)` 5. Vol.Pro 后端零改动
6. Vol.Pro 后端零改动 总工作量: 1-2 天
**总工作量: 1-2 天**
--- ---
@@ -283,7 +341,7 @@ Docker: Owl+ZLM (:80,:5060) │ Docker: MC4.0 (:3000)
| 代码类型 | 路径 | 被覆盖? | | 代码类型 | 路径 | 被覆盖? |
|----------|------|:---:| |----------|------|:---:|
| 第三方对接 | IntegrationGateway/ | ❌ | | 第三方对接 | gateway/ | ❌ |
| 扩展Controller | Controllers/*/Partial/ | ❌ | | 扩展Controller | Controllers/*/Partial/ | ❌ |
| Entity扩展 | DomainModels/*/partial/ | ❌ | | Entity扩展 | DomainModels/*/partial/ | ❌ |
| 前端业务逻辑 | extension/warehouse/*.jsx | ❌ | | 前端业务逻辑 | extension/warehouse/*.jsx | ❌ |
@@ -292,5 +350,4 @@ Docker: Owl+ZLM (:80,:5060) │ Docker: MC4.0 (:3000)
--- ---
> **文档结束** > 取代: V1.0 系列所有整合方案文档
> **取代**: Vol.Pro_MC4.0_整合方案_v1.0、Vol.Pro_Owl_ZLMediaKit_整合方案_v1.0、Vol.Pro_统一设备管理_区域树与地图绑定方案_v1.0、Vol.Pro_整合项目_实施方案_v1.0