fengling-risk-control/Fengling.RiskControl.Application/Services/LotteryService.cs

93 lines
3.0 KiB
C#

using Fengling.RiskControl.Domain.Aggregates.LotteryActivities;
using Fengling.RiskControl.Domain.Events;
using Fengling.RiskControl.Domain.Repositories;
using MediatR;
namespace Fengling.RiskControl.Application.Services;
public class LotteryService : ILotteryService
{
private readonly ILotteryActivityRepository _activityRepository;
private readonly IRiskEvaluationService _riskService;
private readonly IMediator _mediator;
public LotteryService(
ILotteryActivityRepository activityRepository,
IRiskEvaluationService riskService,
IMediator mediator)
{
_activityRepository = activityRepository;
_riskService = riskService;
_mediator = mediator;
}
public async Task<LotteryParticipationResult> ParticipateAsync(LotteryParticipationRequest request)
{
var riskResult = await _riskService.EvaluateRiskAsync(new RiskEvaluationRequest
{
MemberId = request.MemberId,
EntityType = "lottery",
EntityId = request.ActivityType,
ActionType = "execute",
Context = new Dictionary<string, object>
{
["stakePoints"] = request.StakePoints,
["activityType"] = request.ActivityType
}
});
if (riskResult.Blocked)
{
return new LotteryParticipationResult
{
Status = LotteryParticipationStatus.Blocked,
Message = riskResult.Message,
RiskResult = riskResult
};
}
var activity = LotteryActivity.Create(
request.MemberId,
request.ActivityType,
request.StakePoints,
request.IpAddress,
request.DeviceId);
activity.MarkProcessing();
await _activityRepository.AddAsync(activity);
var (winAmount, isWin) = SimulateLotteryOutcome(request.StakePoints);
activity.Complete(winAmount, isWin);
await _mediator.Publish(new LotteryCompletedEvent(
activity.Id, request.MemberId, request.StakePoints, winAmount, isWin, riskResult.TotalScore));
return new LotteryParticipationResult
{
ActivityId = activity.Id,
Status = LotteryParticipationStatus.Allowed,
WinAmount = winAmount,
Message = isWin ? $"恭喜中奖! 获得 {winAmount} 积分" : "未中奖",
RiskResult = riskResult
};
}
private (int winAmount, bool isWin) SimulateLotteryOutcome(int stakePoints)
{
var random = new Random();
var isWin = random.NextDouble() < 0.3;
var winAmount = isWin ? stakePoints * random.Next(2, 10) : 0;
return (winAmount, isWin);
}
public Task<LotteryActivity?> GetActivityAsync(long activityId)
{
return _activityRepository.GetByIdAsync(activityId);
}
public Task<IEnumerable<LotteryActivity>> GetMemberActivitiesAsync(long memberId)
{
return _activityRepository.GetByMemberIdAsync(memberId);
}
}