You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
7.0 KiB
C#

using DS.Module.Core.Data;
namespace DS.Module.Core.Condition
{
public class ConditionHelper
{
/// <summary>
/// 根据ContitionContent条件从数据上下文TaskFlowDataContext中取出指定数据然后判断条件是否符合
/// </summary>
3 months ago
public static bool IsPass(ConditionContent conditionContent, TaskFlowDataContext dataContext)
{
bool? thisScopeResult = null;
if (conditionContent == null || conditionContent.Conditions == null || conditionContent.Conditions.Count == 0)
{
return true;
}
IDictionary<string, object>? dataDic = null;
3 months ago
if (!string.IsNullOrEmpty(conditionContent.SourceName) && dataContext.ContainsKey(conditionContent.SourceName))
{
dataDic = dataContext[conditionContent.SourceName] as IDictionary<string, object>;
}
foreach (var item in conditionContent.Conditions)
{
var itemResult = false;
string? valStr = null;
3 months ago
if (dataDic != null && dataDic.TryGetValue(item.Field, out object? objVal))
{
3 months ago
valStr = objVal?.ToString();
}
else if (dataContext.ContainsKey(item.Field))
{
var obj = dataContext.Get<object>(item.Field)!;
valStr = obj.ToString();
}
else if (item.Field!.Contains('.'))
{
var firstKey = item.Field.Split('.').First();
if (dataContext.ContainsKey(firstKey))
{
var obj = dataContext.Get<object>(firstKey)!;
var propertyPath = item.Field.Substring(item.Field.IndexOf('.') + 1);
var (_, val, _) = GetPropertyValue(obj, propertyPath);
if (val != null)
valStr = val.ToString();
}
}
switch (item.Operator)
{
case "equal":
itemResult = (valStr == null && item.Value == null) || valStr?.Equals(item.Value, StringComparison.OrdinalIgnoreCase) == true; break;
case "not_equal":
itemResult = (valStr != null || item.Value != null) && valStr?.Equals(item.Value, StringComparison.OrdinalIgnoreCase) != true; break;
case "contains":
itemResult = valStr?.Contains(item.Value, StringComparison.OrdinalIgnoreCase) == true; break;
case "not_contain":
itemResult = valStr?.Contains(item.Value, StringComparison.OrdinalIgnoreCase) != true; break;
case "empty":
itemResult = string.IsNullOrWhiteSpace(valStr) == true; break;
case "not_empty":
itemResult = string.IsNullOrWhiteSpace(valStr) != true; break;
case "start_with":
itemResult = valStr?.StartsWith(item.Value, StringComparison.OrdinalIgnoreCase) == true; break;
case "end_with":
itemResult = valStr?.EndsWith(item.Value, StringComparison.OrdinalIgnoreCase) == true; break;
case "greater_than":
{
itemResult = double.TryParse(valStr, out double temp1) && double.TryParse(item.Value, out double temp2) && temp1 > temp2; break;
}
case "greater_than_or_equal":
{
itemResult = double.TryParse(valStr, out double temp1) && double.TryParse(item.Value, out double temp2) && temp1 >= temp2; break;
}
case "less_than":
{
itemResult = double.TryParse(valStr, out double temp1) && double.TryParse(item.Value, out double temp2) && temp1 < temp2; break;
}
case "less_than_or_equal":
{
itemResult = double.TryParse(valStr, out double temp1) && double.TryParse(item.Value, out double temp2) && temp1 <= temp2; break;
}
}
if (thisScopeResult == null)
{
thisScopeResult = itemResult;
}
else
{
if (conditionContent.LogicalOperator == "and")
{
thisScopeResult = thisScopeResult.Value && itemResult;
}
else if (conditionContent.LogicalOperator == "or")
{
thisScopeResult = thisScopeResult.Value || itemResult;
}
}
}
//thisScopeResult ??= true; // 实际这里的thisScopeResult的值啃腚不为null
if (conditionContent.Groups != null && conditionContent.Groups.Count > 0)
{
// 组的结果
var groupResult = new List<bool>();
foreach (var item in conditionContent.Groups)
{
// 递归调用,向组里添加结果
groupResult.Add(IsPass(item, dataContext));
}
if (conditionContent.LogicalOperator == "and")
{
return thisScopeResult == true && groupResult.All(a => a);
}
else if (conditionContent.LogicalOperator == "or")
{
return thisScopeResult == true || groupResult.Any(a => a);
}
}
return thisScopeResult == true;
}
/// <summary>
/// 深度获取对象属性值
/// </summary>
/// <param name="obj">对象</param>
/// <param name="propertyPath">属性路径</param>
static (bool isOk, object? val, string? otherPropertyPath) GetPropertyValue(object obj, string propertyPath)
{
var propertyName = propertyPath.Split('.').FirstOrDefault();
var type = obj.GetType();
var property = type.GetProperty(propertyName);
if (property == null)
{
return (true, null, null);
}
if (property.PropertyType.IsClass && property.PropertyType != typeof(string))
{
var val = property.GetValue(obj);
if (val == null)
{
return (true, null, null);
}
var otherPropertyPath = propertyPath.Substring(propertyPath.IndexOf('.') + 1);
return GetPropertyValue(val, otherPropertyPath);
}
else
{
var val = property.GetValue(obj);
return (true, val, null);
}
}
}
}