Merge remote-tracking branch 'origin/master'(告警中心/通知模块 与 产品/物模型模块 合并,EntityMapper.cs 保留双方映射区域)
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
using Model;
|
||||
using Model.Dto.Inspection;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 告警中心服务接口(全系统统一告警上报入口)
|
||||
/// 其它模块(规则引擎/自动巡检/看板/数采等)只需注入本接口调用 RaiseAsync 即可产生告警,
|
||||
/// 去重合并、落库、通知分发、规则计数均由告警中心内部完成,调用方无需关心
|
||||
/// </summary>
|
||||
public interface IAlertCenterService
|
||||
{
|
||||
/// <summary>
|
||||
/// 上报一条告警
|
||||
/// </summary>
|
||||
/// <param name="dto">告警上报参数(除设备标识外均可空)</param>
|
||||
/// <returns>返回告警消息 Id(string,雪花 Id);合并到已有告警时返回已有告警的 Id</returns>
|
||||
Task<Result<string>> RaiseAsync(AlertRaiseDto dto);
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,79 @@
|
||||
using Model;
|
||||
using Model.Dto.Inspection;
|
||||
using Model.Entity.Inspection;
|
||||
using Model.Mapper;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息告警 服务接口
|
||||
/// 消息告警 服务接口(告警列表/闭环操作/统计分析)
|
||||
/// </summary>
|
||||
public interface IAlertMessageService
|
||||
{
|
||||
// TODO: 定义 消息告警 相关方法
|
||||
/// <summary>
|
||||
/// 分页查询告警(支持级别/状态/类型/来源/设备/关键字/时间范围筛选)
|
||||
/// </summary>
|
||||
Task<Result<List<AlertMessageDto>>> GetPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
||||
AlertLevelEnum? level, AlertStatusEnum? status, AlertTypeEnum? type, AlertSourceEnum? source,
|
||||
string? deviceCode, string? keyword, DateTime? startDate, DateTime? endDate);
|
||||
|
||||
/// <summary>
|
||||
/// 告警详情
|
||||
/// </summary>
|
||||
Task<Result<AlertMessageDto>> GetByIdAsync(long id);
|
||||
|
||||
/// <summary>
|
||||
/// 确认告警
|
||||
/// </summary>
|
||||
Task<Result<bool>> AcknowledgeAsync(long id, AlertOperateDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// 处理告警
|
||||
/// </summary>
|
||||
Task<Result<bool>> HandleAsync(long id, AlertOperateDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// 关闭告警
|
||||
/// </summary>
|
||||
Task<Result<bool>> CloseAsync(long id, AlertOperateDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// 忽略告警
|
||||
/// </summary>
|
||||
Task<Result<bool>> IgnoreAsync(long id, AlertOperateDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// 转工单(一期仅变更状态并记录 WorkOrderId,工单模块二期对接)
|
||||
/// </summary>
|
||||
Task<Result<bool>> ToWorkOrderAsync(long id, AlertOperateDto dto);
|
||||
|
||||
/// <summary>
|
||||
/// 告警概览(列表页顶部卡片)
|
||||
/// </summary>
|
||||
Task<Result<AlertOverviewDto>> GetOverviewAsync();
|
||||
|
||||
/// <summary>
|
||||
/// 趋势统计(granularity:day/week/month)
|
||||
/// </summary>
|
||||
Task<Result<List<AlertTrendItemDto>>> GetTrendAsync(string granularity, DateTime? startDate, DateTime? endDate);
|
||||
|
||||
/// <summary>
|
||||
/// 分布统计(dimension:device/type/level/source)
|
||||
/// </summary>
|
||||
Task<Result<List<AlertDistributionItemDto>>> GetDistributionAsync(string dimension, DateTime? startDate, DateTime? endDate);
|
||||
|
||||
/// <summary>
|
||||
/// 高频告警 TOP 排名
|
||||
/// </summary>
|
||||
Task<Result<List<AlertTopItemDto>>> GetTopAsync(int topN, DateTime? startDate, DateTime? endDate);
|
||||
|
||||
/// <summary>
|
||||
/// 处理及时率统计
|
||||
/// </summary>
|
||||
Task<Result<AlertTimelinessDto>> GetTimelinessAsync(DateTime? startDate, DateTime? endDate);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 通知消息(Notifier 统一入参:与具体渠道报文格式解耦)
|
||||
/// </summary>
|
||||
public class AlertNotifyMessage
|
||||
{
|
||||
/// <summary>
|
||||
/// 消息标题
|
||||
/// </summary>
|
||||
public string Title { get; set; } = "设备告警";
|
||||
|
||||
/// <summary>
|
||||
/// 消息正文(markdown 语法,各 Notifier 按需降级为纯文本)
|
||||
/// </summary>
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// @ 手机号列表(钉钉/企微支持;飞书文本追加展示)
|
||||
/// </summary>
|
||||
public List<string> AtMobiles { get; set; } = new();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通知发送结果
|
||||
/// </summary>
|
||||
public class NotifyResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否成功
|
||||
/// </summary>
|
||||
public bool Success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误信息(失败时填写,含渠道响应原文摘要)
|
||||
/// </summary>
|
||||
public string? ErrorMsg { get; set; }
|
||||
|
||||
public static NotifyResult Ok() => new() { Success = true };
|
||||
public static NotifyResult Fail(string msg) => new() { Success = false, ErrorMsg = msg };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 告警通知渠道发送器抽象(一期:飞书/钉钉/企微 Webhook 机器人)
|
||||
/// 扩展新渠道(如短信网关)只需实现本接口并在 DependencyInjection.AddAlertNotification 注册,调用方零改动
|
||||
/// </summary>
|
||||
public interface IAlertNotifier
|
||||
{
|
||||
/// <summary>
|
||||
/// 本发送器支持的渠道类型
|
||||
/// </summary>
|
||||
Model.Entity.Inspection.NotifyChannelTypeEnum ChannelType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送消息
|
||||
/// </summary>
|
||||
/// <param name="message">统一通知消息</param>
|
||||
/// <param name="webhookUrl">渠道 Webhook 地址</param>
|
||||
/// <param name="secret">加签密钥(可空:未开启加签)</param>
|
||||
/// <param name="ct">取消令牌</param>
|
||||
Task<NotifyResult> SendAsync(AlertNotifyMessage message, string webhookUrl, string? secret, CancellationToken ct = default);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using Model;
|
||||
using Model.Dto.Inspection;
|
||||
using Model.Entity.Inspection;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 告警通知配置服务接口(渠道/通知规则/推送日志/值班排班/跨网发件箱)
|
||||
/// </summary>
|
||||
public interface IAlertNotifyService
|
||||
{
|
||||
#region 通知渠道
|
||||
/// <summary>渠道列表</summary>
|
||||
Task<Result<List<AlertNotifyChannelDto>>> GetChannelsAsync();
|
||||
|
||||
/// <summary>新增渠道</summary>
|
||||
Task<Result<bool>> AddChannelAsync(AlertNotifyChannelDto dto);
|
||||
|
||||
/// <summary>修改渠道(Secret 传空表示保持原值不覆盖)</summary>
|
||||
Task<Result<bool>> UpdateChannelAsync(AlertNotifyChannelDto dto);
|
||||
|
||||
/// <summary>删除渠道(软删除)</summary>
|
||||
Task<Result<bool>> DeleteChannelAsync(long id);
|
||||
|
||||
/// <summary>渠道测试推送(发送一条测试消息验证 Webhook 配置,结果写入推送日志)</summary>
|
||||
Task<Result<bool>> TestSendAsync(long channelId);
|
||||
#endregion
|
||||
|
||||
#region 通知规则
|
||||
/// <summary>规则列表</summary>
|
||||
Task<Result<List<AlertNotifyRuleDto>>> GetRulesAsync();
|
||||
|
||||
/// <summary>新增规则</summary>
|
||||
Task<Result<bool>> AddRuleAsync(AlertNotifyRuleDto dto);
|
||||
|
||||
/// <summary>修改规则</summary>
|
||||
Task<Result<bool>> UpdateRuleAsync(AlertNotifyRuleDto dto);
|
||||
|
||||
/// <summary>删除规则(软删除)</summary>
|
||||
Task<Result<bool>> DeleteRuleAsync(long id);
|
||||
|
||||
/// <summary>启用/停用规则</summary>
|
||||
Task<Result<bool>> SetRuleEnabledAsync(long id, bool enabled);
|
||||
#endregion
|
||||
|
||||
#region 推送日志
|
||||
/// <summary>推送日志分页(可按成功状态/渠道筛选)</summary>
|
||||
Task<Result<List<AlertNotifyLogDto>>> GetLogsPagedAsync(int pageIndex, int pageSize, RefAsync<int> total,
|
||||
bool? success, long channelId = 0);
|
||||
#endregion
|
||||
|
||||
#region 值班排班
|
||||
/// <summary>值班排班列表(按日期范围)</summary>
|
||||
Task<Result<List<DutyRosterDto>>> GetDutiesAsync(DateTime? startDate, DateTime? endDate);
|
||||
|
||||
/// <summary>新增排班</summary>
|
||||
Task<Result<bool>> AddDutyAsync(DutyRosterDto dto);
|
||||
|
||||
/// <summary>修改排班</summary>
|
||||
Task<Result<bool>> UpdateDutyAsync(DutyRosterDto dto);
|
||||
|
||||
/// <summary>删除排班(软删除)</summary>
|
||||
Task<Result<bool>> DeleteDutyAsync(long id);
|
||||
|
||||
/// <summary>查询指定日期的值班人(通知规则关联值班人时使用)</summary>
|
||||
Task<DutyRosterEntity?> GetDutyByDateAsync(DateTime date);
|
||||
#endregion
|
||||
|
||||
#region 跨网发件箱(AlertBridge 对接)
|
||||
/// <summary>
|
||||
/// 写入推送日志(供 AlertNotifyWorker 直连推送后复用)
|
||||
/// </summary>
|
||||
Task WriteLogAsync(long alertId, long channelId, string content, bool success, string? errorMsg, int retryCount);
|
||||
|
||||
/// <summary>
|
||||
/// 写入跨网发件箱(供 AlertNotifyWorker 的 Outbox 模式复用)
|
||||
/// </summary>
|
||||
Task EnqueueOutboxAsync(long alertId, long channelId, AlertNotifyMessage message, List<string> atMobiles);
|
||||
|
||||
/// <summary>
|
||||
/// 拉取待推送发件箱(原子标记为已拉取,防止多实例重复推送)
|
||||
/// </summary>
|
||||
Task<Result<List<AlertOutboxItemDto>>> PullOutboxAsync(int batch);
|
||||
|
||||
/// <summary>
|
||||
/// 回写发件箱推送结果(成功/失败,失败累加重试次数并写推送日志)
|
||||
/// </summary>
|
||||
Task<Result<bool>> ReportOutboxResultAsync(long id, OutboxResultDto dto);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Service.Interface
|
||||
{
|
||||
/// <summary>
|
||||
/// 飞书通讯录服务:手机号 → open_id
|
||||
/// 飞书 at 标签只认 open_id,不认手机号;群机器人 webhook 自身无查询能力,需自建应用凭证(FeishuConfig)。
|
||||
/// </summary>
|
||||
public interface IFeishuContactService
|
||||
{
|
||||
/// <summary>
|
||||
/// 用手机号换取飞书 open_id;未配置应用凭证、查无此人或无权限时返回 null
|
||||
/// </summary>
|
||||
/// <param name="mobile">手机号(中国大陆 11 位)</param>
|
||||
Task<string?> GetOpenIdByMobileAsync(string mobile);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user