This commit is contained in:
“hsc”
2026-09-04 17:38:57 +08:00
67 changed files with 5971 additions and 30 deletions
+28
View File
@@ -0,0 +1,28 @@
namespace Model.Dto.Config
{
/// <summary>
/// 设备指令下发请求 DTO
/// </summary>
public class DeviceCommandDto
{
/// <summary>
/// 设备主键 Idstring
/// </summary>
public string Id { get; set; }
/// <summary>
/// 物模型点 Id(string,决定写哪个寄存器/线圈)
/// </summary>
public string PointId { get; set; }
/// <summary>
/// 下发的工程值
/// </summary>
public double Value { get; set; }
/// <summary>
/// 是否仅记录(模拟/离线调试:不实际发网络报文)
/// </summary>
public bool IsSimulated { get; set; }
}
}
+6
View File
@@ -19,6 +19,12 @@ namespace Model.Dto.Config
/// <summary>设备类型(型号,对应 DeviceCommand 驱动类)</summary>
public string DeviceType { get; set; }
/// <summary>所属产品Idstring0=未分类)</summary>
public string ProductId { get; set; }
/// <summary>所属产品型号/名称(只读展示)</summary>
public string? ProductName { get; set; }
/// <summary>所属网关Code</summary>
public string GatewayCode { get; set; }
+26
View File
@@ -0,0 +1,26 @@
namespace Model.Dto.Config
{
/// <summary>
/// 产品分类 DTOId 由 long 改为 string,避免前端精度丢失)
/// </summary>
public class ProductCategoryDto
{
/// <summary>主键 Idlong → string</summary>
public string Id { get; set; }
/// <summary>分类编码</summary>
public string Code { get; set; }
/// <summary>分类名称</summary>
public string? Name { get; set; }
/// <summary>排序号</summary>
public int Sort { get; set; }
/// <summary>备注</summary>
public string? Remark { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
}
}
+46
View File
@@ -0,0 +1,46 @@
using Model.Entity.Config;
namespace Model.Dto.Config
{
/// <summary>
/// 产品 DTOId 由 long 改为 string,避免前端精度丢失)
/// </summary>
public class ProductDto
{
/// <summary>主键 Idlong → string</summary>
public string Id { get; set; }
/// <summary>型号(唯一)</summary>
public string Model { get; set; }
/// <summary>产品名称</summary>
public string? Name { get; set; }
/// <summary>产品分类Id</summary>
public string CategoryId { get; set; }
/// <summary>分类名称(只读展示)</summary>
public string? CategoryName { get; set; }
/// <summary>制造商</summary>
public string? Manufacturer { get; set; }
/// <summary>产品描述</summary>
public string? Description { get; set; }
/// <summary>通讯协议</summary>
public IotDeviceProtocolEnum ProtocolType { get; set; }
/// <summary>消息模型</summary>
public string? MessageModel { get; set; }
/// <summary>是否启用</summary>
public bool IsEnabled { get; set; } = true;
/// <summary>备注</summary>
public string? Remark { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
}
}
+17
View File
@@ -0,0 +1,17 @@
namespace Model.Dto.Config
{
/// <summary>
/// 产品下拉选项 DTO(设备选择"所属产品"、筛选下拉用)
/// </summary>
public class ProductOptionDto
{
/// <summary>主键 Idstring</summary>
public string Id { get; set; }
/// <summary>型号</summary>
public string Model { get; set; }
/// <summary>产品名称</summary>
public string? Name { get; set; }
}
}
+58
View File
@@ -0,0 +1,58 @@
using Model.Entity.Config;
namespace Model.Dto.Config
{
/// <summary>
/// 物模型点 DTOId 由 long 改为 string,避免前端精度丢失)
/// </summary>
public class ThingModelPointDto
{
/// <summary>主键 Idlong → string</summary>
public string Id { get; set; }
/// <summary>归属类型(1=产品 2=设备)</summary>
public ThingOwnerTypeEnum OwnerType { get; set; }
/// <summary>归属对象Idstring</summary>
public string OwnerId { get; set; }
/// <summary>点编码</summary>
public string Code { get; set; }
/// <summary>点名称</summary>
public string? Name { get; set; }
/// <summary>寄存器类型</summary>
public ThingRegisterTypeEnum RegisterType { get; set; }
/// <summary>读写权限</summary>
public ThingRwEnum Rw { get; set; }
/// <summary>数据类型</summary>
public ThingDataTypeEnum DataType { get; set; }
/// <summary>寄存器起始地址</summary>
public ushort Address { get; set; }
/// <summary>换算系数</summary>
public double Scale { get; set; } = 1;
/// <summary>偏移量</summary>
public double Offset { get; set; }
/// <summary>单位</summary>
public string? Unit { get; set; }
/// <summary>是否启用</summary>
public bool Enabled { get; set; } = true;
/// <summary>排序号</summary>
public int Sort { get; set; }
/// <summary>备注</summary>
public string? Remark { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
}
}
+82
View File
@@ -0,0 +1,82 @@
using Model.Entity.Inspection;
namespace Model.Dto.Inspection
{
/// <summary>
/// 告警消息 DTOId 转 string 防前端精度丢失)
/// </summary>
public class AlertMessageDto
{
/// <summary>主键 Id</summary>
public string? Id { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
/// <summary>告警来源</summary>
public AlertSourceEnum Source { get; set; }
/// <summary>关联告警规则Id"0"表示无)</summary>
public string? RuleId { get; set; }
/// <summary>设备编号</summary>
public string? DeviceCode { get; set; }
/// <summary>设备名称</summary>
public string? DeviceName { get; set; }
/// <summary>设备类型</summary>
public string? DeviceType { get; set; }
/// <summary>测点/监测指标</summary>
public string? Metric { get; set; }
/// <summary>告警类型</summary>
public AlertTypeEnum AlertType { get; set; }
/// <summary>告警级别(1信息/2警告/3紧急)</summary>
public AlertLevelEnum AlertLevel { get; set; }
/// <summary>当前值</summary>
public double? CurrentValue { get; set; }
/// <summary>阈值</summary>
public double? ThresholdValue { get; set; }
/// <summary>告警内容描述</summary>
public string? Content { get; set; }
/// <summary>通知模板编码(预留)</summary>
public string? TemplateCode { get; set; }
/// <summary>触发次数(合并窗口内累计)</summary>
public int TriggerCount { get; set; }
/// <summary>首次告警时间</summary>
public DateTime FirstAlertTime { get; set; }
/// <summary>最近告警时间</summary>
public DateTime LastAlertTime { get; set; }
/// <summary>告警状态(1未确认/2已确认/3已处理/4已关闭/5已忽略/6已转工单)</summary>
public AlertStatusEnum AlertStatus { get; set; }
/// <summary>确认人</summary>
public string? AckBy { get; set; }
/// <summary>确认时间</summary>
public DateTime? AckTime { get; set; }
/// <summary>处理人</summary>
public string? HandleBy { get; set; }
/// <summary>处理时间</summary>
public DateTime? HandleTime { get; set; }
/// <summary>处理备注</summary>
public string? HandleRemark { get; set; }
/// <summary>关联工单Id(预留二期,"0"表示未转工单)</summary>
public string? WorkOrderId { get; set; }
}
}
+136
View File
@@ -0,0 +1,136 @@
using Model.Entity.Inspection;
namespace Model.Dto.Inspection
{
/// <summary>
/// 通知渠道 DTOId 转 string;Secret 出口脱敏为是否已配置)
/// </summary>
public class AlertNotifyChannelDto
{
/// <summary>主键 Id</summary>
public string? Id { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
/// <summary>渠道类型(1飞书/2钉钉/3企微)</summary>
public NotifyChannelTypeEnum ChannelType { get; set; }
/// <summary>渠道名称</summary>
public string? Name { get; set; }
/// <summary>Webhook 地址</summary>
public string? WebhookUrl { get; set; }
/// <summary>加签密钥(入参可传;出口仅返回脱敏标记,不回传明文)</summary>
public string? Secret { get; set; }
/// <summary>是否已配置加签密钥(出口专用)</summary>
public bool HasSecret { get; set; }
/// <summary>推送模式(1直连/2Outbox跨网中转)</summary>
public NotifyPushModeEnum PushMode { get; set; }
/// <summary>是否启用</summary>
public bool IsEnabled { get; set; }
/// <summary>备注</summary>
public string? Remark { get; set; }
}
/// <summary>
/// 通知规则 DTO
/// </summary>
public class AlertNotifyRuleDto
{
/// <summary>主键 Id</summary>
public string? Id { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
/// <summary>规则名称</summary>
public string? RuleName { get; set; }
/// <summary>适用告警级别(1信息/2警告/3紧急)</summary>
public AlertLevelEnum AlertLevel { get; set; }
/// <summary>通知渠道Id</summary>
public string? ChannelId { get; set; }
/// <summary>接收人(@手机号/账号,逗号分隔)</summary>
public string? Receivers { get; set; }
/// <summary>是否通知当班值班人</summary>
public bool NotifyDutyPerson { get; set; }
/// <summary>静默期(分钟)</summary>
public int SilenceMinutes { get; set; }
/// <summary>是否启用</summary>
public bool IsEnabled { get; set; }
/// <summary>备注</summary>
public string? Remark { get; set; }
}
/// <summary>
/// 推送日志 DTO
/// </summary>
public class AlertNotifyLogDto
{
/// <summary>主键 Id</summary>
public string? Id { get; set; }
/// <summary>告警消息Id"0"表示渠道测试推送)</summary>
public string? AlertId { get; set; }
/// <summary>渠道类型</summary>
public NotifyChannelTypeEnum ChannelType { get; set; }
/// <summary>渠道Id</summary>
public string? ChannelId { get; set; }
/// <summary>推送目标(脱敏)</summary>
public string? Target { get; set; }
/// <summary>推送内容摘要</summary>
public string? Content { get; set; }
/// <summary>是否成功</summary>
public bool Success { get; set; }
/// <summary>错误信息</summary>
public string? ErrorMsg { get; set; }
/// <summary>重试次数</summary>
public int RetryCount { get; set; }
/// <summary>推送时间</summary>
public DateTime NotifyTime { get; set; }
}
/// <summary>
/// 值班排班 DTO
/// </summary>
public class DutyRosterDto
{
/// <summary>主键 Id</summary>
public string? Id { get; set; }
/// <summary>创建时间</summary>
public DateTime? CreateTime { get; set; }
/// <summary>值班日期</summary>
public DateTime DutyDate { get; set; }
/// <summary>值班人姓名</summary>
public string? PersonName { get; set; }
/// <summary>联系电话</summary>
public string? Phone { get; set; }
/// <summary>备注</summary>
public string? Remark { get; set; }
}
}
+59
View File
@@ -0,0 +1,59 @@
namespace Model.Dto.Inspection
{
/// <summary>
/// 跨网发件箱拉取结果 DTO(AlertBridge 拉取到的待推送项;Payload 自包含全部推送要素)
/// </summary>
public class AlertOutboxItemDto
{
/// <summary>发件箱 Id(回写结果时使用)</summary>
public string? Id { get; set; }
/// <summary>告警消息Id</summary>
public string? AlertId { get; set; }
/// <summary>渠道Id</summary>
public string? ChannelId { get; set; }
/// <summary>完整推送报文 JSONAlertOutboxPayload 序列化)</summary>
public string? Payload { get; set; }
/// <summary>重试次数</summary>
public int RetryCount { get; set; }
}
/// <summary>
/// 发件箱推送报文(自包含:AlertBridge 无需访问数据库/配置即可推送)
/// </summary>
public class AlertOutboxPayload
{
/// <summary>渠道类型(1飞书/2钉钉/3企微)</summary>
public int ChannelType { get; set; }
/// <summary>Webhook 地址</summary>
public string? WebhookUrl { get; set; }
/// <summary>加签密钥(可空)</summary>
public string? Secret { get; set; }
/// <summary>消息标题</summary>
public string? Title { get; set; }
/// <summary>消息正文(markdown</summary>
public string? Content { get; set; }
/// <summary>@ 手机号列表</summary>
public List<string>? AtMobiles { get; set; }
}
/// <summary>
/// 发件箱结果回写 DTOAlertBridge 推送完成后回写)
/// </summary>
public class OutboxResultDto
{
/// <summary>是否成功</summary>
public bool Success { get; set; }
/// <summary>结果信息(失败原因)</summary>
public string? ResultMsg { get; set; }
}
}
+62
View File
@@ -0,0 +1,62 @@
using Model.Entity.Inspection;
namespace Model.Dto.Inspection
{
/// <summary>
/// 告警上报 DTO(其它模块调用告警中心的统一入参:IAlertCenterService.RaiseAsync / POST raise
/// 除设备标识外全部可空,降低调用方接入成本
/// </summary>
public class AlertRaiseDto
{
/// <summary>告警来源(调用方标识自身模块)</summary>
public AlertSourceEnum Source { get; set; } = AlertSourceEnum.Other;
/// <summary>关联告警规则Id(来源为规则引擎时传,可空/0 表示无)</summary>
public long RuleId { get; set; }
/// <summary>设备编号(建议必传,用于去重合并)</summary>
public string? DeviceCode { get; set; }
/// <summary>设备名称</summary>
public string? DeviceName { get; set; }
/// <summary>设备类型(如 TemperatureBox</summary>
public string? DeviceType { get; set; }
/// <summary>测点/监测指标(如 Temperature</summary>
public string? Metric { get; set; }
/// <summary>告警类型(默认阈值超限)</summary>
public AlertTypeEnum AlertType { get; set; } = AlertTypeEnum.ThresholdExceed;
/// <summary>告警级别(1信息/2警告/3紧急)</summary>
public AlertLevelEnum AlertLevel { get; set; } = AlertLevelEnum.Warning;
/// <summary>当前值</summary>
public double? CurrentValue { get; set; }
/// <summary>阈值</summary>
public double? ThresholdValue { get; set; }
/// <summary>告警内容描述(空则由告警中心按内置模板生成)</summary>
public string? Content { get; set; }
/// <summary>通知模板编码(预留对接通知模板模块)</summary>
public string? TemplateCode { get; set; }
}
/// <summary>
/// 告警操作 DTO(确认/处理/关闭/忽略/转工单 共用入参)
/// </summary>
public class AlertOperateDto
{
/// <summary>操作人</summary>
public string? Operator { get; set; }
/// <summary>备注(处理说明/忽略原因等)</summary>
public string? Remark { get; set; }
/// <summary>工单Id(仅转工单时使用,二期工单模块创建后回填,可空)</summary>
public long WorkOrderId { get; set; }
}
}
+9
View File
@@ -8,6 +8,15 @@ namespace Model.Dto.Inspection
/// <summary>主键 Idlong → string</summary>
public string Id { get; set; }
/// <summary>归属类型(0=全局;1=产品 2=设备)</summary>
public byte OwnerType { get; set; }
/// <summary>归属对象Id0 表示全局)</summary>
public long OwnerId { get; set; }
/// <summary>绑定点编码(空表示整产品/设备级规则)</summary>
public string PointCode { get; set; }
/// <summary>删除状态(0、未删除;1、已删除)</summary>
public byte IsDel { get; set; }
+101
View File
@@ -0,0 +1,101 @@
namespace Model.Dto.Inspection
{
/// <summary>
/// 告警趋势统计项(按日/周/月分桶)
/// </summary>
public class AlertTrendItemDto
{
/// <summary>时间桶(日:yyyy-MM-dd / 周:yyyy-Www / 月:yyyy-MM</summary>
public string Bucket { get; set; }
/// <summary>告警总数</summary>
public int Total { get; set; }
/// <summary>信息级数量</summary>
public int InfoCount { get; set; }
/// <summary>警告级数量</summary>
public int WarningCount { get; set; }
/// <summary>紧急级数量</summary>
public int UrgentCount { get; set; }
/// <summary>未闭环数量(未确认+已确认未处理)</summary>
public int UnhandledCount { get; set; }
}
/// <summary>
/// 告警分布统计项(按设备/类型/级别/来源维度)
/// </summary>
public class AlertDistributionItemDto
{
/// <summary>维度名称</summary>
public string Name { get; set; }
/// <summary>数量</summary>
public int Count { get; set; }
}
/// <summary>
/// 高频告警 TOP 排名项
/// </summary>
public class AlertTopItemDto
{
/// <summary>设备编号</summary>
public string? DeviceCode { get; set; }
/// <summary>设备名称</summary>
public string? DeviceName { get; set; }
/// <summary>告警次数(含合并累计 TriggerCount</summary>
public int Count { get; set; }
/// <summary>最近告警时间</summary>
public DateTime LastAlertTime { get; set; }
}
/// <summary>
/// 告警处理及时率统计
/// </summary>
public class AlertTimelinessDto
{
/// <summary>统计范围内告警总数</summary>
public int Total { get; set; }
/// <summary>已确认数(含已处理/已关闭)</summary>
public int AckCount { get; set; }
/// <summary>已处理/已关闭数</summary>
public int HandledCount { get; set; }
/// <summary>未闭环数</summary>
public int UnhandledCount { get; set; }
/// <summary>平均确认时长(分钟,无确认记录为 null</summary>
public double? AvgAckMinutes { get; set; }
/// <summary>平均处理时长(分钟,无处理记录为 null</summary>
public double? AvgHandleMinutes { get; set; }
/// <summary>及时率(%):30 分钟内确认的占比</summary>
public double TimelyRate { get; set; }
}
/// <summary>
/// 告警概览统计(列表页顶部卡片)
/// </summary>
public class AlertOverviewDto
{
/// <summary>未确认数量</summary>
public int UnacknowledgedCount { get; set; }
/// <summary>今日新增数量</summary>
public int TodayCount { get; set; }
/// <summary>今日紧急数量</summary>
public int TodayUrgentCount { get; set; }
/// <summary>近7日总数</summary>
public int WeekCount { get; set; }
}
}
+6
View File
@@ -27,6 +27,12 @@ namespace Model.Entity.Config
[SugarColumn(ColumnDescription = "设备类型", Length = 64)]
public string DeviceType { get; set; }
/// <summary>
/// 所属产品Id(关联 ProductEntity.Id,仅用于归类,0=未分类)
/// </summary>
[SugarColumn(ColumnDescription = "所属产品Id", DefaultValue = "0")]
public long ProductId { get; set; }
/// <summary>
/// 所属网关Code(对应网关实体/通道的标识,连接时据此刻查找 IP/端口/串口)
/// </summary>
@@ -0,0 +1,34 @@
using SqlSugar;
namespace Model.Entity.Config
{
/// <summary>
/// 产品分类(字典:维护产品分类,新增产品时可设置分类)
/// </summary>
public class ProductCategoryEntity : BaseEntity
{
/// <summary>
/// 分类编码
/// </summary>
[SugarColumn(ColumnDescription = "分类编码", Length = 50)]
public string Code { get; set; }
/// <summary>
/// 分类名称
/// </summary>
[SugarColumn(ColumnDescription = "分类名称", Length = 100, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 排序号
/// </summary>
[SugarColumn(ColumnDescription = "排序号")]
public int Sort { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string? Remark { get; set; }
}
}
+64
View File
@@ -0,0 +1,64 @@
using SqlSugar;
namespace Model.Entity.Config
{
/// <summary>
/// 产品(按型号区分;产品给设备归类,产品的物模型/告警等配置与设备相互独立)
/// </summary>
public class ProductEntity : BaseEntity
{
/// <summary>
/// 型号(唯一,如 GT-100
/// </summary>
[SugarColumn(ColumnDescription = "型号", Length = 100)]
public string Model { get; set; }
/// <summary>
/// 产品名称
/// </summary>
[SugarColumn(ColumnDescription = "产品名称", Length = 100, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 产品分类Id(关联 ProductCategoryEntity.Id0 表示未分类)
/// </summary>
[SugarColumn(ColumnDescription = "产品分类Id")]
public long CategoryId { get; set; }
/// <summary>
/// 制造商
/// </summary>
[SugarColumn(ColumnDescription = "制造商", Length = 100, IsNullable = true)]
public string? Manufacturer { get; set; }
/// <summary>
/// 产品描述
/// </summary>
[SugarColumn(ColumnDescription = "产品描述", Length = 500, IsNullable = true)]
public string? Description { get; set; }
/// <summary>
/// 通讯协议(复用 IotDeviceProtocolEnum:决定 DeviceCommand 驱动分支)
/// </summary>
[SugarColumn(ColumnDescription = "通讯协议")]
public IotDeviceProtocolEnum ProtocolType { get; set; } = IotDeviceProtocolEnum.ModbusTcp;
/// <summary>
/// 消息模型(消息协议/报文格式描述,如 JSON / 透传)
/// </summary>
[SugarColumn(ColumnDescription = "消息模型", Length = 64, IsNullable = true)]
public string? MessageModel { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public bool IsEnabled { get; set; } = true;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string? Remark { get; set; }
}
}
+91
View File
@@ -0,0 +1,91 @@
namespace Model.Entity.Config
{
/// <summary>
/// 物模型归属类型(物模型点表 OwnerType:点挂在哪一类对象下)
/// </summary>
public enum ThingOwnerTypeEnum
{
/// <summary>
/// 产品(型号)
/// </summary>
Product = 1,
/// <summary>
/// 设备(实例)
/// </summary>
Device = 2
}
/// <summary>
/// 点读写权限(决定该点是否可用于下发指令)
/// </summary>
public enum ThingRwEnum
{
/// <summary>
/// 只读
/// </summary>
ReadOnly = 1,
/// <summary>
/// 只写
/// </summary>
WriteOnly = 2,
/// <summary>
/// 读写
/// </summary>
ReadWrite = 3
}
/// <summary>
/// 寄存器类型
/// </summary>
public enum ThingRegisterTypeEnum
{
/// <summary>
/// 线圈(读/写 bool
/// </summary>
Coil = 1,
/// <summary>
/// 保持寄存器(读/写)
/// </summary>
HoldingRegister = 2,
/// <summary>
/// 输入寄存器(只读,如 UMC1300 的温度 PV)
/// </summary>
InputRegister = 3
}
/// <summary>
/// 数据类型
/// </summary>
public enum ThingDataTypeEnum
{
/// <summary>
/// 布尔
/// </summary>
Bool = 1,
/// <summary>
/// 16位有符号整数
/// </summary>
Int16 = 2,
/// <summary>
/// 16位无符号整数
/// </summary>
UInt16 = 3,
/// <summary>
/// 32位整数(占2寄存器,暂不支持下发)
/// </summary>
Int32 = 4,
/// <summary>
/// 32位浮点(占2寄存器,暂不支持下发)
/// </summary>
Float = 5
}
}
@@ -0,0 +1,95 @@
using SqlSugar;
namespace Model.Entity.Config
{
/// <summary>
/// 物模型点(属性/指令通用表;通过 OwnerType+OwnerId 归属产品或设备)
/// 一条点 = 一个寄存器/线圈映射;可写点即"下发指令"的入口
/// </summary>
public class ThingModelPointEntity : BaseEntity
{
/// <summary>
/// 归属类型(1=产品 2=设备)
/// </summary>
[SugarColumn(ColumnDescription = "归属类型")]
public ThingOwnerTypeEnum OwnerType { get; set; }
/// <summary>
/// 归属对象IdProductEntity.Id / IotDeviceEntity.Id
/// </summary>
[SugarColumn(ColumnDescription = "归属对象Id")]
public long OwnerId { get; set; }
/// <summary>
/// 点编码(同一归属内唯一,如 TempPV)
/// </summary>
[SugarColumn(ColumnDescription = "点编码", Length = 64)]
public string Code { get; set; }
/// <summary>
/// 点名称
/// </summary>
[SugarColumn(ColumnDescription = "点名称", Length = 100, IsNullable = true)]
public string? Name { get; set; }
/// <summary>
/// 寄存器类型(线圈/保持寄存器/输入寄存器)
/// </summary>
[SugarColumn(ColumnDescription = "寄存器类型")]
public ThingRegisterTypeEnum RegisterType { get; set; }
/// <summary>
/// 读写权限
/// </summary>
[SugarColumn(ColumnDescription = "读写权限")]
public ThingRwEnum Rw { get; set; }
/// <summary>
/// 数据类型
/// </summary>
[SugarColumn(ColumnDescription = "数据类型")]
public ThingDataTypeEnum DataType { get; set; }
/// <summary>
/// 寄存器起始地址
/// </summary>
[SugarColumn(ColumnDescription = "寄存器起始地址")]
public ushort Address { get; set; }
/// <summary>
/// 换算系数(工程值 = 寄存器原始值 / Scale + Offset,对应驱动内 SCALE
/// </summary>
[SugarColumn(ColumnDescription = "换算系数", DecimalDigits = 4)]
public double Scale { get; set; } = 1;
/// <summary>
/// 偏移量
/// </summary>
[SugarColumn(ColumnDescription = "偏移量", DecimalDigits = 4)]
public double Offset { get; set; }
/// <summary>
/// 单位
/// </summary>
[SugarColumn(ColumnDescription = "单位", Length = 16, IsNullable = true)]
public string? Unit { get; set; }
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public bool Enabled { get; set; } = true;
/// <summary>
/// 排序号
/// </summary>
[SugarColumn(ColumnDescription = "排序号")]
public int Sort { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string? Remark { get; set; }
}
}
+221
View File
@@ -0,0 +1,221 @@
namespace Model.Entity.Inspection
{
/// <summary>
/// 告警级别(与规则引擎 AlertRuleEntity.AlarmLevel 字符串"信息/警告/紧急"保持一致)
/// </summary>
public enum AlertLevelEnum
{
/// <summary>
/// 信息
/// </summary>
Info = 1,
/// <summary>
/// 警告
/// </summary>
Warning = 2,
/// <summary>
/// 紧急
/// </summary>
Urgent = 3
}
/// <summary>
/// 告警状态(闭环流转:未确认 → 已确认 → 已处理 → 已关闭;可忽略/转工单)
/// </summary>
public enum AlertStatusEnum
{
/// <summary>
/// 未确认
/// </summary>
Unacknowledged = 1,
/// <summary>
/// 已确认
/// </summary>
Acknowledged = 2,
/// <summary>
/// 已处理
/// </summary>
Handled = 3,
/// <summary>
/// 已关闭
/// </summary>
Closed = 4,
/// <summary>
/// 已忽略
/// </summary>
Ignored = 5,
/// <summary>
/// 已转工单
/// </summary>
ToWorkOrder = 6
}
/// <summary>
/// 告警来源(标识上报模块,便于其它模块调用与统计)
/// </summary>
public enum AlertSourceEnum
{
/// <summary>
/// 规则引擎
/// </summary>
RuleEngine = 1,
/// <summary>
/// 自动巡检
/// </summary>
AutoPatrol = 2,
/// <summary>
/// 数据看板
/// </summary>
Dashboard = 3,
/// <summary>
/// 数据采集
/// </summary>
Collection = 4,
/// <summary>
/// 手动/API 上报
/// </summary>
Manual = 5,
/// <summary>
/// 其它
/// </summary>
Other = 99
}
/// <summary>
/// 告警类型
/// </summary>
public enum AlertTypeEnum
{
/// <summary>
/// 阈值超限
/// </summary>
ThresholdExceed = 1,
/// <summary>
/// 设备离线
/// </summary>
DeviceOffline = 2,
/// <summary>
/// 通讯故障
/// </summary>
CommFault = 3,
/// <summary>
/// 巡检异常
/// </summary>
PatrolAbnormal = 4,
/// <summary>
/// 自定义
/// </summary>
Custom = 99
}
/// <summary>
/// 通知渠道类型(一期仅支持飞书/钉钉/企微 Webhook 机器人)
/// </summary>
public enum NotifyChannelTypeEnum
{
/// <summary>
/// 飞书
/// </summary>
Feishu = 1,
/// <summary>
/// 钉钉
/// </summary>
DingTalk = 2,
/// <summary>
/// 企业微信
/// </summary>
WeCom = 3
}
/// <summary>
/// 渠道推送模式
/// </summary>
public enum NotifyPushModeEnum
{
/// <summary>
/// 直连推送(服务器可直接访问外网 Webhook)
/// </summary>
Direct = 1,
/// <summary>
/// Outbox 中转(跨网场景:内网写发件箱,跳板机 AlertBridge 拉取后在外网推送)
/// </summary>
Outbox = 2
}
/// <summary>
/// 跨网发件箱状态
/// </summary>
public enum OutboxStatusEnum
{
/// <summary>
/// 待推送
/// </summary>
Pending = 1,
/// <summary>
/// 已拉取(跳板机取走,等待回写结果)
/// </summary>
Pulled = 2,
/// <summary>
/// 推送成功
/// </summary>
Success = 3,
/// <summary>
/// 推送失败
/// </summary>
Failed = 4
}
/// <summary>
/// 告警级别枚举 ↔ 规则引擎字符串 映射工具
/// </summary>
public static class AlertLevelMap
{
/// <summary>
/// 字符串(信息/警告/紧急)→ 枚举,无法识别时默认 Info
/// </summary>
public static AlertLevelEnum FromString(string level)
{
return level?.Trim() switch
{
"警告" => AlertLevelEnum.Warning,
"紧急" => AlertLevelEnum.Urgent,
_ => AlertLevelEnum.Info
};
}
/// <summary>
/// 枚举 → 字符串(信息/警告/紧急)
/// </summary>
public static string ToLabel(AlertLevelEnum level)
{
return level switch
{
AlertLevelEnum.Warning => "警告",
AlertLevelEnum.Urgent => "紧急",
_ => "信息"
};
}
}
}
@@ -0,0 +1,151 @@
using SqlSugar;
using System;
namespace Model.Entity.Inspection
{
/// <summary>
/// 告警消息(消息告警模块核心表:所有模块的告警统一汇聚于此,支持确认/处理/关闭闭环)
/// </summary>
public class AlertMessageEntity : BaseEntity
{
#region
/// <summary>
/// 告警来源(规则引擎/自动巡检/看板/数采/手动等)
/// </summary>
[SugarColumn(ColumnDescription = "告警来源")]
public AlertSourceEnum Source { get; set; } = AlertSourceEnum.Manual;
/// <summary>
/// 关联告警规则Id(来源为规则引擎时填写,0表示无)
/// </summary>
[SugarColumn(ColumnDescription = "关联告警规则Id")]
public long RuleId { get; set; }
/// <summary>
/// 设备编号
/// </summary>
[SugarColumn(ColumnDescription = "设备编号", Length = 64, IsNullable = true)]
public string DeviceCode { get; set; }
/// <summary>
/// 设备名称
/// </summary>
[SugarColumn(ColumnDescription = "设备名称", Length = 128, IsNullable = true)]
public string DeviceName { get; set; }
/// <summary>
/// 设备类型(如 TemperatureBox,与规则引擎 DeviceType 对齐)
/// </summary>
[SugarColumn(ColumnDescription = "设备类型", Length = 64, IsNullable = true)]
public string DeviceType { get; set; }
/// <summary>
/// 测点/监测指标(如 Temperature、Humidity
/// </summary>
[SugarColumn(ColumnDescription = "测点指标", Length = 64, IsNullable = true)]
public string Metric { get; set; }
/// <summary>
/// 告警类型(超限/离线/通讯故障/巡检异常/自定义)
/// </summary>
[SugarColumn(ColumnDescription = "告警类型")]
public AlertTypeEnum AlertType { get; set; } = AlertTypeEnum.ThresholdExceed;
#endregion
#region
/// <summary>
/// 告警级别(信息/警告/紧急,与规则引擎三级一致)
/// </summary>
[SugarColumn(ColumnDescription = "告警级别")]
public AlertLevelEnum AlertLevel { get; set; } = AlertLevelEnum.Info;
/// <summary>
/// 当前值(触发告警时的实际值)
/// </summary>
[SugarColumn(ColumnDescription = "当前值", IsNullable = true)]
public double? CurrentValue { get; set; }
/// <summary>
/// 阈值(规则阈值,可空)
/// </summary>
[SugarColumn(ColumnDescription = "阈值", IsNullable = true)]
public double? ThresholdValue { get; set; }
/// <summary>
/// 告警内容描述
/// </summary>
[SugarColumn(ColumnDescription = "告警内容", Length = 500, IsNullable = true)]
public string Content { get; set; }
/// <summary>
/// 通知模板编码(预留:对接通知模板模块,空表示使用内置模板)
/// </summary>
[SugarColumn(ColumnDescription = "通知模板编码", Length = 64, IsNullable = true)]
public string TemplateCode { get; set; }
#endregion
#region
/// <summary>
/// 触发次数(合并窗口内同设备同测点同类型告警的累计次数)
/// </summary>
[SugarColumn(ColumnDescription = "触发次数")]
public int TriggerCount { get; set; } = 1;
/// <summary>
/// 首次告警时间
/// </summary>
[SugarColumn(ColumnDescription = "首次告警时间")]
public DateTime FirstAlertTime { get; set; }
/// <summary>
/// 最近告警时间
/// </summary>
[SugarColumn(ColumnDescription = "最近告警时间")]
public DateTime LastAlertTime { get; set; }
#endregion
#region
/// <summary>
/// 告警状态(未确认/已确认/已处理/已关闭/已忽略/已转工单)
/// </summary>
[SugarColumn(ColumnDescription = "告警状态")]
public AlertStatusEnum AlertStatus { get; set; } = AlertStatusEnum.Unacknowledged;
/// <summary>
/// 确认人
/// </summary>
[SugarColumn(ColumnDescription = "确认人", Length = 50, IsNullable = true)]
public string AckBy { get; set; }
/// <summary>
/// 确认时间
/// </summary>
[SugarColumn(ColumnDescription = "确认时间", IsNullable = true)]
public DateTime? AckTime { get; set; }
/// <summary>
/// 处理人
/// </summary>
[SugarColumn(ColumnDescription = "处理人", Length = 50, IsNullable = true)]
public string HandleBy { get; set; }
/// <summary>
/// 处理时间
/// </summary>
[SugarColumn(ColumnDescription = "处理时间", IsNullable = true)]
public DateTime? HandleTime { get; set; }
/// <summary>
/// 处理备注
/// </summary>
[SugarColumn(ColumnDescription = "处理备注", Length = 500, IsNullable = true)]
public string HandleRemark { get; set; }
/// <summary>
/// 关联工单Id(预留二期运维工单模块,0表示未转工单)
/// </summary>
[SugarColumn(ColumnDescription = "关联工单Id")]
public long WorkOrderId { get; set; }
#endregion
}
}
@@ -0,0 +1,52 @@
using SqlSugar;
namespace Model.Entity.Inspection
{
/// <summary>
/// 告警通知渠道(飞书/钉钉/企微 Webhook 机器人配置)
/// </summary>
public class AlertNotifyChannelEntity : BaseEntity
{
/// <summary>
/// 渠道类型(1飞书/2钉钉/3企微)
/// </summary>
[SugarColumn(ColumnDescription = "渠道类型")]
public NotifyChannelTypeEnum ChannelType { get; set; }
/// <summary>
/// 渠道名称(如:设备告警-研发飞书群)
/// </summary>
[SugarColumn(ColumnDescription = "渠道名称", Length = 100)]
public string Name { get; set; }
/// <summary>
/// Webhook 地址
/// </summary>
[SugarColumn(ColumnDescription = "Webhook地址", Length = 500)]
public string WebhookUrl { get; set; }
/// <summary>
/// 加签密钥(钉钉/飞书机器人开启加签时填写,企微机器人无此项)
/// </summary>
[SugarColumn(ColumnDescription = "加签密钥", Length = 200, IsNullable = true)]
public string Secret { get; set; }
/// <summary>
/// 推送模式(1直连推送/2Outbox跨网中转)
/// </summary>
[SugarColumn(ColumnDescription = "推送模式")]
public NotifyPushModeEnum PushMode { get; set; } = NotifyPushModeEnum.Direct;
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public bool IsEnabled { get; set; } = true;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string Remark { get; set; }
}
}
@@ -0,0 +1,65 @@
using SqlSugar;
using System;
namespace Model.Entity.Inspection
{
/// <summary>
/// 告警通知推送日志(每次向渠道推送的结果记录,失败可追溯)
/// </summary>
public class AlertNotifyLogEntity : BaseEntity
{
/// <summary>
/// 告警消息Id(关联 AlertMessageEntity.Id0表示渠道测试推送)
/// </summary>
[SugarColumn(ColumnDescription = "告警消息Id")]
public long AlertId { get; set; }
/// <summary>
/// 渠道类型(1飞书/2钉钉/3企微)
/// </summary>
[SugarColumn(ColumnDescription = "渠道类型")]
public NotifyChannelTypeEnum ChannelType { get; set; }
/// <summary>
/// 渠道Id(关联 AlertNotifyChannelEntity.Id
/// </summary>
[SugarColumn(ColumnDescription = "渠道Id")]
public long ChannelId { get; set; }
/// <summary>
/// 推送目标(Webhook 地址脱敏展示)
/// </summary>
[SugarColumn(ColumnDescription = "推送目标", Length = 200, IsNullable = true)]
public string Target { get; set; }
/// <summary>
/// 推送内容摘要
/// </summary>
[SugarColumn(ColumnDescription = "推送内容", Length = 1000, IsNullable = true)]
public string Content { get; set; }
/// <summary>
/// 是否成功
/// </summary>
[SugarColumn(ColumnDescription = "是否成功")]
public bool Success { get; set; }
/// <summary>
/// 错误信息
/// </summary>
[SugarColumn(ColumnDescription = "错误信息", Length = 500, IsNullable = true)]
public string ErrorMsg { get; set; }
/// <summary>
/// 重试次数
/// </summary>
[SugarColumn(ColumnDescription = "重试次数")]
public int RetryCount { get; set; }
/// <summary>
/// 推送时间
/// </summary>
[SugarColumn(ColumnDescription = "推送时间")]
public DateTime NotifyTime { get; set; }
}
}
@@ -0,0 +1,58 @@
using SqlSugar;
namespace Model.Entity.Inspection
{
/// <summary>
/// 告警通知规则(按告警级别配置通知渠道与接收人,支持值班排班关联与静默期)
/// </summary>
public class AlertNotifyRuleEntity : BaseEntity
{
/// <summary>
/// 规则名称
/// </summary>
[SugarColumn(ColumnDescription = "规则名称", Length = 100)]
public string RuleName { get; set; }
/// <summary>
/// 适用告警级别(信息/警告/紧急)
/// </summary>
[SugarColumn(ColumnDescription = "适用告警级别")]
public AlertLevelEnum AlertLevel { get; set; }
/// <summary>
/// 通知渠道Id(关联 AlertNotifyChannelEntity.Id
/// </summary>
[SugarColumn(ColumnDescription = "通知渠道Id")]
public long ChannelId { get; set; }
/// <summary>
/// 接收人(@手机号/企微账号,逗号分隔,可空表示不@)
/// </summary>
[SugarColumn(ColumnDescription = "接收人", Length = 500, IsNullable = true)]
public string Receivers { get; set; }
/// <summary>
/// 是否通知当班值班人(按告警时间查值班排班表)
/// </summary>
[SugarColumn(ColumnDescription = "是否通知值班人")]
public bool NotifyDutyPerson { get; set; }
/// <summary>
/// 静默期(分钟):同一告警合并窗口内重复触发时,静默期内不重复推送,0表示每次必推
/// </summary>
[SugarColumn(ColumnDescription = "静默期分钟")]
public int SilenceMinutes { get; set; } = 5;
/// <summary>
/// 是否启用
/// </summary>
[SugarColumn(ColumnDescription = "是否启用")]
public bool IsEnabled { get; set; } = true;
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string Remark { get; set; }
}
}
@@ -0,0 +1,61 @@
using SqlSugar;
using System;
namespace Model.Entity.Inspection
{
/// <summary>
/// 跨网推送发件箱(内网只写此表;跳板机上的 AlertBridge 控制台程序轮询拉取,
/// 在外网推送飞书/钉钉/企微后回写结果,实现工控内网与即时通讯软件的隔离穿透)
/// </summary>
public class AlertOutboxEntity : BaseEntity
{
/// <summary>
/// 告警消息Id(关联 AlertMessageEntity.Id
/// </summary>
[SugarColumn(ColumnDescription = "告警消息Id")]
public long AlertId { get; set; }
/// <summary>
/// 渠道Id(关联 AlertNotifyChannelEntity.Id
/// </summary>
[SugarColumn(ColumnDescription = "渠道Id")]
public long ChannelId { get; set; }
/// <summary>
/// 完整推送报文(自包含 JSON:渠道类型/WebhookUrl/Secret/标题/内容/@列表,
/// AlertBridge 拉取后无需再查任何配置即可直接推送)
/// </summary>
[SugarColumn(ColumnDescription = "推送报文", ColumnDataType = "text", IsNullable = true)]
public string Payload { get; set; }
/// <summary>
/// 状态(1待推送/2已拉取/3成功/4失败)
/// </summary>
[SugarColumn(ColumnDescription = "状态")]
public OutboxStatusEnum Status { get; set; } = OutboxStatusEnum.Pending;
/// <summary>
/// 重试次数(AlertBridge 推送失败回写时累加)
/// </summary>
[SugarColumn(ColumnDescription = "重试次数")]
public int RetryCount { get; set; }
/// <summary>
/// 拉取时间
/// </summary>
[SugarColumn(ColumnDescription = "拉取时间", IsNullable = true)]
public DateTime? PullTime { get; set; }
/// <summary>
/// 完成时间(成功/失败回写时间)
/// </summary>
[SugarColumn(ColumnDescription = "完成时间", IsNullable = true)]
public DateTime? FinishTime { get; set; }
/// <summary>
/// 结果信息(失败原因等)
/// </summary>
[SugarColumn(ColumnDescription = "结果信息", Length = 500, IsNullable = true)]
public string ResultMsg { get; set; }
}
}
@@ -8,6 +8,24 @@ namespace Model.Entity.Inspection
/// </summary>
public class AlertRuleEntity : BaseEntity
{
/// <summary>
/// 归属类型(0=全局/旧数据;1=产品 2=设备)
/// </summary>
[SugarColumn(ColumnDescription = "归属类型", DefaultValue = "0")]
public byte OwnerType { get; set; }
/// <summary>
/// 归属对象IdProductEntity.Id / IotDeviceEntity.Id0 表示全局)
/// </summary>
[SugarColumn(ColumnDescription = "归属对象Id", DefaultValue = "0")]
public long OwnerId { get; set; }
/// <summary>
/// 绑定点编码(关联物模型点 Code;为空表示整产品/设备级规则)
/// </summary>
[SugarColumn(ColumnDescription = "绑定点编码", Length = 64, IsNullable = true)]
public string? PointCode { get; set; }
/// <summary>
/// 规则名称
/// </summary>
@@ -0,0 +1,35 @@
using SqlSugar;
using System;
namespace Model.Entity.Inspection
{
/// <summary>
/// 值班排班(按天排班;通知规则勾选"通知值班人"时按告警日期匹配当班人)
/// </summary>
public class DutyRosterEntity : BaseEntity
{
/// <summary>
/// 值班日期(当天 00:00:00
/// </summary>
[SugarColumn(ColumnDescription = "值班日期")]
public DateTime DutyDate { get; set; }
/// <summary>
/// 值班人姓名
/// </summary>
[SugarColumn(ColumnDescription = "值班人", Length = 50)]
public string PersonName { get; set; }
/// <summary>
/// 联系电话(用于钉钉/企微 @ 手机号)
/// </summary>
[SugarColumn(ColumnDescription = "联系电话", Length = 30, IsNullable = true)]
public string Phone { get; set; }
/// <summary>
/// 备注
/// </summary>
[SugarColumn(ColumnDescription = "备注", Length = 500, IsNullable = true)]
public string Remark { get; set; }
}
}
+459
View File
@@ -255,6 +255,9 @@ namespace Model.Mapper
return new AlertRuleDto
{
Id = entity.Id.ToString(),
OwnerType = entity.OwnerType,
OwnerId = entity.OwnerId,
PointCode = entity.PointCode,
IsDel = entity.IsDel,
CreateTime = entity.CreateTime,
RuleName = entity.RuleName,
@@ -352,6 +355,9 @@ namespace Model.Mapper
return new AlertRuleEntity
{
Id = ParseId(dto.Id),
OwnerType = dto.OwnerType,
OwnerId = dto.OwnerId,
PointCode = dto.PointCode,
IsDel = dto.IsDel,
CreateTime = dto.CreateTime,
RuleName = dto.RuleName,
@@ -403,6 +409,7 @@ namespace Model.Mapper
Code = entity.Code,
Name = entity.Name,
DeviceType = entity.DeviceType,
ProductId = entity.ProductId.ToString(),
GatewayCode = entity.GatewayCode,
SlaveId = entity.SlaveId,
Manufacturer = entity.Manufacturer,
@@ -437,6 +444,7 @@ namespace Model.Mapper
Code = dto.Code,
Name = dto.Name,
DeviceType = dto.DeviceType,
ProductId = ParseId(dto.ProductId),
GatewayCode = dto.GatewayCode,
SlaveId = dto.SlaveId,
Manufacturer = dto.Manufacturer,
@@ -476,5 +484,456 @@ namespace Model.Mapper
return entities?.Select(e => e.ToDto()).ToList() ?? new List<DeviceLogDto>();
}
#endregion
#region
/// <summary>
/// ProductCategoryEntity → ProductCategoryDto
/// </summary>
public static ProductCategoryDto ToDto(this ProductCategoryEntity entity)
{
if (entity == null) return null;
return new ProductCategoryDto
{
Id = entity.Id.ToString(),
Code = entity.Code,
Name = entity.Name,
Sort = entity.Sort,
Remark = entity.Remark,
CreateTime = entity.CreateTime
};
}
/// <summary>
/// List&lt;ProductCategoryEntity&gt; → List&lt;ProductCategoryDto&gt;
/// </summary>
public static List<ProductCategoryDto> ToDtoList(this List<ProductCategoryEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<ProductCategoryDto>();
}
/// <summary>
/// ProductCategoryDto → ProductCategoryEntity(入参映射)
/// </summary>
public static ProductCategoryEntity ToEntity(this ProductCategoryDto dto)
{
if (dto == null) return null;
return new ProductCategoryEntity
{
Id = ParseId(dto.Id),
Code = dto.Code,
Name = dto.Name,
Sort = dto.Sort,
Remark = dto.Remark
};
}
#endregion
#region
/// <summary>
/// ProductEntity → ProductDto
/// </summary>
public static ProductDto ToDto(this ProductEntity entity)
{
if (entity == null) return null;
return new ProductDto
{
Id = entity.Id.ToString(),
Model = entity.Model,
Name = entity.Name,
CategoryId = entity.CategoryId.ToString(),
Manufacturer = entity.Manufacturer,
Description = entity.Description,
ProtocolType = entity.ProtocolType,
MessageModel = entity.MessageModel,
IsEnabled = entity.IsEnabled,
Remark = entity.Remark,
CreateTime = entity.CreateTime
};
}
/// <summary>
/// List&lt;ProductEntity&gt; → List&lt;ProductDto&gt;
/// </summary>
public static List<ProductDto> ToDtoList(this List<ProductEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<ProductDto>();
}
/// <summary>
/// ProductDto → ProductEntity(入参映射,IsDel/CreateTime 等服务端管控字段不映射)
/// </summary>
public static ProductEntity ToEntity(this ProductDto dto)
{
if (dto == null) return null;
return new ProductEntity
{
Id = ParseId(dto.Id),
Model = dto.Model,
Name = dto.Name,
CategoryId = ParseId(dto.CategoryId),
Manufacturer = dto.Manufacturer,
Description = dto.Description,
ProtocolType = dto.ProtocolType,
MessageModel = dto.MessageModel,
IsEnabled = dto.IsEnabled,
Remark = dto.Remark
};
}
/// <summary>
/// ProductEntity → ProductOptionDto(下拉选项)
/// </summary>
public static ProductOptionDto ToOptionDto(this ProductEntity entity)
{
if (entity == null) return null;
return new ProductOptionDto
{
Id = entity.Id.ToString(),
Model = entity.Model,
Name = entity.Name
};
}
/// <summary>
/// List&lt;ProductEntity&gt; → List&lt;ProductOptionDto&gt;
/// </summary>
public static List<ProductOptionDto> ToOptionDtoList(this List<ProductEntity> entities)
{
return entities?.Select(e => e.ToOptionDto()).ToList() ?? new List<ProductOptionDto>();
}
#endregion
#region
/// <summary>
/// ThingModelPointEntity → ThingModelPointDto
/// </summary>
public static ThingModelPointDto ToDto(this ThingModelPointEntity entity)
{
if (entity == null) return null;
return new ThingModelPointDto
{
Id = entity.Id.ToString(),
OwnerType = entity.OwnerType,
OwnerId = entity.OwnerId.ToString(),
Code = entity.Code,
Name = entity.Name,
RegisterType = entity.RegisterType,
Rw = entity.Rw,
DataType = entity.DataType,
Address = entity.Address,
Scale = entity.Scale,
Offset = entity.Offset,
Unit = entity.Unit,
Enabled = entity.Enabled,
Sort = entity.Sort,
Remark = entity.Remark,
CreateTime = entity.CreateTime
};
}
/// <summary>
/// List&lt;ThingModelPointEntity&gt; → List&lt;ThingModelPointDto&gt;
/// </summary>
public static List<ThingModelPointDto> ToDtoList(this List<ThingModelPointEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<ThingModelPointDto>();
}
/// <summary>
/// ThingModelPointDto → ThingModelPointEntity(入参映射)
/// </summary>
public static ThingModelPointEntity ToEntity(this ThingModelPointDto dto)
{
if (dto == null) return null;
return new ThingModelPointEntity
{
Id = ParseId(dto.Id),
OwnerType = dto.OwnerType,
OwnerId = ParseId(dto.OwnerId),
Code = dto.Code,
Name = dto.Name,
RegisterType = dto.RegisterType,
Rw = dto.Rw,
DataType = dto.DataType,
Address = dto.Address,
Scale = dto.Scale,
Offset = dto.Offset,
Unit = dto.Unit,
Enabled = dto.Enabled,
Sort = dto.Sort,
Remark = dto.Remark
};
}
#endregion
#region
/// <summary>
/// AlertMessageEntity → AlertMessageDto
/// </summary>
public static AlertMessageDto ToDto(this AlertMessageEntity entity)
{
if (entity == null) return null;
return new AlertMessageDto
{
Id = entity.Id.ToString(),
CreateTime = entity.CreateTime,
Source = entity.Source,
RuleId = entity.RuleId.ToString(),
DeviceCode = entity.DeviceCode,
DeviceName = entity.DeviceName,
DeviceType = entity.DeviceType,
Metric = entity.Metric,
AlertType = entity.AlertType,
AlertLevel = entity.AlertLevel,
CurrentValue = entity.CurrentValue,
ThresholdValue = entity.ThresholdValue,
Content = entity.Content,
TemplateCode = entity.TemplateCode,
TriggerCount = entity.TriggerCount,
FirstAlertTime = entity.FirstAlertTime,
LastAlertTime = entity.LastAlertTime,
AlertStatus = entity.AlertStatus,
AckBy = entity.AckBy,
AckTime = entity.AckTime,
HandleBy = entity.HandleBy,
HandleTime = entity.HandleTime,
HandleRemark = entity.HandleRemark,
WorkOrderId = entity.WorkOrderId.ToString()
};
}
/// <summary>
/// List&lt;AlertMessageEntity&gt; → List&lt;AlertMessageDto&gt;
/// </summary>
public static List<AlertMessageDto> ToDtoList(this List<AlertMessageEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<AlertMessageDto>();
}
/// <summary>
/// AlertRaiseDto → AlertMessageEntity(告警中心上报入参映射;
/// 状态/闭环/聚合字段由服务端初始化,不接受调用方指定)
/// </summary>
public static AlertMessageEntity ToEntity(this AlertRaiseDto dto)
{
if (dto == null) return null;
return new AlertMessageEntity
{
Source = dto.Source,
RuleId = dto.RuleId,
DeviceCode = dto.DeviceCode,
DeviceName = dto.DeviceName,
DeviceType = dto.DeviceType,
Metric = dto.Metric,
AlertType = dto.AlertType,
AlertLevel = dto.AlertLevel,
CurrentValue = dto.CurrentValue,
ThresholdValue = dto.ThresholdValue,
Content = dto.Content,
TemplateCode = dto.TemplateCode
};
}
#endregion
#region
/// <summary>
/// AlertNotifyChannelEntity → AlertNotifyChannelDtoSecret 脱敏:不回传明文,仅标记 HasSecret)
/// </summary>
public static AlertNotifyChannelDto ToDto(this AlertNotifyChannelEntity entity)
{
if (entity == null) return null;
return new AlertNotifyChannelDto
{
Id = entity.Id.ToString(),
CreateTime = entity.CreateTime,
ChannelType = entity.ChannelType,
Name = entity.Name,
WebhookUrl = entity.WebhookUrl,
Secret = null,
HasSecret = !string.IsNullOrWhiteSpace(entity.Secret),
PushMode = entity.PushMode,
IsEnabled = entity.IsEnabled,
Remark = entity.Remark
};
}
/// <summary>
/// List&lt;AlertNotifyChannelEntity&gt; → List&lt;AlertNotifyChannelDto&gt;
/// </summary>
public static List<AlertNotifyChannelDto> ToDtoList(this List<AlertNotifyChannelEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<AlertNotifyChannelDto>();
}
/// <summary>
/// AlertNotifyChannelDto → AlertNotifyChannelEntityIsDel/CreateTime 不映射)
/// </summary>
public static AlertNotifyChannelEntity ToEntity(this AlertNotifyChannelDto dto)
{
if (dto == null) return null;
return new AlertNotifyChannelEntity
{
Id = ParseId(dto.Id),
ChannelType = dto.ChannelType,
Name = dto.Name,
WebhookUrl = dto.WebhookUrl,
Secret = dto.Secret,
PushMode = dto.PushMode,
IsEnabled = dto.IsEnabled,
Remark = dto.Remark
};
}
#endregion
#region
/// <summary>
/// AlertNotifyRuleEntity → AlertNotifyRuleDto
/// </summary>
public static AlertNotifyRuleDto ToDto(this AlertNotifyRuleEntity entity)
{
if (entity == null) return null;
return new AlertNotifyRuleDto
{
Id = entity.Id.ToString(),
CreateTime = entity.CreateTime,
RuleName = entity.RuleName,
AlertLevel = entity.AlertLevel,
ChannelId = entity.ChannelId.ToString(),
Receivers = entity.Receivers,
NotifyDutyPerson = entity.NotifyDutyPerson,
SilenceMinutes = entity.SilenceMinutes,
IsEnabled = entity.IsEnabled,
Remark = entity.Remark
};
}
/// <summary>
/// List&lt;AlertNotifyRuleEntity&gt; → List&lt;AlertNotifyRuleDto&gt;
/// </summary>
public static List<AlertNotifyRuleDto> ToDtoList(this List<AlertNotifyRuleEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<AlertNotifyRuleDto>();
}
/// <summary>
/// AlertNotifyRuleDto → AlertNotifyRuleEntityIsDel/CreateTime 不映射)
/// </summary>
public static AlertNotifyRuleEntity ToEntity(this AlertNotifyRuleDto dto)
{
if (dto == null) return null;
return new AlertNotifyRuleEntity
{
Id = ParseId(dto.Id),
RuleName = dto.RuleName,
AlertLevel = dto.AlertLevel,
ChannelId = ParseId(dto.ChannelId),
Receivers = dto.Receivers,
NotifyDutyPerson = dto.NotifyDutyPerson,
SilenceMinutes = dto.SilenceMinutes,
IsEnabled = dto.IsEnabled,
Remark = dto.Remark
};
}
#endregion
#region
/// <summary>
/// AlertNotifyLogEntity → AlertNotifyLogDto
/// </summary>
public static AlertNotifyLogDto ToDto(this AlertNotifyLogEntity entity)
{
if (entity == null) return null;
return new AlertNotifyLogDto
{
Id = entity.Id.ToString(),
AlertId = entity.AlertId.ToString(),
ChannelType = entity.ChannelType,
ChannelId = entity.ChannelId.ToString(),
Target = entity.Target,
Content = entity.Content,
Success = entity.Success,
ErrorMsg = entity.ErrorMsg,
RetryCount = entity.RetryCount,
NotifyTime = entity.NotifyTime
};
}
/// <summary>
/// List&lt;AlertNotifyLogEntity&gt; → List&lt;AlertNotifyLogDto&gt;
/// </summary>
public static List<AlertNotifyLogDto> ToDtoList(this List<AlertNotifyLogEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<AlertNotifyLogDto>();
}
#endregion
#region
/// <summary>
/// AlertOutboxEntity → AlertOutboxItemDto
/// </summary>
public static AlertOutboxItemDto ToDto(this AlertOutboxEntity entity)
{
if (entity == null) return null;
return new AlertOutboxItemDto
{
Id = entity.Id.ToString(),
AlertId = entity.AlertId.ToString(),
ChannelId = entity.ChannelId.ToString(),
Payload = entity.Payload,
RetryCount = entity.RetryCount
};
}
/// <summary>
/// List&lt;AlertOutboxEntity&gt; → List&lt;AlertOutboxItemDto&gt;
/// </summary>
public static List<AlertOutboxItemDto> ToDtoList(this List<AlertOutboxEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<AlertOutboxItemDto>();
}
#endregion
#region
/// <summary>
/// DutyRosterEntity → DutyRosterDto
/// </summary>
public static DutyRosterDto ToDto(this DutyRosterEntity entity)
{
if (entity == null) return null;
return new DutyRosterDto
{
Id = entity.Id.ToString(),
CreateTime = entity.CreateTime,
DutyDate = entity.DutyDate,
PersonName = entity.PersonName,
Phone = entity.Phone,
Remark = entity.Remark
};
}
/// <summary>
/// List&lt;DutyRosterEntity&gt; → List&lt;DutyRosterDto&gt;
/// </summary>
public static List<DutyRosterDto> ToDtoList(this List<DutyRosterEntity> entities)
{
return entities?.Select(e => e.ToDto()).ToList() ?? new List<DutyRosterDto>();
}
/// <summary>
/// DutyRosterDto → DutyRosterEntityIsDel/CreateTime 不映射)
/// </summary>
public static DutyRosterEntity ToEntity(this DutyRosterDto dto)
{
if (dto == null) return null;
return new DutyRosterEntity
{
Id = ParseId(dto.Id),
DutyDate = dto.DutyDate.Date,
PersonName = dto.PersonName,
Phone = dto.Phone,
Remark = dto.Remark
};
}
#endregion
}
}