namespace Admin.NET.Plugin.AiDOP.Entity.S8; [SugarTable("ado_s8_notification_layer", "S8 通知分层")] public class AdoS8NotificationLayer { [SugarColumn(ColumnName = "id", IsPrimaryKey = true, IsIdentity = true, ColumnDataType = "bigint")] public long Id { get; set; } [SugarColumn(ColumnName = "tenant_id", ColumnDataType = "bigint")] public long TenantId { get; set; } [SugarColumn(ColumnName = "factory_id", ColumnDataType = "bigint")] public long FactoryId { get; set; } [SugarColumn(ColumnName = "scene_code", Length = 64)] public string SceneCode { get; set; } = string.Empty; /// S8 业务枚举 FOLLOW(关注)/ SERIOUS(严重)。 [SugarColumn(ColumnName = "severity", Length = 32)] public string Severity { get; set; } = "FOLLOW"; [SugarColumn(ColumnName = "level_code", Length = 32)] public string LevelCode { get; set; } = string.Empty; [SugarColumn(ColumnName = "target_role_ids", Length = 2000, IsNullable = true)] public string? TargetRoleIds { get; set; } [SugarColumn(ColumnName = "notify_channel", Length = 128, IsNullable = true)] public string? NotifyChannel { get; set; } [SugarColumn(ColumnName = "created_at")] public DateTime CreatedAt { get; set; } = DateTime.Now; [SugarColumn(ColumnName = "updated_at", IsNullable = true)] public DateTime? UpdatedAt { get; set; } /// /// S8-STEP6C-CFG-NOTIFY-CLOSURE-1:作用域标识(不落库)。 /// GLOBAL = 平台默认 (0,0),租户侧只读;FACTORY = 当前工厂自有行。 /// [SugarColumn(IsIgnore = true)] public string Scope => Admin.NET.Plugin.AiDOP.Infrastructure.S8ConfigScope.Resolve(TenantId, FactoryId); /// /// S8-STEP6C-CFG-NOTIFY-FIX-AND-CERT-1:本行所属 (scene_code, severity, level_code) 键是否存在平台默认行 /// (不落库,由 ListAsync 赋值)。 /// /// 含义与 exception_type / role_permission 等「逐行覆盖」对象**一致**: /// 「本工厂这一行覆盖了同键的平台默认行」。 /// /// ⚠️ 修正记录:S8-STEP6C-CFG-NOTIFY-CLOSURE-1 版本下覆盖粒度曾是整个 (scene, severity) 键 /// (resolver 精确命中该键即完全不读 (0,0)),本标记当时的含义是「本工厂一旦自建行就整键接管」。 /// 该语义已被 S8NotificationLayerMerge 收敛为逐 level 覆盖,本注释同批修正。 /// [SugarColumn(IsIgnore = true)] public bool HasGlobalDefault { get; set; } }