using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Abp.Dependency;
using Abp.Domain.Repositories;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json;
using ToolLibrary.LogHelper;
using YunDa.SOMS.Entities.DataMonitoring;
using YunDa.SOMS.Redis.Entities.DataMonitorCategory;
using YunDa.SOMS.Redis.Repositories;
using Jint;
namespace YunDa.SOMS.Application.DataMonitoring.SecondaryCircuitInspection.Services
{
///
/// 表达式计算服务实现
///
public class ExpressionEvaluationService : IExpressionEvaluationService, ITransientDependency
{
private readonly IRedisRepository _telemeteringRedisRepository;
private readonly IRedisRepository _telesignalisationRedisRepository;
private readonly IRepository _telemeteringConfigRepository;
private readonly IRepository _telesignalisationConfigRepository;
// 变量代码正则表达式,匹配 {16385_0} 格式
private static readonly Regex VariableCodeRegex = new Regex(@"\{(\d+_\d+)\}", RegexOptions.Compiled);
public ExpressionEvaluationService(
IRedisRepository telemeteringRedisRepository,
IRedisRepository telesignalisationRedisRepository,
IRepository telemeteringConfigRepository,
IRepository telesignalisationConfigRepository)
{
_telemeteringRedisRepository = telemeteringRedisRepository;
_telesignalisationRedisRepository = telesignalisationRedisRepository;
_telemeteringConfigRepository = telemeteringConfigRepository;
_telesignalisationConfigRepository = telesignalisationConfigRepository;
}
///
/// 计算表达式结果
///
public async Task EvaluateExpressionAsync(
string expression,
int timeWindowSeconds = 60,
CancellationToken cancellationToken = default)
{
var stopwatch = Stopwatch.StartNew();
var result = new ExpressionEvaluationResult();
try
{
// 验证表达式
var validation = ValidateExpression(expression);
if (!validation.IsValid)
{
result.ErrorMessage = string.Join("; ", validation.Errors);
return result;
}
// 提取变量代码
var variableCodes = ExtractVariableCodes(expression);
result.EvaluationDetails.Add($"提取到 {variableCodes.Count} 个变量: {string.Join(", ", variableCodes)}");
// 获取变量值
var variableValues = await GetVariableValuesAsync(variableCodes, timeWindowSeconds, cancellationToken);
result.VariableValues = variableValues;
// 替换表达式中的变量
var evaluableExpression = ReplaceVariablesInExpression(expression, variableValues);
result.EvaluationDetails.Add($"替换后的表达式: {evaluableExpression}");
// 使用JavaScript引擎计算表达式
var engine = new Engine();
var jsResult = engine.Evaluate(evaluableExpression);
result.Result = Convert.ToBoolean(jsResult.ToObject());
result.IsSuccess = true;
result.EvaluationDetails.Add($"计算结果: {result.Result}");
}
catch (Exception ex)
{
result.ErrorMessage = $"表达式计算异常: {ex.Message}";
result.EvaluationDetails.Add($"异常详情: {ex}");
Log4Helper.Error($"表达式计算失败: {expression}", ex);
}
finally
{
stopwatch.Stop();
result.ExecutionTimeMs = stopwatch.ElapsedMilliseconds;
}
return result;
}
///
/// 验证表达式语法
///
public ExpressionValidationResult ValidateExpression(string expression)
{
var result = new ExpressionValidationResult();
if (string.IsNullOrWhiteSpace(expression))
{
result.Errors.Add("表达式不能为空");
return result;
}
try
{
// 提取变量代码
result.VariableCodes = ExtractVariableCodes(expression);
if (!result.VariableCodes.Any())
{
result.Warnings.Add("表达式中未找到变量代码");
}
// 基本语法检查
if (!IsValidJavaScriptExpression(expression))
{
result.Errors.Add("表达式语法不正确");
}
result.IsValid = !result.Errors.Any();
}
catch (Exception ex)
{
result.Errors.Add($"表达式验证异常: {ex.Message}");
}
return result;
}
///
/// 提取表达式中的变量代码
///
public List ExtractVariableCodes(string expression)
{
if (string.IsNullOrWhiteSpace(expression))
return new List();
var matches = VariableCodeRegex.Matches(expression);
return matches.Cast()
.Select(m => m.Groups[1].Value)
.Distinct()
.ToList();
}
#region 私有方法
///
/// 获取变量值
///
private async Task> GetVariableValuesAsync(
List variableCodes,
int timeWindowSeconds,
CancellationToken cancellationToken)
{
var result = new Dictionary();
foreach (var code in variableCodes)
{
try
{
var value = await GetSingleVariableValueAsync(code, timeWindowSeconds, cancellationToken);
result[code] = value;
}
catch (Exception ex)
{
Log4Helper.Warning($"获取变量 {code} 的值失败: {ex.Message}");
result[code] = 0; // 默认值
}
}
return result;
}
///
/// 获取单个变量的值
///
private async Task