using Fengling.RiskControl.Domain.Aggregates.RiskRules; using Fengling.RiskControl.Domain.Aggregates.RiskScores; using Fengling.RiskControl.Domain.Repositories; using MediatR; namespace Fengling.RiskControl.Application.Services; public class RiskEvaluationService : IRiskEvaluationService { private readonly IRiskRuleRepository _ruleRepository; private readonly IRiskScoreRepository _scoreRepository; private readonly IMediator _mediator; public RiskEvaluationService( IRiskRuleRepository ruleRepository, IRiskScoreRepository scoreRepository, IMediator mediator) { _ruleRepository = ruleRepository; _scoreRepository = scoreRepository; _mediator = mediator; } public async Task EvaluateRiskAsync(RiskEvaluationRequest request) { var rules = await _ruleRepository.GetActiveRulesAsync(); var factors = new List(); var totalScore = 0; foreach (var rule in rules) { var factor = await EvaluateRuleAsync(rule, request); if (factor != null) { factors.Add(factor); totalScore += factor.Points; } } var riskLevel = DetermineRiskLevel(totalScore); var recommendedAction = DetermineAction(riskLevel); var blocked = recommendedAction == RiskRuleAction.Block; return new RiskEvaluationResult { TotalScore = totalScore, Factors = factors, RiskLevel = riskLevel, RecommendedAction = recommendedAction, Blocked = blocked, Message = blocked ? "操作被风险控制系统拒绝" : "操作已通过风险评估" }; } public async Task IsAllowedAsync(RiskEvaluationRequest request) { var result = await EvaluateRiskAsync(request); return !result.Blocked; } private async Task EvaluateRuleAsync(RiskRule rule, RiskEvaluationRequest request) { return rule.RuleType switch { RiskRuleType.FrequencyLimit => await EvaluateFrequencyLimitAsync(rule, request), RiskRuleType.AmountLimit => await EvaluateAmountLimitAsync(rule, request), RiskRuleType.Blacklist => EvaluateBlacklist(rule, request), _ => null }; } private async Task EvaluateFrequencyLimitAsync(RiskRule rule, RiskEvaluationRequest request) { var config = rule.GetConfig(); var recentCount = 0; if (recentCount >= config.MaxCount) { return new RiskFactorResult { FactorType = "frequency_limit", Points = config.Points, Description = $"超过频率限制: {recentCount}/{config.MaxCount}", RuleName = rule.Name }; } return null; } private async Task EvaluateAmountLimitAsync(RiskRule rule, RiskEvaluationRequest request) { var config = rule.GetConfig(); if (request.Context.TryGetValue("amount", out var amountObj) && amountObj is int amount) { if (amount > config.MaxAmount) { return new RiskFactorResult { FactorType = "amount_limit", Points = config.Points, Description = $"超过金额限制: {amount}/{config.MaxAmount}", RuleName = rule.Name }; } } return null; } private RiskFactorResult? EvaluateBlacklist(RiskRule rule, RiskEvaluationRequest request) { var blacklist = rule.GetConfig(); if (blacklist.MemberIds.Contains(request.MemberId)) { return new RiskFactorResult { FactorType = "blacklist", Points = 100, Description = "用户在黑名单中", RuleName = rule.Name }; } return null; } private RiskLevel DetermineRiskLevel(int score) { return score >= 70 ? RiskLevel.High : score >= 30 ? RiskLevel.Medium : RiskLevel.Low; } private RiskRuleAction DetermineAction(RiskLevel level) { return level switch { RiskLevel.Critical => RiskRuleAction.Block, RiskLevel.High => RiskRuleAction.RequireVerification, RiskLevel.Medium => RiskRuleAction.FlagForReview, _ => RiskRuleAction.Allow }; } } public class FrequencyLimitConfig { public int MaxCount { get; set; } public int WindowMinutes { get; set; } public int Points { get; set; } = 30; } public class AmountLimitConfig { public int MaxAmount { get; set; } public int Points { get; set; } = 40; } public class BlacklistConfig { public HashSet MemberIds { get; set; } = new(); }