using Pas.ScadaService.Model; using Spring.Expressions; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using System; using System.Collections.Concurrent; using NewLife.Serialization; namespace Pas.ScadaService.Core { public class GopTimeCalc { /// /// 点位关联 /// private static readonly ConcurrentDictionary> ChangeDic = new ConcurrentDictionary>(); /// /// 所有时间 /// private static readonly ConcurrentDictionary AllData = new ConcurrentDictionary(); private static IFreeSql Db { get; set; } /// /// 加载配置 /// public static void Load(string config, string sql, List obj) { var inputObject = System.IO.File.ReadAllText(config); var conditionDtoList = inputObject.ToJsonEntity>(); foreach (var item in conditionDtoList) { if (ChangeDic.TryGetValue(HandleParam(item.Change.Replace("@(", "").Replace(")", "")), out var value)) { value.Add(item); } else { ChangeDic.TryAdd(HandleParam(item.Change.Replace("@(", "").Replace(")", "")), new List { item }); } } //初始化数据库 Db = new FreeSql.FreeSqlBuilder() .UseConnectionString(FreeSql.DataType.SqlServer, sql) .Build(); //初始化数据 InitData(obj); } /// /// 初始化数据事件 /// /// private static void InitData(List obj) { foreach (var data in obj) { var key = HandleParam(data.ItemId); if (!AllData.ContainsKey(key)) { AllData.TryAdd(key, data); } } SyncDb(obj); } /// /// 监听事件 /// /// public static void ChangeData(List obj) { foreach (var data in obj) { var key = HandleParam(data.ItemId); if (AllData.ContainsKey(key)) { AllData[key] = data; } } SyncDb(obj); } /// /// 计算点位 /// /// public static List CalcPoints(List obj) { var result = new List(); var resultValue = AllData .ToDictionary(data => data.Key, data => GetValue(data.Value.Value.ToString(), data.Value.DataType)); foreach (var data in obj) { if (!ChangeDic.TryGetValue(HandleParam(data.ItemId), out var conditionDtoList)) continue; foreach (var conditionDto in conditionDtoList) { var conditionValue = conditionDto.Value; var conditionParams = GetConditionParams(conditionValue); var tagNames = new List(); //修正表达式 foreach (var conditionParam in conditionParams) { var replace = HandleParam(conditionParam .Replace("@(", "#") .Replace(")", "")); tagNames.Add(replace.Substring(1)); conditionValue = conditionValue.Replace(conditionParam, replace); } var value = (bool)ExpressionEvaluator.GetValue(null, conditionValue, resultValue); if (!value) continue; var time = AllData.Where(c => tagNames.Contains(c.Key)) .Select(c => HandleTime(c.Value.TimeStamp)) .OrderByDescending(DateTime.Parse) .FirstOrDefault(); result.Add(new CustomLive { CreateTime = DateTime.Now, GroupName = "", ProduceBatch = "批次未知", TagName = conditionDto.Name, Value = time, Visible = true }); } } return result; } private static object GetValue(string value, string type) { switch (type.ToLower()) { case "string": return value; case "bool": return value=="1" || value.ToLower()== "true"; case "int": return value.ToInt(); default: return value.ToDecimal(); } } /// /// 处理参数 /// /// /// private static string HandleParam(string param) { return param.Replace(" ", "__").Replace(".", "___"); } private static string HandleTime(string time) { var last = time.Split(':').Last(); var lastLength = last.Length + 1; return time.Substring(0, time.Length - lastLength) + "." + last; } /// /// 解析参数 /// /// /// private static List GetConditionParams(string condition) { var pattern = @"\@\((.*?)\)"; var regex = new Regex(pattern); var matches = regex.Matches(condition); return (from Match match in matches select match.Groups[0].Value).ToList(); } /// /// 同步到数据库 /// /// private static void SyncDb(List obj) { var customLives = CalcPoints(obj); foreach (var item in customLives) { if (Db.Queryable() .Where(c => c.TagName == item.TagName && c.ProduceBatch == "批次未知") .Any()) { Db.Update() .Set(a => a.Value, item.Value) .Set(a => a.CreateTime, DateTime.Now) .Where(a => a.TagName == item.TagName) .Where(a => a.ProduceBatch == "批次未知") .ExecuteAffrows(); } else { Db.Insert(item).ExecuteAffrows(); } } } } }