- gRPC auth service for token validation - Value comparator system (string, numeric, boolean, datetime, collection) - Condition evaluator with strategy chain - Form definition and data improvements - Workflow instance/task endpoints updated - Seed data and EF design-time factory - Test coverage for comparators and handlers
134 lines
4.5 KiB
C#
134 lines
4.5 KiB
C#
using System.Globalization;
|
|
using System.Text.Json;
|
|
|
|
namespace Workflow.Domain.Expressions.Comparators;
|
|
|
|
/// <summary>
|
|
/// 值对比器共享的静态工具方法。从 ConditionEvaluator 中提取,
|
|
/// 供所有内置对比器复用。
|
|
/// </summary>
|
|
public static class ValueComparatorHelper
|
|
{
|
|
public static bool TryGetDecimal(object? value, out decimal result)
|
|
{
|
|
result = 0m;
|
|
return value switch
|
|
{
|
|
decimal d => SetResult(d, out result),
|
|
double db => SetResult((decimal)db, out result),
|
|
float f => SetResult((decimal)f, out result),
|
|
int i => SetResult((decimal)i, out result),
|
|
long l => SetResult((decimal)l, out result),
|
|
short s => SetResult((decimal)s, out result),
|
|
byte b => SetResult((decimal)b, out result),
|
|
uint ui => SetResult((decimal)ui, out result),
|
|
ulong ul => SetResult((decimal)ul, out result),
|
|
string str => decimal.TryParse(str, out result),
|
|
JsonElement e => TryGetDecimalFromElement(e, out result),
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
public static bool TryGetDecimalFromElement(JsonElement element, out decimal result)
|
|
{
|
|
result = 0m;
|
|
if (element.ValueKind == JsonValueKind.Number)
|
|
return element.TryGetDecimal(out result);
|
|
|
|
if (element.ValueKind == JsonValueKind.String)
|
|
{
|
|
var str = element.GetString();
|
|
return str is not null && decimal.TryParse(str, out result);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool TryGetDateTime(object? value, out DateTime result)
|
|
{
|
|
result = DateTime.MinValue;
|
|
return value switch
|
|
{
|
|
DateTime dt => SetResult(dt, out result),
|
|
DateTimeOffset dto => SetResult(dto.UtcDateTime, out result),
|
|
string s => DateTime.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out result),
|
|
JsonElement e => TryGetDateTimeFromElement(e, out result),
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
public static bool TryGetDateTimeFromElement(JsonElement element, out DateTime result)
|
|
{
|
|
result = DateTime.MinValue;
|
|
if (element.ValueKind == JsonValueKind.String)
|
|
{
|
|
var str = element.GetString();
|
|
return str is not null && DateTime.TryParse(str, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out result);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static bool TryGetBoolean(object? value, out bool result)
|
|
{
|
|
result = false;
|
|
return value switch
|
|
{
|
|
bool b => SetResult(b, out result),
|
|
string s => bool.TryParse(s, out result),
|
|
JsonElement e => TryGetBooleanFromElement(e, out result),
|
|
_ => false
|
|
};
|
|
}
|
|
|
|
public static bool TryGetBooleanFromElement(JsonElement element, out bool result)
|
|
{
|
|
result = false;
|
|
if (element.ValueKind == JsonValueKind.True) { result = true; return true; }
|
|
if (element.ValueKind == JsonValueKind.False) { result = false; return true; }
|
|
if (element.ValueKind == JsonValueKind.String)
|
|
{
|
|
var str = element.GetString();
|
|
return str is not null && bool.TryParse(str, out result);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static string? GetStringValue(object? value)
|
|
{
|
|
return value switch
|
|
{
|
|
null => null,
|
|
string s => s,
|
|
JsonElement e => e.ValueKind == JsonValueKind.String ? e.GetString() : e.GetRawText(),
|
|
_ => value.ToString()
|
|
};
|
|
}
|
|
|
|
public static bool TryGetDecimalFromCondition(object? conditionValue, out decimal result)
|
|
{
|
|
if (conditionValue is string s)
|
|
return decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out result);
|
|
return TryGetDecimal(conditionValue, out result);
|
|
}
|
|
|
|
public static bool TryGetDateTimeFromCondition(object? conditionValue, out DateTime result)
|
|
{
|
|
if (conditionValue is string s)
|
|
return DateTime.TryParse(s, CultureInfo.InvariantCulture, DateTimeStyles.RoundtripKind, out result);
|
|
return TryGetDateTime(conditionValue, out result);
|
|
}
|
|
|
|
public static bool TryGetBooleanFromCondition(object? conditionValue, out bool result)
|
|
{
|
|
if (conditionValue is string s)
|
|
return bool.TryParse(s, out result);
|
|
return TryGetBoolean(conditionValue, out result);
|
|
}
|
|
|
|
private static bool SetResult<T>(T value, out T result)
|
|
{
|
|
result = value;
|
|
return true;
|
|
}
|
|
}
|