diff --git a/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs b/WeiCloud.Fusion/AlarmService/Alarm.DomainService/DahAlarm/DahuaGeneralCtlService.cs index 68c3155..2cd3c87 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}"); + try { - if (dto2 is null) + if (dto is null) { result.Code = "500"; result.Msg = "请求参数不能为空"; @@ -203,14 +202,14 @@ namespace Alarm.DomainService.DahAlarm _logger.LogWarning("大华报警事件订阅回调处理失败,参数不能为空"); return result; } - EventEnvelopeDto dto = dto2 as EventEnvelopeDto; + if (dto.Info is not null) { //这是大华的残卫报警类型 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); @@ -289,7 +288,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/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 09e7dc8..31368bf 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 { @@ -34,12 +36,49 @@ namespace AlarmService.API.Controllers /// /// 报警的回调 /// - /// + /// /// [HttpPost] - public async Task> DahuaAuthCallback(object env) + [Consumes("application/json")] + [Produces("application/json")] + public async Task DahuaAuthCallback([FromBody] JsonElement data) { - return await _generalCtlService.HandleAsync(env); + EventEnvelopeDto dto = new EventEnvelopeDto(); + try + { + dto = JsonSerializer.Deserialize(data.ToJson())!; + } + catch (Exception ex) + { + _logger.LogWarning($"收到了报警回调{data.ToJson()}"); + _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); } /// 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