1 feat: 重构触发器设计,移除触发条件并添加名称字段
2
3 - 从Trigger、DbTriggerDefinition和TriggerItem类中移除了所有条件相关的属性(Condition, Threshold, LowerBound, UpperBound)
4 - 删除了ConditionType枚举,简化了触发器逻辑
5 - 为触发器添加了Name字段,在核心模型、数据库实体和视图模型中都添加了该属性
6 - 删除了TriggerDialog界面中的变量选择和搜索功能
7 - 从TriggerDialog界面中删除了触发条件相关的UI元素
8 - 更新了TriggerDialogViewModel,移除了条件相关的验证和业务逻辑
9 - 更新了TriggersViewModel,移除了条件的初始化设置
10 - 更新了AutoMapper配置文件,增加TriggerItem与Trigger之间的映射
11 - 在TriggerEvaluationService中移除了条件判断逻辑,现在激活的触发器会直接执行动作
12 - 更新了App.xaml,移除了对已删除枚举的引用
13 - 修改了保存验证逻辑,确保触发器名称不能为空
This commit is contained in:
@@ -49,7 +49,7 @@ namespace DMS.Application.Services.Management
|
||||
public async Task<Trigger> CreateTriggerAsync(Trigger triggerDto)
|
||||
{
|
||||
// 1. 验证 DTO (可以在应用层或领域层做)
|
||||
ValidateTriggerDto(triggerDto);
|
||||
// ValidateTriggerDto(triggerDto);
|
||||
|
||||
// 2. 转换 DTO 到实体
|
||||
var triggerEntity = _mapper.Map<Trigger>(triggerDto);
|
||||
@@ -150,23 +150,6 @@ namespace DMS.Application.Services.Management
|
||||
throw new ArgumentException("触发器必须至少关联一个变量。");
|
||||
|
||||
// 添加必要的验证逻辑
|
||||
switch (dto.Condition)
|
||||
{
|
||||
case ConditionType.GreaterThan:
|
||||
case ConditionType.LessThan:
|
||||
case ConditionType.EqualTo:
|
||||
case ConditionType.NotEqualTo:
|
||||
if (!dto.Threshold.HasValue)
|
||||
throw new ArgumentException($"{dto.Condition} requires Threshold.");
|
||||
break;
|
||||
case ConditionType.InRange:
|
||||
case ConditionType.OutOfRange:
|
||||
if (!dto.LowerBound.HasValue || !dto.UpperBound.HasValue)
|
||||
throw new ArgumentException($"{dto.Condition} requires LowerBound and UpperBound.");
|
||||
if (dto.LowerBound > dto.UpperBound)
|
||||
throw new ArgumentException("LowerBound must be less than or equal to UpperBound.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ namespace DMS.Application.Services.Triggers.Impl
|
||||
switch (context.Trigger.Action)
|
||||
{
|
||||
case ActionType.SendEmail:
|
||||
await ExecuteSendEmail(context);
|
||||
// await ExecuteSendEmail(context);
|
||||
break;
|
||||
case ActionType.ActivateAlarm:
|
||||
_logger.LogWarning("Action 'ActivateAlarm' is not implemented yet.");
|
||||
@@ -61,72 +61,5 @@ namespace DMS.Application.Services.Triggers.Impl
|
||||
}
|
||||
}
|
||||
|
||||
#region 私有执行方法
|
||||
|
||||
private async Task ExecuteSendEmail(TriggerContext context)
|
||||
{
|
||||
if (_emailService == null)
|
||||
{
|
||||
_logger.LogWarning("Email service is not configured, skipping SendEmail action for trigger '{TriggerId}'.", context.Trigger.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
var config = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(context.Trigger.ActionConfigurationJson);
|
||||
if (config == null ||
|
||||
!config.TryGetValue("Recipients", out var recipientsElement) ||
|
||||
!config.TryGetValue("SubjectTemplate", out var subjectTemplateElement) ||
|
||||
!config.TryGetValue("BodyTemplate", out var bodyTemplateElement))
|
||||
{
|
||||
_logger.LogError("Invalid configuration for SendEmail action for trigger '{TriggerId}'.", context.Trigger.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
var recipients = recipientsElement.Deserialize<List<string>>();
|
||||
var subjectTemplate = subjectTemplateElement.GetString();
|
||||
var bodyTemplate = bodyTemplateElement.GetString();
|
||||
|
||||
if (recipients == null || string.IsNullOrEmpty(subjectTemplate) || string.IsNullOrEmpty(bodyTemplate))
|
||||
{
|
||||
_logger.LogError("Missing required fields in SendEmail configuration for trigger '{TriggerId}'.", context.Trigger.Id);
|
||||
return;
|
||||
}
|
||||
|
||||
// Simple token replacement - in practice, use a templating engine like Scriban, RazorLight etc.
|
||||
// Note: This assumes context.Variable and context.CurrentValue have Name properties/values.
|
||||
// You might need to adjust the token names and values based on your actual Variable structure.
|
||||
var subject = subjectTemplate
|
||||
.Replace("{VariableName}", context.Variable?.Name ?? "Unknown")
|
||||
.Replace("{CurrentValue}", context.CurrentValue?.ToString() ?? "N/A")
|
||||
.Replace("{Threshold}", context.Trigger.Threshold?.ToString() ?? "N/A")
|
||||
.Replace("{LowerBound}", context.Trigger.LowerBound?.ToString() ?? "N/A")
|
||||
.Replace("{UpperBound}", context.Trigger.UpperBound?.ToString() ?? "N/A");
|
||||
|
||||
var body = bodyTemplate
|
||||
.Replace("{VariableName}", context.Variable?.Name ?? "Unknown")
|
||||
.Replace("{CurrentValue}", context.CurrentValue?.ToString() ?? "N/A")
|
||||
.Replace("{Threshold}", context.Trigger.Threshold?.ToString() ?? "N/A")
|
||||
.Replace("{LowerBound}", context.Trigger.LowerBound?.ToString() ?? "N/A")
|
||||
.Replace("{UpperBound}", context.Trigger.UpperBound?.ToString() ?? "N/A")
|
||||
.Replace("{Timestamp}", DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss"));
|
||||
|
||||
// await _emailService.SendEmailAsync(recipients, subject, body);
|
||||
}
|
||||
|
||||
private async Task ExecuteActivateAlarm(TriggerContext context)
|
||||
{
|
||||
var alarmId = $"trigger_{context.Trigger.Id}_{context.Variable.Id}";
|
||||
var message = $"Trigger '{context.Trigger.Description}' activated for variable '{context.Variable.Name}' with value '{context.CurrentValue}'.";
|
||||
// 假设 INotificationService 有 RaiseAlarmAsync 方法
|
||||
// await _notificationService.RaiseAlarmAsync(alarmId, message);
|
||||
}
|
||||
|
||||
private async Task ExecuteWriteToLog(TriggerContext context)
|
||||
{
|
||||
var message = $"Trigger '{context.Trigger.Description}' activated for variable '{context.Variable.Name}' with value '{context.CurrentValue}'.";
|
||||
// 假设 ILoggingService 有 LogTriggerAsync 方法
|
||||
// await _loggingService.LogTriggerAsync(message);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -109,31 +109,10 @@ namespace DMS.Application.Services.Triggers.Impl
|
||||
return false; // Cannot evaluate null
|
||||
}
|
||||
|
||||
// Attempt conversion from object to double - adjust parsing logic as needed for your data types
|
||||
if (!double.TryParse(currentValueObj.ToString(), out double currentValue))
|
||||
{
|
||||
_logger.LogWarning("Could not parse current value '{CurrentValue}' to double for trigger evaluation (trigger ID: {TriggerId}).", currentValueObj, trigger.Id);
|
||||
return false;
|
||||
}
|
||||
// 由于移除了条件,所有激活的触发器都会被触发
|
||||
_logger.LogInformation("Trigger activated for trigger ID: {TriggerId}", trigger.Id);
|
||||
|
||||
bool result = trigger.Condition switch
|
||||
{
|
||||
ConditionType.GreaterThan => currentValue > trigger.Threshold,
|
||||
ConditionType.LessThan => currentValue < trigger.Threshold,
|
||||
ConditionType.EqualTo => Math.Abs(currentValue - trigger.Threshold.GetValueOrDefault()) < double.Epsilon,
|
||||
ConditionType.NotEqualTo => Math.Abs(currentValue - trigger.Threshold.GetValueOrDefault()) >= double.Epsilon,
|
||||
ConditionType.InRange => currentValue >= trigger.LowerBound && currentValue <= trigger.UpperBound,
|
||||
ConditionType.OutOfRange => currentValue < trigger.LowerBound || currentValue > trigger.UpperBound,
|
||||
_ => false
|
||||
};
|
||||
|
||||
if(result)
|
||||
{
|
||||
_logger.LogInformation("Trigger condition met: Variable value {CurrentValue} satisfies {Condition} for trigger ID: {TriggerId}",
|
||||
currentValue, trigger.Condition, trigger.Id);
|
||||
}
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user