全量提交: KMS适配器终检修复+warehouse P0修复+MC4认证修复+网关B路由+接口文档+代码审核报告

This commit is contained in:
2026-06-04 04:07:32 +08:00
parent fa170e55a9
commit 29e12a235a
11 changed files with 1706 additions and 377 deletions

View File

@@ -0,0 +1,424 @@
# VolPro.WebApi 网关相关接口文档
> **版本**: 1.0
> **日期**: 2026-06-04
> **基址**: `http://{host}:{port}`(默认 `http://localhost:9100`
> **内容类型**: `application/json`
> **接口来源**: `api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/`
---
## 目录
1. [A 组 — 网关注册通信](#1-a-组--网关注册通信)
- A1: 网关注册 `POST /api/gateway/register`
- A2: 心跳上报 `POST /api/gateway/heartbeat`
- A3: 设备同步 `POST /api/gateway/sync/devices`
- A4: 告警同步 `POST /api/gateway/sync/alarms`
2. [设备管理](#2-设备管理)
- 区域树 `GET /api/DeviceManager/GetRegionTree`
- 点位设备 `GET /api/DeviceManager/GetDevicesByPoint`
3. [定时任务](#3-定时任务)
- 设备同步任务 `POST /api/task/syncDevices`
- 心跳监控任务 `POST /api/task/heartbeatMonitor`
- 实时轮询任务 `POST /api/task/realtimePoll`
- 规则引擎任务 `POST /api/task/ruleEngine`
4. [错误代码](#4-错误代码)
---
## 1. A 组 — 网关注册通信
> A 组接口是 VolPro 向网关暴露的管理端点,由网关主动调用。所有 A 组使用 `[AllowAnonymous]` + `NodeToken` 二次认证,不走 VolPro JWT 体系。
>
> **实现文件**: `Controllers/Warehouse/Partial/gateway_nodesController.cs`
### A1: 网关注册Upsert
```
POST /api/gateway/register
```
网关启动时调用注册自身节点信息。NodeCode 已存在则更新,不存在则插入。返回当前网关的已有设备列表供网关对比差异。
**请求头**: `Content-Type: application/json`
**请求体 (GatewayRegisterRequest)**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `NodeCode` | string | ✅ | 网关节点编码,如 `gw-31ku` |
| `Token` | string | ✅ | 认证令牌(由环境变量 `SECMPS_GATEWAY_TOKEN` 注入) |
| `AdapterTypes` | string | ✅ | 适配器类型列表(逗号分隔),如 `Owl:main,MC4:31ku` |
| `BaseUrl` | string | ✅ | 网关自身地址,如 `http://192.168.1.10:5100` |
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `nodeId` | int | 网关节点 IDbase_device.NodeId 外键) |
| `devices` | array | 该网关已有的设备列表 |
**devices[] 条目**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `deviceId` | int | 设备自增 ID |
| `deviceName` | string | 设备名称 |
| `adapterCode` | string | 适配器编码 |
| `sourceId` | string | 子系统设备原始 ID |
| `deviceCategory` | string | 设备种类 |
| `deviceGroup` | string | 设备分组 |
| `isParent` | string | 是否父设备("是"/"否" |
| `isOnline` | string | 是否在线("在线"/"离线" |
| `extraData` | string? | 扩展数据 JSON |
**返回示例**:
```json
{
"nodeId": 1,
"devices": [
{ "deviceId": 10, "deviceName": "NVR-1", "adapterCode": "Owl:main", "sourceId": "nvr_001", "deviceCategory": "硬盘录像机", "deviceGroup": "视频设备", "isParent": "是", "isOnline": "在线" }
]
}
```
**错误响应**:
| HTTP | 说明 |
|:---:|------|
| 400 | `NodeCode``Token` 为空 |
| 401 | `NodeToken` 不匹配(已有节点 Token 变更) |
---
### A2: 心跳上报
```
POST /api/gateway/heartbeat
```
网关每 15s 调用一次,更新 `LastHeartbeat` 字段。连续失败 ≥3 次45s后网关自动触发 A1+A3 重注册。
**请求体 (GatewayHeartbeatRequest)**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `NodeCode` | string | ✅ | 网关节点编码 |
| `Token` | string | ✅ | 认证令牌 |
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `status` | string | 固定 `"ok"` |
| `serverTime` | string | 服务器时间 (`yyyy-MM-dd HH:mm:ss`) |
**错误响应**:
| HTTP | 说明 |
|:---:|------|
| 400 | `NodeCode``Token` 为空 |
| 401 | NodeCode+Token 组合不匹配 |
---
### A3: 设备数据同步
```
POST /api/gateway/sync/devices
```
网关每次设备变更后调用,将全量设备列表推送到 VolPro。采用字段分治策略首次入库写全量后续只更新网关字段。
**请求体 (SyncDevicesRequest)**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `NodeCode` | string | ✅ | 网关节点编码 |
| `Token` | string | ✅ | 认证令牌 |
| `Devices` | array | ✅ | 设备列表 |
**Devices[].SyncDeviceItemDto**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `AdapterCode` | string | ✅ | 适配器编码 |
| `SourceId` | string | ✅ | 子系统设备原始 ID |
| `Name` | string? | ❌ | 设备名称 |
| `Category` | string? | ❌ | 设备种类 |
| `Group` | string? | ❌ | 设备分组 |
| `IsParent` | bool | ❌ | 是否父设备 |
| `ParentSourceId` | string? | ❌ | 父设备 SourceId用于解析 ParentDeviceId |
| `IsOnline` | bool | ❌ | 是否在线 |
| `IpAddress` | string? | ❌ | IP 地址 |
| `Port` | int? | ❌ | 端口号 |
| `ExtraDataJson` | string? | ❌ | 扩展数据 JSON |
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `added` | int | 新增设备数 |
| `updated` | int | 更新设备数 |
| `removed` | int | 固定 `0`(当前版本不移除下线设备) |
**错误响应**:
| HTTP | 说明 |
|:---:|------|
| 400 | `NodeCode``Token` 为空 |
| 401 | NodeCode+Token 认证失败 |
---
### A4: 告警数据同步
```
POST /api/gateway/sync/alarms
```
网关检测到新告警后调用,推送告警列表到 VolPro。通过 `SourceAlarmId` 去重(同一告警不重复入库)。
**请求体 (SyncAlarmsRequest)**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `NodeCode` | string | ✅ | 网关节点编码 |
| `Token` | string | ✅ | 认证令牌 |
| `Alarms` | array | ✅ | 告警列表 |
**Alarms[].SyncAlarmItemDto**:
| 字段 | 类型 | 必填 | 说明 |
|------|------|:--:|------|
| `SourceAlarmId` | string | ✅ | 子系统告警唯一 ID用于去重 |
| `DeviceSourceId` | string | ✅ | 关联设备 SourceId用于映射 DeviceId |
| `AdapterCode` | string | ✅ | 适配器编码 |
| `Level` | string | ✅ | 告警等级:`提示`/`普通`/`重要`/`紧急` |
| `Desc` | string | ✅ | 告警描述 |
| `Value` | double? | ❌ | 告警实际值 |
| `StartTime` | string | ✅ | 告警发生时间 |
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `added` | int | 新增告警数 |
**错误响应**:
| HTTP | 说明 |
|:---:|------|
| 400 | `NodeCode``Token` 为空 |
| 401 | NodeCode+Token 认证失败 |
---
## 2. 设备管理
> **实现文件**: `Controllers/Warehouse/Partial/base_deviceController.cs`
### 区域树
```
GET /api/DeviceManager/GetRegionTree
```
返回 区域→点位 的层级结构,供管理端左侧树形控件使用。
**请求参数**: 无
**返回参数**: `TreeNode[]`
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | string | 节点 ID`r_{regionId}``p_{pointId}` |
| `label` | string | 节点显示名称 |
| `type` | string | 节点类型:`region`(区域) 或 `point`(点位) |
| `deviceCount` | int | 该节点下的设备数量 |
| `children` | array? | 子节点列表(仅 region 节点有) |
**返回示例**:
```json
[
{
"id": "r_1", "label": "库房A区", "type": "region", "deviceCount": 3,
"children": [
{ "id": "p_10", "label": "温湿度监测点1", "type": "point", "deviceCount": 5 },
{ "id": "p_11", "label": "门禁点1", "type": "point", "deviceCount": 2 }
]
}
]
```
---
### 点位设备列表
```
GET /api/DeviceManager/GetDevicesByPoint?pointId={pointId}&page={page}&size={size}
```
获取指定点位下的设备列表(含子设备),支持分页。
**请求参数**:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|------|------|:--:|------|------|
| `pointId` | int | ✅ | — | 点位 ID |
| `page` | int | ❌ | 1 | 页码 |
| `size` | int | ❌ | 20 | 每页条数 |
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `items` | array | 设备列表 |
| `total` | int | 总设备数 |
**items[] 条目**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `deviceId` | int | 设备自增 ID |
| `deviceName` | string | 设备名称 |
| `adapterCode` | string | 适配器编码 |
| `sourceId` | string | 子系统设备原始 ID |
| `deviceCategory` | string | 设备种类 |
| `deviceGroup` | string | 设备分组(`视频设备`/`IoT设备`/`门禁设备` |
| `isParent` | string | 是否父设备("是"/"否" |
| `parentDeviceId` | int? | 父设备 ID |
| `isOnline` | string | 是否在线("在线"/"离线" |
| `ipAddress` | string? | IP 地址 |
| `port` | int? | 端口号 |
| `location` | string? | 位置描述 |
| `extraData` | string? | 扩展数据 JSON |
| `lastSyncTime` | DateTime? | 最后同步时间 |
| `mapModelId` | string? | 3D 地图模型 ID |
| `mapModelScale` | decimal? | 模型缩放比例 |
| `mapModelRotation` | string? | 模型旋转参数 JSON |
| `enable` | string | 启用状态("启用"/"停用" |
---
## 3. 定时任务
> VolPro 框架通过 `Sys_QuartzOptions` 表配置 URL+Cron 定时调用。每个端点加 `[ApiTask]` 属性以允许框架匿名调用。
>
> **实现文件**: `Controllers/Warehouse/TaskController.cs`
### 设备同步任务
```
POST /api/task/syncDevices
```
遍历所有在线网关,触发全量设备同步至 VolPro。
**Cron**: `0 */5 * * * ?`(每 5 分钟)
**请求参数**: 无
**返回参数**:
| 字段 | 类型 | 说明 |
|------|------|------|
| `time` | DateTime | 执行时间 |
| `status` | string | 固定 `"ok"` |
**错误响应**:
| HTTP | 说明 |
|:---:|------|
| 500 | `gateway_nodesService` 未注册 |
---
### 心跳监控任务
```
POST /api/task/heartbeatMonitor
```
扫描心跳超时 ≥30s 的网关节点,标记离线并级联标记该节点下所有设备离线。
**Cron**: `0/15 * * * * ?`(每 15 秒)
**请求参数**: 无
**返回**: 同设备同步任务
---
### 实时轮询任务
```
POST /api/task/realtimePoll
```
轮询所有在线 MC4 IoT 设备的实时值,写入 `iot_devicedata` 表。
**Cron**: `0/10 * * * * ?`(每 10 秒)
**请求参数**: 无
**返回**: 同设备同步任务
---
### 规则引擎任务
```
POST /api/task/ruleEngine
```
加载启用规则 → 从网关批量获取实时值 → 逐规则评估条件 → 触发动作(控制/告警/通知)。
**Cron**: `0/10 * * * * ?`(每 10 秒)
**请求参数**: 无
**返回**: 同设备同步任务
**当前状态**: 桩实现。`RuleEngineService.EvaluateAllAsync()` 抛出 `NotImplementedException`,需先执行 SQL ALTER TABLE + 代码生成器。
---
## 4. 错误代码
### HTTP 状态码
| 状态码 | 含义 | 触发条件 |
|:---:|------|------|
| 200 | OK | 请求成功 |
| 400 | Bad Request | 必填参数缺失(`NodeCode`/`Token`/`pointId` |
| 401 | Unauthorized | A 组接口 NodeToken 认证失败 |
| 500 | Internal Server Error | 服务未注册或内部异常 |
### A 组认证错误
所有 A 组接口在认证失败时返回:
```json
{ "message": "认证失败Token 无效" }
```
```json
{ "message": "认证失败" }
```
### 定时任务错误
定时任务在服务未注册时返回:
```json
{ "error": "服务未注册: gateway_nodesService" }
```
---
> **接口总数**: 10 个端点A 组 4 + 设备管理 2 + 定时任务 4
> **实现位置**: `api_sqlsugar/VolPro.WebApi/Controllers/Warehouse/`