fengling-risk-control/Fengling.RiskControl.Domain/Aggregates/RiskScores/RiskScore.cs

62 lines
1.9 KiB
C#

using NetCorePal.Extensions.Domain;
namespace Fengling.RiskControl.Domain.Aggregates.RiskScores;
public class RiskScore : Entity<long>, IAggregateRoot
{
public long MemberId { get; private set; }
public string EntityType { get; private set; } = string.Empty;
public string EntityId { get; private set; } = string.Empty;
public int TotalScore { get; private set; }
public RiskLevel RiskLevel { get; private set; }
private readonly List<RiskFactor> _factors = new();
public IReadOnlyCollection<RiskFactor> Factors => _factors.AsReadOnly();
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
public DateTime? ExpiresAt { get; private set; }
private RiskScore() { }
public static RiskScore Create(long memberId, string entityType, string entityId,
DateTime? expiresAt = null)
{
return new RiskScore
{
MemberId = memberId,
EntityType = entityType,
EntityId = entityId,
TotalScore = 0,
RiskLevel = RiskLevel.Low,
ExpiresAt = expiresAt
};
}
public void AddRiskFactor(string factorType, int points, string description)
{
_factors.Add(RiskFactor.Create(factorType, points, description));
RecalculateScore();
}
public void Reset()
{
_factors.Clear();
TotalScore = 0;
RiskLevel = RiskLevel.Low;
}
private static readonly int HIGH_THRESHOLD = 70;
private static readonly int MEDIUM_THRESHOLD = 30;
private void RecalculateScore()
{
TotalScore = _factors.Sum(f => f.Points);
RiskLevel = TotalScore >= HIGH_THRESHOLD ? RiskLevel.High :
TotalScore >= MEDIUM_THRESHOLD ? RiskLevel.Medium :
RiskLevel.Low;
}
public bool IsExpired()
{
return ExpiresAt.HasValue && DateTime.UtcNow > ExpiresAt.Value;
}
}