75 lines
2.4 KiB
C#
75 lines
2.4 KiB
C#
using Fengling.RiskControl.Domain.Aggregates.RiskScores;
|
|
|
|
namespace Fengling.RiskControl.Application.Services;
|
|
|
|
public class OrderRiskValidationService : IOrderRiskValidationService
|
|
{
|
|
private readonly IRiskEvaluationService _riskService;
|
|
private readonly IMemberIntegrationService _memberService;
|
|
|
|
public OrderRiskValidationService(
|
|
IRiskEvaluationService riskService,
|
|
IMemberIntegrationService memberService)
|
|
{
|
|
_riskService = riskService;
|
|
_memberService = memberService;
|
|
}
|
|
|
|
public async Task<OrderDiscountValidationResult> ValidateDiscountAsync(OrderDiscountValidationRequest request)
|
|
{
|
|
if (request.OriginalAmount <= 0)
|
|
{
|
|
return new OrderDiscountValidationResult
|
|
{
|
|
IsAllowed = false,
|
|
Reason = "订单金额必须大于0",
|
|
MaxDiscountAllowed = 0
|
|
};
|
|
}
|
|
|
|
var discountRate = (double)request.DiscountAmount / request.OriginalAmount;
|
|
|
|
var riskResult = await _riskService.EvaluateRiskAsync(new RiskEvaluationRequest
|
|
{
|
|
MemberId = request.MemberId,
|
|
EntityType = "order_discount",
|
|
EntityId = request.OrderId,
|
|
ActionType = "apply_discount",
|
|
Context = new Dictionary<string, object>
|
|
{
|
|
["discountAmount"] = request.DiscountAmount,
|
|
["originalAmount"] = request.OriginalAmount,
|
|
["discountRate"] = discountRate,
|
|
["discountType"] = request.DiscountType
|
|
}
|
|
});
|
|
|
|
if (riskResult.Blocked)
|
|
{
|
|
return new OrderDiscountValidationResult
|
|
{
|
|
IsAllowed = false,
|
|
Reason = riskResult.Message,
|
|
MaxDiscountAllowed = 0,
|
|
RiskDetails = riskResult
|
|
};
|
|
}
|
|
|
|
var maxDiscount = riskResult.RiskLevel switch
|
|
{
|
|
RiskLevel.Low => request.OriginalAmount / 2,
|
|
RiskLevel.Medium => request.OriginalAmount / 5,
|
|
RiskLevel.High => 0,
|
|
_ => 0
|
|
};
|
|
|
|
return new OrderDiscountValidationResult
|
|
{
|
|
IsAllowed = request.DiscountAmount <= maxDiscount,
|
|
Reason = request.DiscountAmount <= maxDiscount ? "折扣申请通过" : $"超过最大允许折扣: {maxDiscount}",
|
|
MaxDiscountAllowed = maxDiscount,
|
|
RiskDetails = riskResult
|
|
};
|
|
}
|
|
}
|