整合方案v3.0文档

This commit is contained in:
2026-05-17 02:26:07 +08:00
parent 23ea4fe05f
commit 9277330922

View File

@@ -0,0 +1,424 @@
# SecMPS 整合方案 v3.0
> 版本: 3.0
> 日期: 2025-05-17
> 状态: 草稿
---
## 1. 背景与目标
SecMPS 需要将多套异构子系统视频监控、IoT动环、门禁道闸、报警统一整合到 Vol.Pro 管理端。v2.0 采用 Vol.Pro 直接对接各子系统 API存在紧耦合、协议适配散落、扩展困难等问题。
v3.0 引入 **IntegrationGateway整合网关** 作为统一中间层,面向子系统做协议适配,面向 Vol.Pro 提供标准化 REST API实现"适配一次,多处复用"。
### 1.1 核心原则
| 原则 | 说明 |
|------|------|
| 适配器隔离 | 每个子系统一个 Adapter实现统一接口互不干扰 |
| 懒加载 | 适配器按需初始化,不阻塞网关启动 |
| 分页语义统一 | 统一 page/size 分页,适配器内部转换 skip/limit |
| 字段分治 | 网关负责"来源标识+在线状态"Vol.Pro 负责"设备名称+扩展属性",首次入库全量,后续仅更新网关字段 |
### 1.2 子系统清单
| 子系统 | 对接方式 | 适配器 | 核心能力 |
|--------|----------|--------|----------|
| Owl + ZLMediaKit | REST API | OwlAdapter | 视频设备发现、实时流、PTZ、录像回放、截图 |
| MC4.0 | REST API | MC4Adapter | 对象树、实时点值、设备控制、告警查询/确认/结束 |
---
## 2. 架构总览
```
┌──────────────────────────────────────────────────────────┐
│ Vol.Pro 管理端 │
│ ┌─────────────┐ ┌──────────────┐ ┌─────────────────┐ │
│ │ gateway_nodes│ │ base_device │ │ device_manager │ │
│ │ Controller │ │ Controller │ │ (前端页面) │ │
│ │ A1-A4 │ │ GetRegion..│ │ RegionTree + │ │
│ │ │ │ GetDevices │ │ DeviceTable │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬────────┘ │
│ │ │ │ │
│ │ GatewayClient │ │ HTTP │
│ └────────┬────────┘ │ │
│ │ B3 (REST) │ │
└──────────────────┼─────────────────────────────┼──────────┘
│ │
┌──────────────────┼─────────────────────────────┼──────────┐
│ IntegrationGateway (net8.0) │ │
│ │ │ │
│ ┌───────────────┴──────────────────────────────┴───────┐ │
│ │ AdapterRegistry │ │
│ │ ┌─────────────┐ ┌─────────────┐ │ │
│ │ │ OwlAdapter │ │ MC4Adapter │ ... │ │
│ │ │ IHasFlat.. │ │ IHasOwnTree │ │ │
│ │ │ IHasStreams │ │ IHasPoints │ │ │
│ │ │ IHasPtz │ │ IHasAlarms │ │ │
│ │ └──────┬──────┘ └──────┬──────┘ │ │
│ └─────────┼────────────────┼───────────────────────────┘ │
│ │ │ │
│ ┌────────┴────────┐ ┌───┴──────────┐ │
│ │ Owl + ZLMediaKit│ │ MC4.0 │ │
│ │ (视频监控) │ │ (动环/IoT) │ │
│ └─────────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────┘
```
### 2.1 数据流
```
MC4.0 对象树 → Mc4Adapter.GetObjectTree()
→ SyncEngine.ProcessMc4Tree()
→ type=1 节点 → warehouse_regions (区域匹配)
→ type=2 节点 → base_device (Upsert, 字段分治)
```
### 2.2 网关端口约定
| 服务 | 端口 | 说明 |
|------|------|------|
| IntegrationGateway | 5100 | 设备管理 REST API |
| Owl + ZLMediaKit | 15123 | 视频流/录像 |
| MC4.0 | 3000 | 动环数据/告警 |
| Vol.Pro | 9991 | 管理端后端 |
---
## 3. 核心接口体系
### 3.1 能力接口Capability Interfaces
```csharp
// 适配器按需实现,网关通过反射或接口判断自动发现能力
interface IHasFlatDevices { Task<PagedResult<StandardDevice>> GetDevicesAsync(int page, int size, string? keyword); }
interface IHasOwnDeviceTree { Task<List<DeviceTreeNode>> GetObjectTreeAsync(); }
interface IHasStreams { Task<StreamUrls> GetLiveUrlAsync(string channelId); Task<StreamUrls> GetPlaybackUrlAsync(string channelId, DateTime start, DateTime end); }
interface IHasPtz { Task PtzControlAsync(string channelId, string direction, float speed); }
interface IHasRecordings { Task<PagedResult<StandardRecording>> GetRecordingsAsync(string channelId, DateTime start, DateTime end, int page, int size); }
interface IHasPoints { Task<List<PointValue>> GetRealtimeValuesAsync(string sourceDeviceId); Task SetPointValueAsync(string sourceDeviceId, int pointIndex, double value); }
interface IHasAlarms { Task<PagedResult<StandardAlarm>> GetAlarmsAsync(int page, int size, DateTime from, DateTime to, ...); Task ConfirmAlarmAsync(string alarmId); Task EndAlarmAsync(string alarmId); }
interface IAcceptsMetadataPush { Task<MetadataPushResult> PushMetadataAsync(string sourceDeviceId, MetadataChangeSet changes); }
```
### 3.2 网关统一模型
```csharp
class StandardDevice {
int DeviceId; // Vol.Pro 侧主键(同步后回填)
string AdapterCode; // "Owl:main" / "MC4:31ku"
string SourceId; // 子系统原始 ID
string DeviceName;
string DeviceCategory; // 摄像机/温湿度变送器/...
string DeviceGroup; // 视频设备/IoT设备/门禁设备/...
bool IsParent;
string ParentSourceId;
bool IsOnline;
string IpAddress;
int? Port;
Dictionary<string,object?> Extra; // 子系统扩展属性
}
class StandardAlarm {
string AlarmId;
string DeviceId;
string AdapterCode;
string Level; // 提示/普通/重要/紧急
string Title;
string Content;
DateTime OccurTime;
string Status; // 未确认/已确认/已结束
double? ActualValue;
double? ThresholdValue;
}
class DeviceTreeNode {
string SourceId;
string Name;
int NodeType; // 1=区域, 2=设备
int ObjectType;
string Tag;
Dictionary<string,object?> Option;
List<DeviceTreeNode> Children;
}
```
### 3.3 订阅接口B3供 Vol.Pro 回调)
| 路由 | 方法 | 说明 |
|------|------|------|
| `/api/gateway/register` | POST | 网关注册 (Upsert) |
| `/api/gateway/heartbeat` | POST | 心跳 |
| `/api/gateway/sync/devices` | POST | 设备数据同步 |
| `/api/gateway/sync/alarms` | POST | 告警同步 |
### 3.4 网关暴露接口
| 路由 | 适配器能力 | 说明 |
|------|-----------|------|
| `GET /devices?adapter={code}&page=&size=` | IHasFlatDevices | 分页获取设备列表 |
| `GET /tree?adapter={code}` | IHasOwnDeviceTree | 获取对象树 |
| `GET /streams/{adapter}/{deviceId}/live` | IHasStreams | 获取实时流地址 |
| `GET /streams/{adapter}/{deviceId}/playback` | IHasStreams | 获取回放地址 |
| `POST /streams/{adapter}/{deviceId}/snapshot` | IHasStreams | 获取截图 |
| `POST /streams/{adapter}/{deviceId}/ptz` | IHasPtz | 云台控制 |
| `GET /recordings/{adapter}/{deviceId}` | IHasRecordings | 获取录像列表 |
| `GET /points/{adapter}/{deviceId}` | IHasPoints | 获取实时点值 |
| `POST /points/{adapter}/{deviceId}` | IHasPoints | 控制写值 |
| `GET /alarms/{adapter}` | IHasAlarms | 分页获取告警 |
| `POST /alarms/{adapter}/{id}/confirm` | IHasAlarms | 确认告警 |
| `POST /alarms/{adapter}/{id}/end` | IHasAlarms | 结束告警 |
| `GET /health` | - | 适配器健康状态 |
---
## 4. 数据库设计
### 4.1 新增表5 张Vol.Pro 侧)
```sql
-- 网关节点表
CREATE TABLE gateway_nodes (
NodeId INT IDENTITY PRIMARY KEY,
NodeCode NVARCHAR(50) NOT NULL,
NodeName NVARCHAR(100),
NodeToken NVARCHAR(200),
AdapterTypes NVARCHAR(200), -- "Owl:main,MC4:31ku"
BaseUrl NVARCHAR(500),
IsOnline NVARCHAR(10), -- 在线/离线
Enable NVARCHAR(10), -- 启用/禁用
LastHeartbeat DATETIME,
CreateDate DATETIME,
CreateID INT,
Creator NVARCHAR(50),
ModifyDate DATETIME,
ModifyID INT,
Modifier NVARCHAR(50)
);
-- 统一设备表
CREATE TABLE base_device (
DeviceId INT IDENTITY,
AdapterCode NVARCHAR(50) NOT NULL, -- 联合主键
DeviceName NVARCHAR(100),
SourceId NVARCHAR(100) NOT NULL, -- 联合主键 (AdapterCode + SourceId = 唯一)
DeviceCategory NVARCHAR(50), -- 摄像机/硬盘录像机/温湿度变送器/...
DeviceGroup NVARCHAR(50), -- 视频设备/IoT设备/门禁设备/...
PointId INT NULL, -- FK → warehouse_devicepoint
GatewayNodeId INT NULL, -- FK → gateway_nodes
IsParent NVARCHAR(10),
ParentDeviceId INT NULL,
IsOnline NVARCHAR(10),
Enable NVARCHAR(10),
Protocol NVARCHAR(50),
IpAddress NVARCHAR(50),
Port INT NULL,
LastSyncTime DATETIME,
MapModelId NVARCHAR(100),
MapModelScale NVARCHAR(50),
MapModelRotation NVARCHAR(200),
ExtraData NVARCHAR(MAX), -- JSON 扩展属性
CreateDate DATETIME,
CreateID INT,
Creator NVARCHAR(50),
ModifyDate DATETIME,
ModifyID INT,
Modifier NVARCHAR(50),
PRIMARY KEY (DeviceId, AdapterCode)
);
-- 数据归档表
CREATE TABLE iot_devicedata (
DataId INT IDENTITY PRIMARY KEY,
DeviceId INT NULL,
AdapterCode NVARCHAR(50),
PointIndex INT,
Value FLOAT,
UpdateTime DATETIME,
CreateDate DATETIME
);
-- 告警记录表
CREATE TABLE iot_alarm (
AlarmId INT IDENTITY PRIMARY KEY,
SourceAlarmId NVARCHAR(100),
DeviceId INT NULL,
AdapterCode NVARCHAR(50),
AlarmLevel NVARCHAR(20),
AlarmDesc NVARCHAR(500),
AlarmValue FLOAT,
ThresholdValue FLOAT,
StartTime DATETIME,
EndTime DATETIME,
ConfirmTime DATETIME,
State NVARCHAR(20), -- 未确认/已确认/已结束
ConfirmUser NVARCHAR(50),
CreateDate DATETIME
);
-- 视频通道表base_device 子表)
CREATE TABLE video_channel (
ChannelId INT NOT NULL,
DeviceId INT NOT NULL, -- FK → base_device
ChannelNo NVARCHAR(50),
SourceId NVARCHAR(100),
ChannelName NVARCHAR(100),
IsOnline NVARCHAR(10),
CreateDate DATETIME,
PRIMARY KEY (ChannelId, DeviceId)
);
-- 录像文件表
CREATE TABLE video_record (
RecordId INT IDENTITY PRIMARY KEY,
ChannelId INT NULL,
FilePath NVARCHAR(500),
Size BIGINT,
StartTime DATETIME,
EndTime DATETIME,
Duration FLOAT,
CreateDate DATETIME
);
```
### 4.2 字典初始化
```sql
-- 设备分类字典
INSERT INTO Sys_Dictionary (DicName, DicValue, DicNo, Config) VALUES
('设备分组', '视频设备', 'device_group_1', '视频设备'),
('设备分组', 'IoT设备', 'device_group_2', 'IoT设备'),
('设备分组', '门禁设备', 'device_group_3', '门禁设备'),
('设备分组', '道闸设备', 'device_group_4', '道闸设备'),
('设备分组', '报警设备', 'device_group_5', '报警设备');
```
---
## 5. 管理端前端
### 5.1 页面结构
```
/web.vite/src/views/warehouse/DeviceManager/
├── index.vue 左右分栏主页面
├── api/
│ └── deviceManager.js API 封装
└── components/
├── RegionTree.vue 区域→点位树 (左侧)
├── DeviceTable.vue 设备列表 (右侧)
├── VideoDeviceActions.vue 视频设备操作按钮组
├── DeviceLivePreview.vue 实时预览弹窗
├── PtzControlPanel.vue 云台方向键面板
├── MapBindingPanel.vue 地图绑定面板
└── DeviceEditDialog.vue 设备编辑弹窗
```
### 5.2 路由
```
/device-manager → DeviceManager/index.vue
```
### 5.3 功能矩阵
| 功能 | 触发条件 | 组件 | 说明 |
|------|---------|------|------|
| 区域树展开 | 页面加载 | RegionTree | 调 GetRegionTree API |
| 设备列表 | 点击点位 | DeviceTable | 调 GetDevicesByPoint API |
| 实时预览 | 视频设备→预览 | DeviceLivePreview | WS-FLV 播放 |
| 云台控制 | 视频设备→云台 | PtzControlPanel | ↑↓←→ + ZOOM |
| 查看回放 | 视频设备→回放 | (待实现) | 录像时间轴 |
| 获取快照 | 视频设备→快照 | (待实现) | JPEG 快照 |
| 地图绑定 | 任意设备→地图 | MapBindingPanel | 模型 ID/缩放/旋转 |
| 编辑设备 | 非视频设备→编辑 | DeviceEditDialog | 名称/种类/分组/启用 |
---
## 6. 实施计划
### Phase 0: 基础设施Day 1-2
| Day | 内容 | 产出 |
|-----|------|------|
| 1 | 网关项目骨架 (net8.0) | IntegrationGateway.sln, Core/Host 项目, 7 个能力接口, 10 个统一模型, 3 个基础设施 (Registry/RateLimiter/HttpClientFactory) |
| 2 | Vol.Pro 侧集成 | GatewayClient, gateway_nodesController(A1-A4骨架), base_deviceController(骨架), Quartz Job, db_init.sql, 代码生成器产物 |
### Phase 1: Owl 适配器 + 管理端Day 3-5
| Day | 内容 | 产出 |
|-----|------|------|
| 3 | OwlAdapter | RSA 加密登录, 3 个接口实现 (IHasFlatDevices + IHasStreams + IAcceptsMetadataPush) |
| 4 | DeviceManager 页面框架 | RegionTree + DeviceTable + router |
| 5 | 视频组件 | 预览/云台/地图绑定/编辑弹窗 |
### Phase 2: MC4 适配器 + 联调Day 6-11
| Day | 内容 | 产出 |
|-----|------|------|
| 6 | 联调验证 (Owl + MC4) | 需子系统就绪 |
| 7 | MC4Adapter | Token 认证, IHasOwnDeviceTree + IHasPoints + IHasAlarms |
| 8 | 区域自动匹配 | SyncEngine, 字段分治, parentSourceId 映射 |
| 9 | 物联网操作接口 | 实时值读取, 控制写值 API |
| 10 | 告警集成 + SignalR | 告警查询/确认/结束, SignalR 实时推送 |
| 11 | 地图绑定 + Quartz | MapBindingPanel, SyncDevicesJob, HeartbeatMonitorJob |
### Phase 3: Warehouse 端Day 12-17
| Day | 内容 | 产出 |
|-----|------|------|
| 12 | 钥匙柜管理 | 钥匙柜设备 + 钥匙借还流程 |
| 13 | 巡更管理 | 巡更路径/点位/排班 |
| 14 | 门禁管理 | 门禁一体机 + 授权 |
| 15 | 道闸管理 | 人行道闸 + 车辆道闸 |
| 16 | 报警管理 | 紧急报警 + 离线报警 |
| 17 | 仓库页面整合 | 菜单 + 权限 |
### Phase 4: 验证发布Day 18-20
| Day | 内容 | 产出 |
|-----|------|------|
| 18 | 系统测试 | 功能测试 + 边界测试 |
| 19 | 性能优化 | 流性能 + 并发 + 缓存 |
| 20 | 文档 + 发布 | 部署手册, Dockerfile |
---
## 7. 风险与约束
| 风险 | 缓解措施 |
|------|----------|
| Vol.Pro 框架 API 与自主代码不兼容 | 网关层独立编译dotnet buildVol.Pro 后端逻辑骨架化,联调时一边调一边补 |
| Owl 接口不稳定 | 统一 2 QPS 限流 + 重试 |
| MC4 字段映射复杂 | 对象树 Option 弹性 JSON 字段,扩容不破坏现有映射 |
| 设备数量大导致同步慢 | 增量同步 + 批量 Upsert |
---
## 8. 环境配置
### 8.1 网关 appsettings.json
```json
{
"Owl": {
"BaseUrl": "http://owl_host:15123",
"Username": "admin",
"Password": "your_owl_password"
},
"MC4": {
"BaseUrl": "http://mc4_host:3000"
}
}
```
### 8.2 启动顺序
1. Owl + ZLMediaKit → 端口 15123
2. MC4.0 → 端口 3000
3. IntegrationGateway → 端口 5100 (`dotnet run --project src/IntegrationGateway.Host`)
4. Vol.Pro 后端 → 端口 9991
5. web.vite 前端 → 端口 9000 (`npm run dev`)