using DS.Module.Core.Data; namespace DS.Module.Core.Condition { public class ConditionHelper { /// /// 根据ContitionContent条件,从数据上下文TaskFlowDataContext中取出指定数据,然后判断条件是否符合 /// public static bool IsPass(ConditionContent conditionContent, TaskFlowDataContext dataContext) { bool? thisScopeResult = null; if (conditionContent == null || conditionContent.Conditions == null || conditionContent.Conditions.Count == 0) { return true; } IDictionary? dataDic = null; if (!string.IsNullOrEmpty(conditionContent.SourceName) && dataContext.ContainsKey(conditionContent.SourceName)) { dataDic = dataContext[conditionContent.SourceName] as IDictionary; } 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(item.Field)!; } else if (item.Field!.Contains('.')) { var firstKey = item.Field.Split('.').First(); if (dataContext.ContainsKey(firstKey)) { var firstVal = dataContext.Get(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; } 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_contain": 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(); 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; } /// /// 获取指定条件的条件数量 /// /// /// 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; } /// /// 深度获取对象属性值 /// /// 对象 /// 属性路径 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); } } } }