93 lines
3.0 KiB
C#
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);
|
|
}
|
|
}
|