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.

315 lines
14 KiB
C#

using DS.Module.Core.Data;
namespace DS.Module.Core.Condition
{
public class ConditionHelper
{
/// <summary>
/// 根据ContitionContent条件从数据上下文TaskFlowDataContext中取出指定数据然后判断条件是否符合
/// </summary>
4 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;
4 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;
object? val = null;
if (dataDic != null && dataDic.TryGetValue(item.Field, out val))
{ }
else if (dataContext.ContainsKey(item.Field))
{
val = dataContext.Get<object>(item.Field)!;
}
else if (item.Field!.Contains('.'))
{
var firstKey = item.Field.Split('.').First();
if (dataContext.ContainsKey(firstKey))
{
var firstVal = dataContext.Get<object>(firstKey)!;
if (firstVal != null)
{
var propertyPath = item.Field.Substring(item.Field.IndexOf('.') + 1);
val = GetPropertyValue(firstVal, propertyPath).val;
}
}
}
switch (item.ValueType)
{
case "bool":
{
bool? judgeVal = null;
if (val is bool || (val != null && val.GetType() == typeof(bool?)))
{
judgeVal = (bool?)val;
}
else
{
if (bool.TryParse(val?.ToString(), out bool result))
{
judgeVal = result;
}
}
bool conditionVal = false;
switch (item.Value)
{
case "是":
case "true":
case "True":
conditionVal = true;
break;
}
switch (item.Operator)
{
case "equal":
itemResult = judgeVal == conditionVal; break;
case "not_equal":
itemResult = judgeVal != conditionVal; break;
case "empty":
itemResult = judgeVal == null; break;
case "not_empty":
itemResult = judgeVal != null; break;
}
break;
}
case "number":
{
double? judgeVal = null;
if (val is System.ValueType)
{
judgeVal = Convert.ToDouble(val);
}
else
{
if (double.TryParse(val?.ToString(), out double result))
{
judgeVal = result;
}
}
double? conditionVal = null;
if (double.TryParse(item.Value, out double temp))
{
conditionVal = temp;
}
switch (item.Operator)
{
case "equal":
itemResult = judgeVal == conditionVal; break;
case "not_equal":
itemResult = judgeVal != conditionVal; break;
case "empty":
itemResult = judgeVal == null; break;
case "not_empty":
itemResult = judgeVal != null; break;
case "greater_than":
itemResult = judgeVal != null && conditionVal != null && judgeVal > conditionVal; break;
case "greater_than_or_equal":
itemResult = judgeVal != null && conditionVal != null && judgeVal >= conditionVal; break;
case "less_than":
itemResult = judgeVal != null && conditionVal != null && judgeVal < conditionVal; break;
case "less_than_or_equal":
itemResult = judgeVal != null && conditionVal != null && judgeVal <= conditionVal; break;
}
break;
}
case "datetime":
{
DateTime? judgeVal = null;
if (val is DateTime || (val != null && val.GetType() == typeof(DateTime?)))
{
judgeVal = (DateTime?)val;
}
else
{
if (DateTime.TryParse(val?.ToString(), out DateTime result))
{
judgeVal = result;
}
}
DateTime? conditionVal = null;
if (DateTime.TryParse(item.Value, out DateTime temp))
{
conditionVal = temp;
}
switch (item.Operator)
{
case "equal":
itemResult = judgeVal == conditionVal; break;
case "not_equal":
itemResult = judgeVal != conditionVal; break;
case "empty":
itemResult = judgeVal == null; break;
case "not_empty":
itemResult = judgeVal != null; break;
case "greater_than":
itemResult = judgeVal != null && conditionVal != null && judgeVal > conditionVal; break;
case "greater_than_or_equal":
itemResult = judgeVal != null && conditionVal != null && judgeVal >= conditionVal; break;
case "less_than":
itemResult = judgeVal != null && conditionVal != null && judgeVal < conditionVal; break;
case "less_than_or_equal":
itemResult = judgeVal != null && conditionVal != null && judgeVal <= conditionVal; break;
}
break;
}
//case "array": 暂未测试
// {
// IEnumerable<string> judgeVal = [];
// if (val is IEnumerable<string> && val != null)
// {
// judgeVal = (IEnumerable<string>)val;
// }
// IEnumerable<string> conditionVal = [];
// if (!string.IsNullOrEmpty(item.Value))
// {
// var temp = item.Value.Replace("", ",").Replace(";", ",").Replace("", ",");
// conditionVal = temp.Split(",");
// }
// switch (item.Operator)
// {
// case "contains":
// itemResult = !conditionVal.Except(judgeVal).Any(); break;
// case "not_contains":
// itemResult = conditionVal.Except(judgeVal).Any(); break;
// case "empty":
// itemResult = judgeVal.Count() == 0; break;
// case "not_empty":
// itemResult = judgeVal.Count() > 0; break;
// }
// break;
// }
default:
case "string":
{
string judgeVal = val?.ToString() ?? "";
string conditionVal = item.Value ??= "";
switch (item.Operator)
{
case "equal":
itemResult = judgeVal.Equals(conditionVal, StringComparison.OrdinalIgnoreCase); break;
case "not_equal":
itemResult = !judgeVal.Equals(conditionVal, StringComparison.OrdinalIgnoreCase); break;
case "contains":
itemResult = judgeVal.Contains(conditionVal, StringComparison.OrdinalIgnoreCase); break;
case "not_contains":
itemResult = !judgeVal.Contains(conditionVal, StringComparison.OrdinalIgnoreCase); break;
case "empty":
itemResult = string.IsNullOrWhiteSpace(judgeVal); break;
case "not_empty":
itemResult = !string.IsNullOrWhiteSpace(judgeVal); break;
case "start_with":
itemResult = judgeVal.StartsWith(conditionVal, StringComparison.OrdinalIgnoreCase); break;
case "end_with":
itemResult = judgeVal.EndsWith(conditionVal, StringComparison.OrdinalIgnoreCase); break;
}
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="condition"></param>
/// <returns></returns>
public static int GetConditionCount(ConditionContent condition)
{
int n = condition.Conditions?.Count ?? 0;
if (condition.Groups != null && condition.Groups.Count > 0)
{
n += condition.Groups.Sum(GetConditionCount);
}
return n;
}
/// <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);
}
}
}
}