288 lines
8.2 KiB
C#
288 lines
8.2 KiB
C#
using Newtonsoft.Json;
|
||
using PropertyChanged;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Collections.ObjectModel;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace ATS.Models
|
||
{
|
||
[AddINotifyPropertyChangedInterface]
|
||
public class ParameterModel
|
||
{
|
||
|
||
#region 构造函数
|
||
|
||
public ParameterModel()
|
||
{
|
||
|
||
}
|
||
|
||
public ParameterModel(ParameterModel source)
|
||
{
|
||
if (source == null) return;
|
||
|
||
ID = source.ID;
|
||
Name = source.Name;
|
||
Type = source.Type;
|
||
Category = source.Category;
|
||
IsUseVar = source.IsUseVar;
|
||
IsSave = source.IsSave;
|
||
VariableName = source.VariableName;
|
||
VariableID = source.VariableID;
|
||
IsGlobal = source.IsGlobal;
|
||
Value = source.Value;
|
||
LowerLimit = source.LowerLimit;
|
||
UpperLimit = source.UpperLimit;
|
||
IsOutputToReport = source.IsOutputToReport;
|
||
}
|
||
|
||
#endregion
|
||
|
||
public Guid ID { get; set; } = Guid.NewGuid();
|
||
|
||
public bool IsVisible { get; set; } = true;
|
||
|
||
public string Name { get; set; }
|
||
|
||
public Type? Type { get; set; } = typeof(string);
|
||
|
||
public ParameterCategory Category { get; set; } = ParameterCategory.Temp;
|
||
|
||
public bool IsGlobal { get; set; }
|
||
|
||
public object? Value { get; set; }
|
||
|
||
public object? LowerLimit { get; set; }
|
||
|
||
public object? UpperLimit { get; set; }
|
||
|
||
public bool Result { get; set; } = true;
|
||
|
||
public bool IsUseVar { get; set; }
|
||
|
||
public bool IsSave { get; set; }
|
||
|
||
public string? VariableName { get; set; }
|
||
|
||
public Guid? VariableID { get; set; }
|
||
|
||
/// <summary>
|
||
/// 是否输出到报告(仅对输出参数有效,默认为false)
|
||
/// </summary>
|
||
public bool IsOutputToReport { get; set; } = false;
|
||
|
||
public enum ParameterCategory
|
||
{
|
||
Input,
|
||
Output,
|
||
Temp
|
||
}
|
||
|
||
public object? GetActualValue(Dictionary<Guid, ParameterModel> paraList)
|
||
{
|
||
// 用于检测循环引用的哈希集合
|
||
HashSet<Guid> visitedIds = [];
|
||
ParameterModel current = this;
|
||
|
||
while (current != null)
|
||
{
|
||
// 如果没有使用变量,则返回值
|
||
if (!current.IsUseVar)
|
||
{
|
||
return current.Value;
|
||
}
|
||
|
||
// 检测循环引用
|
||
if (visitedIds.Contains(current.ID))
|
||
{
|
||
return null;
|
||
}
|
||
visitedIds.Add(current.ID);
|
||
|
||
// 如果当前参数没有关联变量,则返回其实际值
|
||
if (current.VariableID == null)
|
||
{
|
||
if (Type != null && Value != null)
|
||
{
|
||
try
|
||
{
|
||
return Convert.ChangeType(Value, Type);
|
||
}
|
||
catch
|
||
{
|
||
return Value;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 查找下一个关联参数
|
||
ParameterModel? next = paraList[(Guid)current.VariableID!];
|
||
if (next == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
current = next;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取方法步骤中的返回值映射的主程序参数
|
||
/// </summary>
|
||
/// <param name="paraList"></param>
|
||
/// <returns></returns>
|
||
public ParameterModel? GetCurrentParameter(Dictionary<Guid, ParameterModel> paraList)
|
||
{
|
||
// 用于检测循环引用的哈希集合
|
||
HashSet<Guid> visitedIds = new HashSet<Guid>();
|
||
ParameterModel current = this;
|
||
|
||
while (current != null)
|
||
{
|
||
// 如果没有使用变量,则返回值
|
||
if (current.VariableID == null)
|
||
{
|
||
return current;
|
||
}
|
||
|
||
// 检测循环引用
|
||
if (visitedIds.Contains(current.ID))
|
||
{
|
||
return null;
|
||
}
|
||
visitedIds.Add(current.ID);
|
||
|
||
// 如果当前参数没有关联变量,则返回其实际值
|
||
if (current.VariableID == null)
|
||
{
|
||
if (Type != null && Value != null)
|
||
{
|
||
try
|
||
{
|
||
return current;
|
||
}
|
||
catch
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 查找下一个关联参数
|
||
ParameterModel? next = paraList[(Guid)current.VariableID!];
|
||
if (next == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
current = next;
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
public (bool, string?) GetResult()
|
||
{
|
||
|
||
if (Type == typeof(string) && (!string.IsNullOrWhiteSpace(LowerLimit?.ToString()) || !string.IsNullOrWhiteSpace(UpperLimit?.ToString())))
|
||
{
|
||
return (true, $"参数 [ {Name}({Type}) ] 不可比较");
|
||
}
|
||
|
||
// 当值或限制条件不存在时返回true
|
||
if (Value == null || (LowerLimit == null && UpperLimit == null))
|
||
{
|
||
return (true, null);
|
||
}
|
||
|
||
// 检查空字符串情况
|
||
if (string.IsNullOrWhiteSpace(Value?.ToString()) || (string.IsNullOrWhiteSpace(LowerLimit?.ToString()) && string.IsNullOrWhiteSpace(UpperLimit?.ToString())))
|
||
{
|
||
return (true, null);
|
||
}
|
||
|
||
// 尝试将值转换为可比较的类型
|
||
try
|
||
{
|
||
object? comparableValue = ConvertToComparable(Value);
|
||
object? comparableLower = LowerLimit != null ? ConvertToComparable(LowerLimit) : null;
|
||
object? comparableUpper = UpperLimit != null ? ConvertToComparable(UpperLimit) : null;
|
||
|
||
if (comparableValue == null)
|
||
{
|
||
return (true, $"参数 [ {Name}({Type}) ] 不可比较");
|
||
}
|
||
|
||
bool lowerValid = true;
|
||
bool upperValid = true;
|
||
|
||
// 处理下限比较
|
||
if (comparableLower != null)
|
||
{
|
||
lowerValid = CompareValues(comparableValue, comparableLower) >= 0;
|
||
}
|
||
|
||
// 处理上限比较
|
||
if (comparableUpper != null)
|
||
{
|
||
upperValid = CompareValues(comparableValue, comparableUpper) <= 0;
|
||
}
|
||
|
||
return (lowerValid && upperValid, null);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
return (true, $"参数 [ {Name}({Type}) ] 上下限比较失败:{ex.Message}");
|
||
}
|
||
}
|
||
|
||
private static object? ConvertToComparable(object value)
|
||
{
|
||
if (value is IConvertible convertible)
|
||
{
|
||
// 尝试转换为最适合比较的类型
|
||
try
|
||
{
|
||
return convertible.ToDouble(null);
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
try
|
||
{
|
||
return convertible.ToDateTime(null);
|
||
}
|
||
catch
|
||
{
|
||
|
||
}
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
private static int CompareValues(object a, object b)
|
||
{
|
||
// 优先尝试数值比较
|
||
if (a is double aDouble && b is double bDouble)
|
||
{
|
||
return aDouble.CompareTo(bDouble);
|
||
}
|
||
|
||
// 尝试日期比较
|
||
if (a is DateTime aDate && b is DateTime bDate)
|
||
{
|
||
return aDate.CompareTo(bDate);
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
}
|
||
}
|