整合方案v3.0文档
This commit is contained in:
424
doc/整合方案/SecMPS_整合方案_v3.0.md
Normal file
424
doc/整合方案/SecMPS_整合方案_v3.0.md
Normal 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 build),Vol.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`)
|
||||
Reference in New Issue
Block a user