2025-10-23 21:58:47 +08:00
|
|
|
|
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;
|
2025-10-27 21:57:26 +08:00
|
|
|
|
using Yi.Framework.AiHub.Domain.Managers;
|
2025-10-23 21:58:47 +08:00
|
|
|
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Yi.Framework.AiHub.Application.Services;
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
2025-10-27 21:57:26 +08:00
|
|
|
|
/// 翻牌服务 - 应用层组合服务
|
2025-10-23 21:58:47 +08:00
|
|
|
|
/// </summary>
|
|
|
|
|
|
[Authorize]
|
|
|
|
|
|
public class CardFlipService : ApplicationService, ICardFlipService
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
private readonly CardFlipManager _cardFlipManager;
|
|
|
|
|
|
private readonly InviteCodeManager _inviteCodeManager;
|
2025-10-23 21:58:47 +08:00
|
|
|
|
private readonly ISqlSugarRepository<PremiumPackageAggregateRoot> _premiumPackageRepository;
|
|
|
|
|
|
private readonly ILogger<CardFlipService> _logger;
|
|
|
|
|
|
|
|
|
|
|
|
public CardFlipService(
|
2025-10-27 21:57:26 +08:00
|
|
|
|
CardFlipManager cardFlipManager,
|
|
|
|
|
|
InviteCodeManager inviteCodeManager,
|
2025-10-23 21:58:47 +08:00
|
|
|
|
ISqlSugarRepository<PremiumPackageAggregateRoot> premiumPackageRepository,
|
|
|
|
|
|
ILogger<CardFlipService> logger)
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
_cardFlipManager = cardFlipManager;
|
|
|
|
|
|
_inviteCodeManager = inviteCodeManager;
|
2025-10-23 21:58:47 +08:00
|
|
|
|
_premiumPackageRepository = premiumPackageRepository;
|
|
|
|
|
|
_logger = logger;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取本周翻牌任务状态
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<CardFlipStatusOutput> GetWeeklyTaskStatusAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = CurrentUser.GetId();
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 获取本周任务
|
|
|
|
|
|
var task = await _cardFlipManager.GetOrCreateWeeklyTaskAsync(userId, weekStart, createIfNotExists: false);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取邀请码信息
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var inviteCode = await _inviteCodeManager.GetUserInviteCodeAsync(userId);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 统计本周邀请人数
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var invitedCount = await _inviteCodeManager.GetWeeklyInvitationCountAsync(userId, weekStart);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 检查用户是否已被邀请
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var isInvited = await _inviteCodeManager.IsUserInvitedAsync(userId);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
var output = new CardFlipStatusOutput
|
|
|
|
|
|
{
|
|
|
|
|
|
TotalFlips = task?.TotalFlips ?? 0,
|
2025-10-27 21:57:26 +08:00
|
|
|
|
RemainingFreeFlips = CardFlipManager.MAX_FREE_FLIPS - (task?.FreeFlipsUsed ?? 0),
|
|
|
|
|
|
RemainingBonusFlips = CardFlipManager.MAX_BONUS_FLIPS - (task?.BonusFlipsUsed ?? 0),
|
|
|
|
|
|
RemainingInviteFlips = CardFlipManager.MAX_INVITE_FLIPS - (task?.InviteFlipsUsed ?? 0),
|
|
|
|
|
|
CanFlip = _cardFlipManager.CanFlipCard(task),
|
2025-10-23 21:58:47 +08:00
|
|
|
|
MyInviteCode = inviteCode?.Code,
|
|
|
|
|
|
InvitedCount = invitedCount,
|
|
|
|
|
|
IsInvited = isInvited,
|
|
|
|
|
|
FlipRecords = BuildFlipRecords(task)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 生成提示信息
|
|
|
|
|
|
output.NextFlipTip = GenerateNextFlipTip(output);
|
|
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 翻牌
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<FlipCardOutput> FlipCardAsync(FlipCardInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = CurrentUser.GetId();
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 执行翻牌逻辑(由Manager处理验证和翻牌)
|
|
|
|
|
|
var result = await _cardFlipManager.ExecuteFlipAsync(userId, input.FlipNumber, weekStart);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 如果中奖,发放奖励
|
|
|
|
|
|
if (result.IsWin)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
await GrantRewardAsync(userId, result.RewardAmount, $"翻牌活动第{input.FlipNumber}次中奖");
|
2025-10-23 21:58:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 构建输出
|
2025-10-23 21:58:47 +08:00
|
|
|
|
var output = new FlipCardOutput
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
FlipNumber = result.FlipNumber,
|
|
|
|
|
|
IsWin = result.IsWin,
|
|
|
|
|
|
RewardAmount = result.RewardAmount,
|
|
|
|
|
|
RewardDesc = result.RewardDesc,
|
|
|
|
|
|
ShowDoubleRewardTip = result.ShowDoubleRewardTip,
|
|
|
|
|
|
RemainingFlips = CardFlipManager.TOTAL_MAX_FLIPS - input.FlipNumber
|
2025-10-23 21:58:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return output;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 使用邀请码解锁翻牌次数
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task UseInviteCodeAsync(UseInviteCodeInput input)
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = CurrentUser.GetId();
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取本周任务
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var task = await _cardFlipManager.GetOrCreateWeeklyTaskAsync(userId, weekStart, createIfNotExists: true);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 验证是否已经使用了所有邀请解锁次数
|
2025-10-27 21:57:26 +08:00
|
|
|
|
if (task.InviteFlipsUsed >= CardFlipManager.MAX_INVITE_FLIPS)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
|
|
|
|
|
throw new UserFriendlyException("本周邀请解锁次数已用完");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 使用邀请码(由Manager处理验证和邀请逻辑)
|
|
|
|
|
|
await _inviteCodeManager.UseInviteCodeAsync(userId, input.InviteCode);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
_logger.LogInformation($"用户 {userId} 使用邀请码 {input.InviteCode} 解锁翻牌次数成功");
|
2025-10-23 21:58:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取我的邀请码信息
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<InviteCodeOutput> GetMyInviteCodeAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = CurrentUser.GetId();
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取我的邀请码
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var inviteCode = await _inviteCodeManager.GetUserInviteCodeAsync(userId);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 统计本周邀请人数
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var invitedCount = await _inviteCodeManager.GetWeeklyInvitationCountAsync(userId, weekStart);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
// 获取邀请历史
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var invitationHistory = await _inviteCodeManager.GetInvitationHistoryAsync(userId, 10);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
return new InviteCodeOutput
|
|
|
|
|
|
{
|
|
|
|
|
|
MyInviteCode = inviteCode?.Code,
|
|
|
|
|
|
InvitedCount = invitedCount,
|
|
|
|
|
|
IsInvited = inviteCode?.IsUserInvited ?? false,
|
2025-10-27 21:57:26 +08:00
|
|
|
|
InvitationHistory = invitationHistory.Select(x => new InvitationHistoryItem
|
|
|
|
|
|
{
|
|
|
|
|
|
InvitedUserName = x.InvitedUserName,
|
|
|
|
|
|
InvitationTime = x.InvitationTime,
|
|
|
|
|
|
WeekDescription = GetWeekDescription(x.InvitationTime)
|
|
|
|
|
|
}).ToList()
|
2025-10-23 21:58:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 生成我的邀请码
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
public async Task<string> GenerateMyInviteCodeAsync()
|
|
|
|
|
|
{
|
|
|
|
|
|
var userId = CurrentUser.GetId();
|
|
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 生成邀请码(由Manager处理)
|
|
|
|
|
|
var code = await _inviteCodeManager.GenerateInviteCodeForUserAsync(userId);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
|
|
|
|
|
|
return code;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region 私有辅助方法
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建翻牌记录列表
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private List<CardFlipRecord> BuildFlipRecords(CardFlipTaskAggregateRoot? task)
|
|
|
|
|
|
{
|
|
|
|
|
|
var records = new List<CardFlipRecord>();
|
|
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
// 获取已翻牌的顺序
|
|
|
|
|
|
var flippedOrder = task != null ? _cardFlipManager.GetFlippedOrder(task) : new List<int>();
|
|
|
|
|
|
var flippedNumbers = new HashSet<int>(flippedOrder);
|
|
|
|
|
|
|
|
|
|
|
|
// 构建记录,按照原始序号1-10排列
|
|
|
|
|
|
for (int i = 1; i <= CardFlipManager.TOTAL_MAX_FLIPS; i++)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
|
|
|
|
|
var record = new CardFlipRecord
|
|
|
|
|
|
{
|
|
|
|
|
|
FlipNumber = i,
|
2025-10-27 21:57:26 +08:00
|
|
|
|
IsFlipped = flippedNumbers.Contains(i),
|
2025-10-23 21:58:47 +08:00
|
|
|
|
IsWin = false,
|
2025-10-27 21:57:26 +08:00
|
|
|
|
FlipTypeDesc = CardFlipManager.GetFlipTypeDesc(i),
|
|
|
|
|
|
// 设置在翻牌顺序中的位置(0表示未翻,>0表示第几个翻的)
|
|
|
|
|
|
FlipOrderIndex = flippedOrder.IndexOf(i) >= 0 ? flippedOrder.IndexOf(i) + 1 : 0
|
2025-10-23 21:58:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 设置中奖信息
|
2025-10-27 21:57:26 +08:00
|
|
|
|
if (task != null && flippedNumbers.Contains(i))
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
if (i == 9 && task.HasNinthReward)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
|
|
|
|
|
record.IsWin = true;
|
|
|
|
|
|
record.RewardAmount = task.NinthRewardAmount;
|
|
|
|
|
|
}
|
2025-10-27 21:57:26 +08:00
|
|
|
|
else if (i == 10 && task.HasTenthReward)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
|
|
|
|
|
record.IsWin = true;
|
|
|
|
|
|
record.RewardAmount = task.TenthRewardAmount;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
records.Add(record);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return records;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 生成下次翻牌提示
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private string GenerateNextFlipTip(CardFlipStatusOutput status)
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
if (status.TotalFlips >= CardFlipManager.TOTAL_MAX_FLIPS)
|
2025-10-23 21:58:47 +08:00
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
return "本周翻牌次数已用完,请下周再来!";
|
2025-10-23 21:58:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (status.RemainingFreeFlips > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"还有{status.RemainingFreeFlips}次免费翻牌机会";
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (status.RemainingBonusFlips > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return $"还有{status.RemainingBonusFlips}次赠送翻牌机会";
|
|
|
|
|
|
}
|
|
|
|
|
|
else if (status.RemainingInviteFlips > 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (status.TotalFlips == 8)
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
return "再邀请一个人,马上中奖!";
|
2025-10-23 21:58:47 +08:00
|
|
|
|
}
|
2025-10-27 21:57:26 +08:00
|
|
|
|
|
2025-10-23 21:58:47 +08:00
|
|
|
|
return $"使用邀请码可解锁{status.RemainingInviteFlips}次翻牌";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-10-27 21:57:26 +08:00
|
|
|
|
return "继续加油!";
|
2025-10-23 21:58:47 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 发放奖励
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private async Task GrantRewardAsync(Guid userId, long amount, string description)
|
|
|
|
|
|
{
|
|
|
|
|
|
var premiumPackage = new PremiumPackageAggregateRoot(userId, amount, description)
|
|
|
|
|
|
{
|
|
|
|
|
|
PurchaseAmount = 0, // 奖励不需要付费
|
2025-10-27 21:57:26 +08:00
|
|
|
|
Remark = $"翻牌活动奖励:{amount / 10000}w tokens"
|
2025-10-23 21:58:47 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
await _premiumPackageRepository.InsertAsync(premiumPackage);
|
|
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"用户 {userId} 获得翻牌奖励 {amount / 10000}w tokens");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 获取周描述
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private string GetWeekDescription(DateTime date)
|
|
|
|
|
|
{
|
2025-10-27 21:57:26 +08:00
|
|
|
|
var weekStart = CardFlipManager.GetWeekStartDate(date);
|
2025-10-23 21:58:47 +08:00
|
|
|
|
var weekEnd = weekStart.AddDays(6);
|
|
|
|
|
|
|
|
|
|
|
|
return $"{weekStart:MM-dd} 至 {weekEnd:MM-dd}";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
2025-10-27 21:57:26 +08:00
|
|
|
|
}
|