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();
}
}
}
}
}