133 lines
4.2 KiB
C#
133 lines
4.2 KiB
C#
using DynamicExpresso;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
|
|
namespace MesWork
|
|
{
|
|
/// <summary>
|
|
/// 重量标定公式计算工具。
|
|
/// </summary>
|
|
public static class WeightCalibrationHelper
|
|
{
|
|
private class CalibrationCache
|
|
{
|
|
public string ToolName;
|
|
public string CalibrationValue;
|
|
public string Formula;
|
|
public string Description;
|
|
public DateTime LoadedAt;
|
|
}
|
|
|
|
private static readonly object CacheLock = new object();
|
|
private static readonly Dictionary<string, CalibrationCache> Cache = new Dictionary<string, CalibrationCache>(StringComparer.OrdinalIgnoreCase);
|
|
private static readonly TimeSpan CacheLife = TimeSpan.FromSeconds(3);
|
|
|
|
public static bool Apply(string opName, decimal rawWeight, out decimal calibratedWeight, out string formula, out string message)
|
|
{
|
|
calibratedWeight = rawWeight;
|
|
formula = "x";
|
|
message = "";
|
|
|
|
if (!TryGetConfig(opName, out CalibrationCache config, out string queryMsg))
|
|
{
|
|
message = string.IsNullOrWhiteSpace(queryMsg) ? "未找到工具标定配置" : queryMsg;
|
|
return false;
|
|
}
|
|
|
|
formula = NormalizeFormula(config.Formula);
|
|
return TryEvaluateFormula(formula, rawWeight, out calibratedWeight, out message);
|
|
}
|
|
|
|
public static void ClearCache()
|
|
{
|
|
lock (CacheLock)
|
|
{
|
|
Cache.Clear();
|
|
}
|
|
}
|
|
|
|
public static bool ValidateFormula(string formula, out string message)
|
|
{
|
|
decimal _;
|
|
return TryEvaluateFormula(NormalizeFormula(formula), 1M, out _, out message);
|
|
}
|
|
|
|
private static string NormalizeFormula(string formula)
|
|
{
|
|
return string.IsNullOrWhiteSpace(formula) ? "" : formula.Trim();
|
|
}
|
|
|
|
private static bool TryEvaluateFormula(string formula, decimal xValue, out decimal result, out string message)
|
|
{
|
|
result = xValue;
|
|
message = "";
|
|
|
|
if (string.IsNullOrWhiteSpace(formula))
|
|
{
|
|
message = "计算公式不能为空,至少填写 x";
|
|
return false;
|
|
}
|
|
|
|
try
|
|
{
|
|
var interpreter = new Interpreter();
|
|
interpreter.Reference(typeof(Math));
|
|
double x = Convert.ToDouble(xValue);
|
|
interpreter.SetVariable("x", x);
|
|
interpreter.SetVariable("X", x);
|
|
|
|
object value = interpreter.Eval(formula);
|
|
if (value == null)
|
|
{
|
|
message = "计算公式未返回数值";
|
|
return false;
|
|
}
|
|
|
|
result = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
|
|
return true;
|
|
}
|
|
catch (Exception err)
|
|
{
|
|
message = $"计算公式错误:{err.Message}";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private static bool TryGetConfig(string opName, out CalibrationCache config, out string message)
|
|
{
|
|
config = null;
|
|
message = "";
|
|
string key = string.IsNullOrWhiteSpace(opName) ? "" : opName.Trim();
|
|
|
|
lock (CacheLock)
|
|
{
|
|
if (Cache.TryGetValue(key, out config) && DateTime.Now - config.LoadedAt < CacheLife)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
if (!B_DB_Opera.QueryToolCalibration(key, out string toolName, out string calibrationValue, out string formula, out string description, out message))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
config = new CalibrationCache
|
|
{
|
|
ToolName = toolName,
|
|
CalibrationValue = calibrationValue,
|
|
Formula = formula,
|
|
Description = description,
|
|
LoadedAt = DateTime.Now
|
|
};
|
|
|
|
lock (CacheLock)
|
|
{
|
|
Cache[key] = config;
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
}
|