using AutoMapper;
using CapMachine.Core;
using CapMachine.Model;
using CapMachine.Wpf.Dtos;
using DynamicExpresso;
using FreeSql;
using FreeSql.DataAnnotations;
using Prism.Mvvm;
using Syncfusion.Windows.Shared;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace CapMachine.Wpf.Services
{
///
/// 逻辑服务 - 用于处理数据逻辑转换
///
public class LogicRuleService : BindableBase
{
private readonly ILogService LogService;
private readonly IFreeSql FreeSql;
///
/// 逻辑转换规则集合
///
public ObservableCollection LogicRuleDtos { get; private set; }
///
/// DynamicExpresso解释器
///
private Interpreter CurInterpreter { get; set; }
public IMapper Mapper { get; }
///
/// 规则表达式缓存(高性能访问)
/// Key: 规则名称, Value: 已编译的Lambda表达式
///private readonly ConcurrentDictionary> _expressionCache;
///
private readonly ConcurrentDictionary _expressionCache;
/////
///// 创建包含指定值的参数数组
/////
//private Parameter[] CreateParameters(double value)
//{
// return new Parameter[]
// {
// new Parameter("value", typeof(double), value)
// };
//}
///
/// 创建包含指定值的参数
///
private Parameter CreateParameters(double value)
{
return new Parameter("value", typeof(double),value);
}
///
/// 实例化函数
///
public LogicRuleService(ILogService logService, IFreeSql freeSql, IMapper mapper)
{
LogService = logService;
FreeSql = freeSql;
Mapper = mapper;
// 初始化集合
LogicRuleDtos = new ObservableCollection();
_expressionCache = new ConcurrentDictionary();
// 初始化DynamicExpresso解释器
CurInterpreter = new Interpreter();
//.Reference(typeof(Math)) // 引用Math类
// //.SetVariable("Math", typeof(Math))
//.SetVariable("value", 0.2);
try
{
// 从数据库加载规则
LoadRulesFromDatabase();
}
catch (Exception ex)
{
LogService.Error($"初始化逻辑服务失败: {ex.Message}");
}
}
///
/// 从数据库加载规则
///
private void LoadRulesFromDatabase()
{
try
{
// 从数据库加载规则
var dbRules = FreeSql.Select().OrderBy(a => a.Id).ToList();
if (dbRules != null && dbRules.Count > 0)
{
LogicRuleDtos.Clear();
_expressionCache.Clear(); // 清空表达式缓存
foreach (var rule in dbRules)
{
LogicRuleDtos.Add(Mapper.Map(rule));
}
// 预编译所有表达式
WarmUpExpressionCache();
//LogService.Info($"已从数据库加载并预编译 {dbRules.Count} 条逻辑规则");
}
else
{
LogService.Warn("数据库中没有逻辑规则");
}
}
catch (Exception ex)
{
LogService.Error($"从数据库加载逻辑规则失败: {ex.Message}");
throw; // 重新抛出异常以便调用者处理
}
}
#region 增删改查LogicRule
///
/// 添加新规则
///
/// 规则对象
public void AddRule(LogicRule rule)
{
if (string.IsNullOrWhiteSpace(rule.Name))
{
MessageBox.Show("规则名称不能为空");
return;
}
if (string.IsNullOrWhiteSpace(rule.Expression))
{
MessageBox.Show("规则表达式不能为空");
return;
}
if (LogicRuleDtos.Where(a => a.Name == rule.Name).Any())
{
MessageBox.Show("已经有另一个相同名称的规则了");
return;
}
// 验证表达式是否有效
if (!ValidateExpression(rule.Expression))
{
MessageBox.Show("规则表达式验证失败");
return;
}
if (InsertRuleToDb(rule, out LogicRule resultInsert))
{
//此时的resultInsert有新增的ID
// 添加规则
LogicRuleDtos.Add(Mapper.Map(resultInsert));
// 预编译并缓存表达式
CacheExpression(Mapper.Map(resultInsert));
}
else
{
MessageBox.Show("增加数据失败!");
return;
}
//LogService.Info($"添加新规则: {rule.Name}");
}
///
/// 保存规格到数据库中
///
///
public bool InsertRuleToDb(LogicRule rule, out LogicRule ResultInsert)
{
try
{
// 插入规则到数据库
var result = FreeSql.Insert(rule).ExecuteInserted();
// 检查影响的行数
bool success = result.Count > 0;
if (success)
{
ResultInsert = result.FirstOrDefault()!;
return success;
//LogService.Info($"成功插入规则: {rule.Name}");
// 刷新内存中的规则集合
//LoadRulesFromDatabase();
}
else
{
LogService.Warn($"插入规则失败: {rule.Name},没有行受影响");
ResultInsert = null;
return success;
}
}
catch (Exception ex)
{
LogService.Error($"插入规则到数据库时发生异常: {ex.Message}");
ResultInsert = null;
return false;
}
}
///
/// 更新规则
///
/// 规则对象
public void UpdateRule(LogicRule rule)
{
if (string.IsNullOrWhiteSpace(rule.Name))
{
MessageBox.Show("规则名称不能为空");
return;
}
if (string.IsNullOrWhiteSpace(rule.Expression))
{
MessageBox.Show("规则表达式不能为空");
return;
}
// 验证表达式是否有效
if (!ValidateExpression(rule.Expression))
{
MessageBox.Show("规则表达式验证失败");
return;
}
if (UpdateRuleToDb(rule))
{
// 更新缓存
var updatedDto = LogicRuleDtos.FirstOrDefault(r => r.Id == rule.Id);
var insertIndex = LogicRuleDtos.ToList().FindIndex(x => x.Id > rule.Id);
if (updatedDto != null)
{
//移除数据
LogicRuleDtos.Remove(updatedDto);
if (insertIndex == -1)
{
LogicRuleDtos.Add(Mapper.Map(rule));
}
else
{
// 在找到的位置插入
LogicRuleDtos.Insert(insertIndex - 1, Mapper.Map(rule));
}
_expressionCache.TryRemove(updatedDto.Name, out _);
CacheExpression(updatedDto);
}
}
//LogService.Info($"更新规则: {rule.Name}");
}
///
/// 更新规格到数据库中
///
///
public bool UpdateRuleToDb(LogicRule rule)
{
try
{
// 更新规则到数据库
var result = FreeSql.Update()
.Set(a => a.Name, rule.Name)
.Set(a => a.Description, rule.Description)
.Set(a => a.Expression, rule.Expression)
.Set(a => a.ParameterType, rule.ParameterType)
.Where(r => r.Id == rule.Id)
.ExecuteUpdated();
// 检查影响的行数
bool success = result.Count() > 0;
if (success)
{
//LogService.Info($"成功更新规则: {rule.Name}");
}
else
{
//LogService.Warn($"更新规则失败: {rule.Name},没有行受影响");
}
return success;
}
catch (Exception ex)
{
//LogService.Error($"更新规则到数据库时发生异常: {ex.Message}");
return false;
}
}
///
/// 删除规则
///
/// 规则名称
public void DeleteRule(string ruleName)
{
var rule = LogicRuleDtos.FirstOrDefault(r => r.Name == ruleName);
if (rule == null)
{
MessageBox.Show("找不到删除的数据");
return;
}
var Count = FreeSql.Delete().Where(r => r.Id == rule.Id).ExecuteAffrows();
if (Count > 0)
{
// 删除规则
LogicRuleDtos.Remove(rule);
// 从缓存中移除表达式
_expressionCache.TryRemove(ruleName, out _);
}
//LogService.Info($"删除规则: {ruleName}");
}
///
/// 验证表达式是否有效
///
/// 表达式字符串
/// 表达式是否有效
private bool ValidateExpression(string expression)
{
try
{
// 创建测试解释器并直接设置变量
var interpreter = new Interpreter()
.Reference(typeof(Math)) // 引用Math类
.SetVariable("Math", typeof(Math))
.SetVariable("value", 100); // 直接设置值变量
// 尝试编译表达式
var lambda = interpreter.Parse(expression);
// 尝试执行表达式
var result = lambda.Invoke();
// 检查结果是否为数值类型
if (result is double doubleResult)
{
// 验证结果不是NaN或Infinity
if (double.IsNaN(doubleResult) || double.IsInfinity(doubleResult))
{
//LogService.Warn($"表达式执行结果无效 (NaN或Infinity): {expression}");
return false;
}
}
return true;
}
catch (Exception ex)
{
LogService.Warn($"验证表达式失败: {expression}, 错误: {ex.Message}");
return false;
}
}
#endregion
///
/// 根据参数类型获取适用的规则
///
/// 参数类型
/// 适用的规则列表
public IEnumerable GetRulesByParameterType(string parameterType)
{
return LogicRuleDtos.Where(r => r.ParameterType == parameterType);
}
///
/// 获取指定名称的规则
///
/// 规则名称
/// 规则对象
public LogicRuleDto GetRuleByName(string ruleName)
{
var rule = LogicRuleDtos.FirstOrDefault(r => r.Name == ruleName);
if (rule == null)
{
throw new KeyNotFoundException($"找不到名为 {ruleName} 的规则");
}
return rule;
}
///
/// 应用逻辑转换 - 主要使用方法
///
/// 输入值
/// 规则名称
/// 转换后的输出值
public double ApplyLogic(double value, string ruleName)
{
var rule = GetRuleByName(ruleName);
return ApplyExpression(value, rule);
}
///
/// 应用逻辑转换(基于参数类型自动选择规则)
///
/// 输入值
/// 参数类型
/// 转换后的输出值
public double ApplyLogicByType(double value, string parameterType)
{
var rules = GetRulesByParameterType(parameterType).ToList();
if (rules.Count == 0)
{
LogService.Warn($"未找到适用于 {parameterType} 的转换规则,将返回原始值");
return value;
}
// 如果存在多个规则,取第一个
var rule = rules.First();
return ApplyExpression(value, rule);
}
///
/// 将规则表达式预编译并缓存到字典中
///
/// 要缓存的规则
private void CacheExpression(LogicRuleDto rule)
{
if (string.IsNullOrEmpty(rule.Name) || string.IsNullOrEmpty(rule.Expression))
{
return; // 防止空名称或空表达式
}
try
{
// 使用已有的CreateParameters方法创建参数声明
var parameter = CreateParameters(0); // 值不重要,只是为了获取参数声明
// 只解析一次,得到 Lambda 对象
var lambda = CurInterpreter.Parse(rule.Expression, parameter); // 只定义参数类型,不传值
// 存入缓存
_expressionCache[rule.Name] = lambda;
}
catch (Exception ex)
{
LogService.Error($"缓存规则 {rule.Name} 表达式失败: {ex.Message}");
}
}
///
/// 预热表达式缓存 - 预编译所有规则
///
private void WarmUpExpressionCache()
{
foreach (var rule in LogicRuleDtos)
{
if (!_expressionCache.ContainsKey(rule.Name))
{
CacheExpression(rule);
}
}
LogService.Info($"已预编译 {_expressionCache.Count} 条规则表达式");
}
///
/// 根据规则应用表达式(高性能版本)
///
/// 输入值
/// 规则对象
/// 转换后的输出值
public double ApplyExpression(double value, LogicRuleDto rule)
{
try
{
// 尝试从缓存获取预编译的表达式
if (!_expressionCache.TryGetValue(rule.Name, out var compiledExpression))
{
// 如果缓存中没有,则编译并添加到缓存
CacheExpression(rule);
// 再次尝试获取
if (!_expressionCache.TryGetValue(rule.Name, out compiledExpression))
{
// 初始解析表达式(只需执行一次)
string expressionText = rule.Expression;
// 强类型函数
Func compiledFunc = (v) =>
{
// 高性能版本:直接根据公式计算
try
{
if (expressionText.Contains("value"))
{
var parameters = CreateParameters(v);
var lambda = CurInterpreter.Parse(expressionText, parameters);
return (double)lambda.Invoke();
}
else
{
// 简单表达式使用直接求值
return v / 100.0; // 默认处理
}
}
catch
{
// 出错时返回原值
return v;
}
};
// 再次尝试缓存
CacheExpression(rule);
return compiledFunc(value);
}
}
// 创建包含实际值的参数
var parameter = new Parameter("value", typeof(double), value);
// 使用预编译的表达式执行计算(高性能)
var convertedValue = (double)compiledExpression.Invoke(value);
return convertedValue;
}
catch (Exception ex)
{
//LogService.Error($"应用规则 {rule.Name} 失败: {ex.Message}");
return value; // 出错时返回原始值
}
}
///
/// 临时测试用
///
///
///
///
public double ApplyExpressionNoCache(double value, LogicRuleDto rule)
{
try
{
CurInterpreter.SetVariable("value", value);
var lambda = CurInterpreter.Parse(rule.Expression);
return (double)lambda.Invoke();
//// 创建全新的解释器实例
//var localInterpreter = new Interpreter()
// .Reference(typeof(Math))
// .SetVariable("Math", typeof(Math));
//// 直接设置变量值而不是使用参数
//localInterpreter.SetVariable("value", value);
//// 解析并执行
//var result = localInterpreter.Eval(rule.Expression);
//Console.WriteLine($"直接执行: 输入={value}, 表达式={rule.Expression}, 结果={result}");
//return result;
}
catch (Exception ex)
{
LogService.Error($"直接执行表达式失败: {ex.Message}");
return value;
}
}
///
/// 批量应用逻辑转换 (高性能版本)
///
/// 原始值字典(键为参数名称,值为原始值)
/// 转换后的值字典
public Dictionary ApplyBatchLogic(Dictionary values)
{
// 为了性能,预分配容量
var result = new Dictionary(values.Count);
// 缓存参数类型到规则的映射,避免重复查询
var cachedRulesByType = new Dictionary();
foreach (var entry in values)
{
var paramName = entry.Key;
var origValue = entry.Value;
try
{
// 获取参数类型
var paramType = DetermineParameterType(paramName);
// 尝试从缓存获取规则
if (!cachedRulesByType.TryGetValue(paramType, out var rule))
{
var rules = GetRulesByParameterType(paramType).ToList();
if (rules.Count > 0)
{
rule = rules.First();
cachedRulesByType[paramType] = rule; // 添加到缓存
}
}
// 如果找到规则,应用转换
if (rule != null)
{
var convertedValue = ApplyExpression(origValue, rule);
result.Add(paramName, convertedValue);
}
else
{
result.Add(paramName, origValue); // 没有规则时使用原始值
}
}
catch (Exception ex)
{
LogService.Error($"处理参数 {paramName} 失败: {ex.Message}");
result.Add(paramName, origValue); // 出错时使用原始值
}
}
return result;
}
///
/// 从参数名称确定参数类型
///
/// 参数名称
/// 参数类型
private string DetermineParameterType(string paramName)
{
// 根据参数名称确定类型的逻辑
// 这里使用简单的名称匹配,实际项目中可能需要更复杂的映射
if (paramName.Contains("速度") || paramName.Contains("转速"))
return "转速";
else if (paramName.Contains("功率") || paramName.Contains("pw") || paramName.Contains("power"))
return "功率";
else if (paramName.Contains("温度") || paramName.Contains("temp"))
return "温度";
else if (paramName.Contains("压力") || paramName.Contains("press"))
return "压力";
// 默认类型
return "通用";
}
}
}