From 47f03eafa8253aaefb4834ee6f456f16a3f5d52c Mon Sep 17 00:00:00 2001 From: LiuXin Date: Mon, 25 Aug 2025 19:14:47 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E6=8A=A5=E8=AD=A6=E7=9A=84=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs | 2 +- .../AlarmService.API/Controllers/AlarmController.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs index 68c3155..aedb2a1 100644 --- a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs @@ -289,7 +289,7 @@ namespace Alarm.DomainService.DahAlarm _logger.LogWarning("获取事件列表:token无效"); return new DaHApiResult { Success = false, Code = "1009", Msg = "token无效" }; } - // var url = $"http://demo.weienergy.cn:15230/open-api/token/v1/oauth/token?client_id=69591850&client_secret=WHcpAryKFc28suzL&grant_type=client_credentials"; + // var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-brm/1.0.0/device/1000007"; var url = $"https://{_configuration["DahuaAuth:Host"]}/evo-apigw/evo-event/1.0.0/subscribe/subscribe-list?monitorType=url&category={name}"; try { diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs index 09e7dc8..3c8222c 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs @@ -37,7 +37,9 @@ namespace AlarmService.API.Controllers /// /// [HttpPost] - public async Task> DahuaAuthCallback(object env) + [Consumes("application/json")] + [Produces("application/json")] + public async Task> DahuaAuthCallback([FromBody] object env) { return await _generalCtlService.HandleAsync(env); } From 1983eba9626f01ea70ec8dd54eeed3367c66f56b Mon Sep 17 00:00:00 2001 From: LiuXin Date: Wed, 27 Aug 2025 16:42:39 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DahAlarm/DahuaGeneralCtlService.cs | 17 ++++--- .../DahAlarm/IDahuaGeneralCtlService.cs | 2 +- .../Controllers/AlarmController.cs | 44 ++++++++++++++++++- 3 files changed, 51 insertions(+), 12 deletions(-) diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs index aedb2a1..f0a4e71 100644 --- a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs @@ -2,6 +2,7 @@ using Common.Shared.DomainService; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; +using MongoDB.Bson; using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text.Json; @@ -98,16 +99,14 @@ namespace Alarm.DomainService.DahAlarm MonitorType = "url", Events = new List { - new EventConfig - { + new() { Category = "alarm", SubscribeAll = 1, DomainSubscribe = 2, Authorities = new List { - new Authority - { - Types = new List { "4321" } + new() { + Types = ["81"] } } } @@ -189,13 +188,13 @@ namespace Alarm.DomainService.DahAlarm /// /// /// - public async Task> HandleAsync(object dto2) + public async Task> HandleAsync(EventEnvelopeDto dto) { DaHApiResult result = new() { Code = "200", Msg = "接口调用成功", Data = true }; - _logger.LogWarning($"报警回调的数据{dto2}"); + _logger.LogWarning($"报警回调的数据{dto.ToJson()}"); try { - if (dto2 is null) + if (dto is null) { result.Code = "500"; result.Msg = "请求参数不能为空"; @@ -203,7 +202,7 @@ namespace Alarm.DomainService.DahAlarm _logger.LogWarning("大华报警事件订阅回调处理失败,参数不能为空"); return result; } - EventEnvelopeDto dto = dto2 as EventEnvelopeDto; + if (dto.Info is not null) { //这是大华的残卫报警类型 diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/IDahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/IDahuaGeneralCtlService.cs index e419693..d37e808 100644 --- a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/IDahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/IDahuaGeneralCtlService.cs @@ -25,6 +25,6 @@ namespace Alarm.DomainService.DahAlarm /// /// /// - Task> HandleAsync(object env); + Task> HandleAsync(EventEnvelopeDto env); } } \ No newline at end of file diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs index 3c8222c..dbe2e65 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs @@ -1,6 +1,8 @@ using Alarm.DomainService.DahAlarm; using Common.Shared.Application.DaHua; using Microsoft.AspNetCore.Mvc; +using MongoDB.Bson; +using System.Text.Json; namespace AlarmService.API.Controllers { @@ -39,9 +41,47 @@ namespace AlarmService.API.Controllers [HttpPost] [Consumes("application/json")] [Produces("application/json")] - public async Task> DahuaAuthCallback([FromBody] object env) + public async Task DahuaAuthCallback([FromBody] JsonElement data) { - return await _generalCtlService.HandleAsync(env); + var rawJson = data.GetRawText(); + _logger.LogWarning($"收到了报警回调{data.ToJson()}"); + _logger.LogWarning($"收到了报警回调{rawJson}"); + EventEnvelopeDto dto = null; + try + { + dto = JsonSerializer.Deserialize(rawJson); + } + catch (Exception ex) + { + _logger.LogError(ex, "JSON反序列化失败"); + // 即使反序列化失败也要返回成功,避免平台反复重试 + } + + // 即使数据结构异常,也不应该让平台收到 HTTP 500 + try + { + if (dto != null) + { + await _generalCtlService.HandleAsync(dto); + } + else + { + _logger.LogWarning("接收到的DTO为 null,跳过业务处理"); + } + } + catch (Exception ex) + { + _logger.LogError(ex, "处理回调时异常"); + } + + // 返回 Java 示例中的成功结构 + var result = new + { + code = "0", + message = "成功" + }; + + return new JsonResult(result); } /// From 398ed7c76cac89c70075d6412641d4a9fb3c2d3b Mon Sep 17 00:00:00 2001 From: LiuXin Date: Wed, 27 Aug 2025 17:22:17 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=8A=A5=E8=AD=A6?= =?UTF-8?q?=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DahAlarm/DahuaGeneralCtlService.cs | 4 +- .../Controllers/AlarmController.cs | 11 +-- .../DaHua/ResponeDto/EventEnvelopeDto.cs | 82 ++++++++++++------- 3 files changed, 60 insertions(+), 37 deletions(-) diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs index f0a4e71..2cd3c87 100644 --- a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs +++ b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs @@ -191,7 +191,7 @@ namespace Alarm.DomainService.DahAlarm public async Task> HandleAsync(EventEnvelopeDto dto) { DaHApiResult result = new() { Code = "200", Msg = "接口调用成功", Data = true }; - _logger.LogWarning($"报警回调的数据{dto.ToJson()}"); + try { if (dto is null) @@ -209,7 +209,7 @@ namespace Alarm.DomainService.DahAlarm if (dto.Info.AlarmType == 4321) { //拼接物联平台标准的mqtt消息格式 - var payload = "[{\"taglabel\":\"" + dto.Info.DeviceCode + ".alart." + dto.Info.DeviceName + "\",\"value\":\"" + dto.Info.AlarmStat + "\",\"time\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\"}]"; + var payload = "[{\"taglabel\":\"DH" + dto.Info.DeviceName + "\",\"value\":\"" + dto.Info.AlarmStat + "\",\"time\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\"}]"; // var payload = "[{\"taglabel\":\"残卫测试报警按钮.alarmStat\",\"value\":\"" + dto.Info.AlarmStat + "\",\"time\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds() + "\"}]"; await _mqttClient.EnsureConnectedAsync(mqttHostIp, mqttHostPort, mqttUsername, mqttPassword, topicName, mqttClientId); diff --git a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs index dbe2e65..31368bf 100644 --- a/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs +++ b/WeiCloud.Fusion/AlarmService/AlarmService.API/Controllers/AlarmController.cs @@ -36,25 +36,22 @@ namespace AlarmService.API.Controllers /// /// 报警的回调 /// - /// + /// /// [HttpPost] [Consumes("application/json")] [Produces("application/json")] public async Task DahuaAuthCallback([FromBody] JsonElement data) { - var rawJson = data.GetRawText(); - _logger.LogWarning($"收到了报警回调{data.ToJson()}"); - _logger.LogWarning($"收到了报警回调{rawJson}"); - EventEnvelopeDto dto = null; + EventEnvelopeDto dto = new EventEnvelopeDto(); try { - dto = JsonSerializer.Deserialize(rawJson); + dto = JsonSerializer.Deserialize(data.ToJson())!; } catch (Exception ex) { + _logger.LogWarning($"收到了报警回调{data.ToJson()}"); _logger.LogError(ex, "JSON反序列化失败"); - // 即使反序列化失败也要返回成功,避免平台反复重试 } // 即使数据结构异常,也不应该让平台收到 HTTP 500 diff --git a/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/ResponeDto/EventEnvelopeDto.cs b/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/ResponeDto/EventEnvelopeDto.cs index 3ddd1a5..d0708c2 100644 --- a/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/ResponeDto/EventEnvelopeDto.cs +++ b/WeiCloud.Fusion/Common.SharedService/Common.Shared.Application/DaHua/ResponeDto/EventEnvelopeDto.cs @@ -19,23 +19,42 @@ namespace Common.Shared.Application.DaHua /// 方法名(平台定义,不同大类可能不同) [JsonPropertyName("method")] - public string? Method { get; set; } + public string Method { get; set; } = string.Empty; // 改为非空,符合必填要求 /// 序号(非唯一标识,平台侧递增) [JsonPropertyName("id")] - public long? Id { get; set; } + public long Id { get; set; } // 改为非空,符合必填要求 /// 子系统名称(与你订阅时的 subsystem.name/magic 对应) [JsonPropertyName("subsystem")] - public string? Subsystem { get; set; } + public string Subsystem { get; set; } = string.Empty; // 改为非空,符合必填要求 /// 域 ID(级联域标识) [JsonPropertyName("domainId")] - public string? DomainId { get; set; } + public string? DomainId { get; set; } // 保持可空,非必填 - /// 实际负载(不同大类结构不同,统一先接成 JsonElement) + /// 实际负载(不同大类结构不同) [JsonPropertyName("info")] - public AlarmVO Info { get; set; } + public AlarmVO Info { get; set; } = new AlarmVO(); // 初始化避免空引用 + + // 忽略JSON中存在但实体类未定义的字段(如userIds、sid、uuid等) + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? UserIds { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? Sid { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? InfoArray { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? Protocol { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public object? SupplementFlag { get; set; } + + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] + public string? Uuid { get; set; } } /// @@ -45,79 +64,86 @@ namespace Common.Shared.Application.DaHua { /// 设备编码 [JsonPropertyName("deviceCode")] - public string? DeviceCode { get; set; } + public string? DeviceCode { get; set; } // 保持可空,非必填 /// 设备名称 [JsonPropertyName("deviceName")] - public string? DeviceName { get; set; } + public string? DeviceName { get; set; } // 保持可空,非必填 /// 通道序号 [JsonPropertyName("channelSeq")] - public int? ChannelSeq { get; set; } + public int? ChannelSeq { get; set; } // 保持可空,非必填 /// 通道名称 [JsonPropertyName("channelName")] - public string? ChannelName { get; set; } + public string? ChannelName { get; set; } // 保持可空,非必填 /// 单元类型(必填:平台字段 unitType) [JsonPropertyName("unitType")] - public int UnitType { get; set; } + public int UnitType { get; set; } // 保持非空,必填 - /// 单元序号(必填:平台字段 unitSeq) + /// 单元序号(非必填:平台字段 unitSeq) [JsonPropertyName("unitSeq")] - public int UnitSeq { get; set; } + public int? UnitSeq { get; set; } // 改为可空,非必填(关键修改) /// 报警唯一编码(幂等键之一) [JsonPropertyName("alarmCode")] - public string AlarmCode { get; set; } = string.Empty; + public string AlarmCode { get; set; } = string.Empty; // 保持非空,必填 /// 报警状态:1 产生;2 消失(幂等键之一) [JsonPropertyName("alarmStat")] - public int AlarmStat { get; set; } + public int AlarmStat { get; set; } // 保持非空,必填 /// 报警类型 [JsonPropertyName("alarmType")] - public int AlarmType { get; set; } + public int AlarmType { get; set; } // 保持非空,必填 /// 报警级别 [JsonPropertyName("alarmGrade")] - public int AlarmGrade { get; set; } + public int AlarmGrade { get; set; } // 保持非空,必填 - /// 报警时间(秒级时间戳,平台可能传字符串或数字,建议按字符串接收) + /// 报警时间(秒级时间戳,平台可能传字符串或数字) [JsonPropertyName("alarmDate")] - public string AlarmDate { get; set; } = string.Empty; + public string AlarmDate { get; set; } = string.Empty; // 保持非空,必填 - /// 报警图片相对路径(如需取图需按平台 OSS 规则拼接) + /// 报警图片相对路径 [JsonPropertyName("alarmPicture")] - public string? AlarmPicture { get; set; } + public string? AlarmPicture { get; set; } // 保持可空,非必填 /// 报警图片大小(字节) [JsonPropertyName("alarmPictureSize")] - public long? AlarmPictureSize { get; set; } + public long? AlarmPictureSize { get; set; } // 保持可空,非必填 /// 备注信息 [JsonPropertyName("memo")] - public string? Memo { get; set; } + public string? Memo { get; set; } // 保持可空,非必填 /// 节点类型:1 设备;2 通道 [JsonPropertyName("nodeType")] - public int NodeType { get; set; } + public int NodeType { get; set; } // 保持非空,必填 /// 节点编码(设备或通道编码) [JsonPropertyName("nodeCode")] - public string NodeCode { get; set; } = string.Empty; + public string NodeCode { get; set; } = string.Empty; // 保持非空,必填 /// 组织编码 [JsonPropertyName("orgCode")] - public string? OrgCode { get; set; } + public string? OrgCode { get; set; } // 保持可空,非必填 /// 组织名称 [JsonPropertyName("orgName")] - public string? OrgName { get; set; } + public string? OrgName { get; set; } // 保持可空,非必填 /// 扩展字段(不同类型报警差异字段) [JsonPropertyName("extend")] - public JsonElement? Extend { get; set; } + public JsonElement? Extend { get; set; } // 保持可空,非必填 + + // 忽略JSON中存在但文档未定义的扩展字段(isSave、isEvent等) + [JsonIgnore] + public bool? IsSave { get; set; } + + [JsonIgnore] + public bool? IsEvent { get; set; } } public sealed class SubscribeDataDto