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(); 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 ruleOld,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中肯定是找不到的,可以用之前的ruleOld _expressionCache.TryRemove(ruleOld.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; } /// /// 将规则表达式预编译并缓存到字典中 /// /// 要缓存的规则 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); // 只定义参数类型,不传值 // 编译为强类型委托 var compiledFunc = lambda.Compile>(); // 存入缓存 _expressionCache[rule.Name] = compiledFunc; } 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 ApplyExpressionFast(double value, LogicRuleDto rule) { try { if (!_expressionCache.TryGetValue(rule.Name, out var CurActiveFunc)) { CacheExpression(rule); if (!_expressionCache.TryGetValue(rule.Name, out CurActiveFunc)) return value; } // 直接调用委托,无反射开销 return CurActiveFunc(value); } catch { return value; } } /// /// 如果需要对多个数据应用相同规则,考虑实现批处理版本: /// /// /// /// public IEnumerable ApplyExpressionBatch(IEnumerable values, LogicRuleDto rule) { if (!_expressionCache.TryGetValue(rule.Name, out var func)) { CacheExpression(rule); if (!_expressionCache.TryGetValue(rule.Name, out func)) return values; } // 使用并行处理大量数据 return values.AsParallel().Select(v => { try { return func(v); } catch { return v; } }); } } }