- 在 CardFlipStatusOutput 与前端 types 添加 FlipOrderIndex 字段以记录牌在翻牌顺序中的位置 - 在域实体 CardFlipTaskAggregateRoot 增加 FlippedOrder(Json 列)以保存用户实际翻牌顺序 - 将 CardFlipService 重构为调用 CardFlipManager 与 InviteCodeManager,移除大量内聚的业务实现与常量(职责下沉到 Manager) - 调整翻牌、使用邀请码和查询相关流程为 Manager 驱动,更新返回结构与提示文本 - 更新前端 CardFlipActivity 组件与 types,允许任意未翻的卡片被点击并显示翻牌顺序位置 - 若干文案、格式与日志细节修正
280 lines
9.5 KiB
C#
280 lines
9.5 KiB
C#
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;
|
||
|
||
/// <summary>
|
||
/// 翻牌服务 - 应用层组合服务
|
||
/// </summary>
|
||
[Authorize]
|
||
public class CardFlipService : ApplicationService, ICardFlipService
|
||
{
|
||
private readonly CardFlipManager _cardFlipManager;
|
||
private readonly InviteCodeManager _inviteCodeManager;
|
||
private readonly ISqlSugarRepository<PremiumPackageAggregateRoot> _premiumPackageRepository;
|
||
private readonly ILogger<CardFlipService> _logger;
|
||
|
||
public CardFlipService(
|
||
CardFlipManager cardFlipManager,
|
||
InviteCodeManager inviteCodeManager,
|
||
ISqlSugarRepository<PremiumPackageAggregateRoot> premiumPackageRepository,
|
||
ILogger<CardFlipService> logger)
|
||
{
|
||
_cardFlipManager = cardFlipManager;
|
||
_inviteCodeManager = inviteCodeManager;
|
||
_premiumPackageRepository = premiumPackageRepository;
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取本周翻牌任务状态
|
||
/// </summary>
|
||
public async Task<CardFlipStatusOutput> 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 isInvited = await _inviteCodeManager.IsUserInvitedAsync(userId);
|
||
|
||
var output = new CardFlipStatusOutput
|
||
{
|
||
TotalFlips = task?.TotalFlips ?? 0,
|
||
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),
|
||
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();
|
||
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,
|
||
ShowDoubleRewardTip = result.ShowDoubleRewardTip,
|
||
RemainingFlips = CardFlipManager.TOTAL_MAX_FLIPS - input.FlipNumber
|
||
};
|
||
|
||
return output;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 使用邀请码解锁翻牌次数
|
||
/// </summary>
|
||
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} 解锁翻牌次数成功");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取我的邀请码信息
|
||
/// </summary>
|
||
public async Task<InviteCodeOutput> 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,
|
||
IsInvited = inviteCode?.IsUserInvited ?? false,
|
||
InvitationHistory = invitationHistory.Select(x => new InvitationHistoryItem
|
||
{
|
||
InvitedUserName = x.InvitedUserName,
|
||
InvitationTime = x.InvitationTime,
|
||
WeekDescription = GetWeekDescription(x.InvitationTime)
|
||
}).ToList()
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成我的邀请码
|
||
/// </summary>
|
||
public async Task<string> GenerateMyInviteCodeAsync()
|
||
{
|
||
var userId = CurrentUser.GetId();
|
||
|
||
// 生成邀请码(由Manager处理)
|
||
var code = await _inviteCodeManager.GenerateInviteCodeForUserAsync(userId);
|
||
|
||
return code;
|
||
}
|
||
|
||
#region 私有辅助方法
|
||
|
||
/// <summary>
|
||
/// 构建翻牌记录列表
|
||
/// </summary>
|
||
private List<CardFlipRecord> BuildFlipRecords(CardFlipTaskAggregateRoot? task)
|
||
{
|
||
var records = new List<CardFlipRecord>();
|
||
|
||
// 获取已翻牌的顺序
|
||
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++)
|
||
{
|
||
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))
|
||
{
|
||
if (i == 9 && task.HasNinthReward)
|
||
{
|
||
record.IsWin = true;
|
||
record.RewardAmount = task.NinthRewardAmount;
|
||
}
|
||
else if (i == 10 && task.HasTenthReward)
|
||
{
|
||
record.IsWin = true;
|
||
record.RewardAmount = task.TenthRewardAmount;
|
||
}
|
||
}
|
||
|
||
records.Add(record);
|
||
}
|
||
|
||
return records;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成下次翻牌提示
|
||
/// </summary>
|
||
private string GenerateNextFlipTip(CardFlipStatusOutput status)
|
||
{
|
||
if (status.TotalFlips >= CardFlipManager.TOTAL_MAX_FLIPS)
|
||
{
|
||
return "本周翻牌次数已用完,请下周再来!";
|
||
}
|
||
|
||
if (status.RemainingFreeFlips > 0)
|
||
{
|
||
return $"还有{status.RemainingFreeFlips}次免费翻牌机会";
|
||
}
|
||
else if (status.RemainingBonusFlips > 0)
|
||
{
|
||
return $"还有{status.RemainingBonusFlips}次赠送翻牌机会";
|
||
}
|
||
else if (status.RemainingInviteFlips > 0)
|
||
{
|
||
if (status.TotalFlips == 8)
|
||
{
|
||
return "再邀请一个人,马上中奖!";
|
||
}
|
||
|
||
return $"使用邀请码可解锁{status.RemainingInviteFlips}次翻牌";
|
||
}
|
||
|
||
return "继续加油!";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 发放奖励
|
||
/// </summary>
|
||
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");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取周描述
|
||
/// </summary>
|
||
private string GetWeekDescription(DateTime date)
|
||
{
|
||
var weekStart = CardFlipManager.GetWeekStartDate(date);
|
||
var weekEnd = weekStart.AddDays(6);
|
||
|
||
return $"{weekStart:MM-dd} 至 {weekEnd:MM-dd}";
|
||
}
|
||
|
||
#endregion
|
||
} |