using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using Volo.Abp.Application.Services; using Volo.Abp.Users; using Yi.Framework.AiHub.Application.Contracts.Dtos.CardFlip; using Yi.Framework.AiHub.Application.Contracts.IServices; using Yi.Framework.AiHub.Domain.Entities; using Yi.Framework.AiHub.Domain.Extensions; using Yi.Framework.AiHub.Domain.Managers; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.AiHub.Application.Services; /// /// 翻牌服务 - 应用层组合服务 /// [Authorize] public class CardFlipService : ApplicationService, ICardFlipService { private readonly CardFlipManager _cardFlipManager; private readonly InviteCodeManager _inviteCodeManager; private readonly ISqlSugarRepository _premiumPackageRepository; private readonly ILogger _logger; public CardFlipService( CardFlipManager cardFlipManager, InviteCodeManager inviteCodeManager, ISqlSugarRepository premiumPackageRepository, ILogger logger) { _cardFlipManager = cardFlipManager; _inviteCodeManager = inviteCodeManager; _premiumPackageRepository = premiumPackageRepository; _logger = logger; } /// /// 获取本周翻牌任务状态 /// public async Task GetWeeklyTaskStatusAsync() { var userId = CurrentUser.GetId(); var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now); // 获取本周任务 var task = await _cardFlipManager.GetOrCreateWeeklyTaskAsync(userId, weekStart, createIfNotExists: false); // 获取邀请码信息 var inviteCode = await _inviteCodeManager.GetUserInviteCodeAsync(userId); // 统计本周邀请人数 var invitedCount = await _inviteCodeManager.GetWeeklyInvitationCountAsync(userId, weekStart); //当前用户是否已填写过邀请码 var isFilledInviteCode = await _inviteCodeManager.IsFilledInviteCodeAsync(userId); var output = new CardFlipStatusOutput { TotalFlips = task?.TotalFlips ?? 0, RemainingFreeFlips = CardFlipManager.MAX_FREE_FLIPS - (task?.FreeFlipsUsed ?? 0), RemainingBonusFlips = 0, // 已废弃 RemainingInviteFlips = CardFlipManager.MAX_INVITE_FLIPS - (task?.InviteFlipsUsed ?? 0), CanFlip = _cardFlipManager.CanFlipCard(task), MyInviteCode = inviteCode?.Code, InvitedCount = invitedCount, FlipRecords = BuildFlipRecords(task), IsFilledInviteCode = isFilledInviteCode }; // 生成提示信息 output.NextFlipTip = GenerateNextFlipTip(output); return output; } /// /// 翻牌 /// public async Task FlipCardAsync(FlipCardInput input) { var userId = CurrentUser.GetId(); var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now); // 执行翻牌逻辑(由Manager处理验证和翻牌) var result = await _cardFlipManager.ExecuteFlipAsync(userId, input.FlipNumber, weekStart); // 如果中奖,发放奖励 if (result.IsWin) { await GrantRewardAsync(userId, result.RewardAmount, $"翻牌活动-序号{input.FlipNumber}中奖"); } // 构建输出 var output = new FlipCardOutput { FlipNumber = result.FlipNumber, IsWin = result.IsWin, RewardAmount = result.RewardAmount, RewardDesc = result.RewardDesc, RemainingFlips = CardFlipManager.TOTAL_MAX_FLIPS - input.FlipNumber }; return output; } /// /// 使用邀请码解锁翻牌次数 /// public async Task UseInviteCodeAsync(UseInviteCodeInput input) { var userId = CurrentUser.GetId(); var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now); // 获取本周任务 var task = await _cardFlipManager.GetOrCreateWeeklyTaskAsync(userId, weekStart, createIfNotExists: true); // 验证是否已经使用了所有邀请解锁次数 if (task.InviteFlipsUsed >= CardFlipManager.MAX_INVITE_FLIPS) { throw new UserFriendlyException("本周邀请解锁次数已用完"); } // 使用邀请码(由Manager处理验证和邀请逻辑) await _inviteCodeManager.UseInviteCodeAsync(userId, input.InviteCode); _logger.LogInformation($"用户 {userId} 使用邀请码 {input.InviteCode} 解锁翻牌次数成功"); } /// /// 获取我的邀请码信息 /// public async Task GetMyInviteCodeAsync() { var userId = CurrentUser.GetId(); var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now); // 获取我的邀请码 var inviteCode = await _inviteCodeManager.GetUserInviteCodeAsync(userId); // 统计本周邀请人数 var invitedCount = await _inviteCodeManager.GetWeeklyInvitationCountAsync(userId, weekStart); // 获取邀请历史 var invitationHistory = await _inviteCodeManager.GetInvitationHistoryAsync(userId, 10); return new InviteCodeOutput { MyInviteCode = inviteCode?.Code, InvitedCount = invitedCount, InvitationHistory = invitationHistory.Select(x => new InvitationHistoryItem { InvitedUserName = x.InvitedUserName, InvitationTime = x.InvitationTime, WeekDescription = GetWeekDescription(x.InvitationTime) }).ToList() }; } /// /// 生成我的邀请码 /// public async Task GenerateMyInviteCodeAsync() { var userId = CurrentUser.GetId(); // 生成邀请码(由Manager处理) var code = await _inviteCodeManager.GenerateInviteCodeForUserAsync(userId); return code; } #region 私有辅助方法 /// /// 构建翻牌记录列表 /// private List BuildFlipRecords(CardFlipTaskAggregateRoot? task) { var records = new List(); // 获取已翻牌的顺序 var flippedOrder = task != null ? _cardFlipManager.GetFlippedOrder(task) : new List(); var flippedNumbers = new HashSet(flippedOrder); // 获取中奖记录 var winRecords = task?.WinRecords ?? new Dictionary(); // 构建记录,按照原始序号1-10排列 for (int i = 1; i <= CardFlipManager.TOTAL_MAX_FLIPS; i++) { var record = new CardFlipRecord { FlipNumber = i, IsFlipped = flippedNumbers.Contains(i), IsWin = false, FlipTypeDesc = CardFlipManager.GetFlipTypeDesc(i), // 设置在翻牌顺序中的位置(0表示未翻,>0表示第几个翻的) FlipOrderIndex = flippedOrder.IndexOf(i) >= 0 ? flippedOrder.IndexOf(i) + 1 : 0 }; // 设置中奖信息 // 判断这张卡是第几次翻的 if (task != null && flippedNumbers.Contains(i)) { var flipOrderIndex = flippedOrder.IndexOf(i) + 1; // 第几次翻的(1-based) // 检查这次翻牌是否中奖 if (winRecords.TryGetValue(flipOrderIndex, out var rewardAmount)) { record.IsWin = true; record.RewardAmount = rewardAmount; } } records.Add(record); } return records; } /// /// 生成下次翻牌提示 /// private string GenerateNextFlipTip(CardFlipStatusOutput status) { if (status.TotalFlips >= CardFlipManager.TOTAL_MAX_FLIPS) { return "本周翻牌次数已用完,请下周再来!"; } if (status.RemainingFreeFlips > 0) { return $"本周您还有{status.RemainingFreeFlips}次免费翻牌机会"; } else if (status.RemainingInviteFlips > 0) { if (status.TotalFlips >= 7) { return $"本周使用他人邀请码或他人使用你的邀请码,可解锁{status.RemainingInviteFlips}次翻牌,且必中大奖!每次中奖最大额度将翻倍!"; } return $"本周使用他人邀请码或他人使用你的邀请码,可解锁{status.RemainingInviteFlips}次翻牌,必中大奖!每次中奖最大额度将翻倍!"; } return "继续加油!"; } /// /// 发放奖励 /// private async Task GrantRewardAsync(Guid userId, long amount, string description) { var premiumPackage = new PremiumPackageAggregateRoot(userId, amount, description) { PurchaseAmount = 0, // 奖励不需要付费 Remark = $"翻牌活动奖励:{amount / 10000}w tokens" }; await _premiumPackageRepository.InsertAsync(premiumPackage); _logger.LogInformation($"用户 {userId} 获得翻牌奖励 {amount / 10000}w tokens"); } /// /// 获取周描述 /// private string GetWeekDescription(DateTime date) { var weekStart = CardFlipManager.GetWeekStartDate(date); var weekEnd = weekStart.AddDays(6); return $"{weekStart:MM-dd} 至 {weekEnd:MM-dd}"; } #endregion }