using Microsoft.Extensions.Logging; using SqlSugar; using Volo.Abp.Domain.Services; using Yi.Framework.AiHub.Domain.Entities; using Yi.Framework.SqlSugarCore.Abstractions; namespace Yi.Framework.AiHub.Domain.Managers; /// /// 邀请码管理器 - 负责邀请码核心业务逻辑 /// public class InviteCodeManager : DomainService { private readonly ISqlSugarRepository _inviteCodeRepository; private readonly ISqlSugarRepository _invitationRecordRepository; private readonly ILogger _logger; public InviteCodeManager( ISqlSugarRepository inviteCodeRepository, ISqlSugarRepository invitationRecordRepository, ILogger logger) { _inviteCodeRepository = inviteCodeRepository; _invitationRecordRepository = invitationRecordRepository; _logger = logger; } /// /// 生成用户的邀请码 /// /// 用户ID /// 邀请码 public async Task GenerateInviteCodeForUserAsync(Guid userId) { // 检查是否已有邀请码 var existingCode = await _inviteCodeRepository._DbQueryable .Where(x => x.UserId == userId) .FirstAsync(); if (existingCode != null) { return existingCode.Code; } // 生成新邀请码 var code = GenerateUniqueInviteCode(); var inviteCode = new InviteCodeAggregateRoot(userId, code); await _inviteCodeRepository.InsertAsync(inviteCode); _logger.LogInformation($"用户 {userId} 生成邀请码 {code}"); return code; } /// /// 获取用户的邀请码信息 /// public async Task GetUserInviteCodeAsync(Guid userId) { return await _inviteCodeRepository._DbQueryable .Where(x => x.UserId == userId) .FirstAsync(); } /// /// 统计用户本周邀请人数 /// public async Task GetWeeklyInvitationCountAsync(Guid userId, DateTime weekStart) { return await _invitationRecordRepository._DbQueryable .Where(x => x.InviterId == userId) .Where(x => x.InvitationTime >= weekStart) .CountAsync(); } /// /// 获取邀请历史记录 /// public async Task> GetInvitationHistoryAsync(Guid userId, int limit = 10) { return await _invitationRecordRepository._DbQueryable .Where(x => x.InviterId == userId) .OrderBy(x => x.InvitationTime, OrderByType.Desc) .Take(limit) .Select(x => new InvitationHistoryDto { InvitedUserName = "用户***", // 脱敏处理 InvitationTime = x.InvitationTime }) .ToListAsync(); } /// /// 使用邀请码 /// /// 使用者ID /// 邀请码 /// 邀请人ID public async Task UseInviteCodeAsync(Guid userId, string inviteCode) { if (string.IsNullOrWhiteSpace(inviteCode)) { throw new UserFriendlyException("邀请码不能为空"); } // 查找邀请码 var inviteCodeEntity = await _inviteCodeRepository._DbQueryable .Where(x => x.Code == inviteCode) .FirstAsync(); if (inviteCodeEntity == null) { throw new UserFriendlyException("邀请码不存在"); } // 验证不能使用自己的邀请码 if (inviteCodeEntity.UserId == userId) { throw new UserFriendlyException("不能使用自己的邀请码"); } // 验证邀请码是否已被使用 if (inviteCodeEntity.IsUsed) { throw new UserFriendlyException("该邀请码已被使用"); } // 验证邀请码拥有者是否已被邀请 if (inviteCodeEntity.IsUserInvited) { throw new UserFriendlyException("该用户已被邀请,邀请码无效"); } // 验证本周邀请码使用次数 var weekStart = CardFlipManager.GetWeekStartDate(DateTime.Now); var weeklyUseCount = await _invitationRecordRepository._DbQueryable .Where(x => x.InvitedUserId == userId) .Where(x => x.InvitationTime >= weekStart) .CountAsync(); if (weeklyUseCount >= CardFlipManager.MAX_INVITE_FLIPS) { throw new UserFriendlyException($"本周邀请码使用次数已达上限({CardFlipManager.MAX_INVITE_FLIPS}次),请下周再来"); } // 检查当前用户的邀请码信息 var myInviteCode = await _inviteCodeRepository._DbQueryable .Where(x => x.UserId == userId) .FirstAsync(); // 标记邀请码为已使用 inviteCodeEntity.MarkAsUsed(userId); await _inviteCodeRepository.UpdateAsync(inviteCodeEntity); // 标记当前用户已被邀请(仅第一次使用邀请码时标记) if (myInviteCode == null) { myInviteCode = new InviteCodeAggregateRoot(userId, GenerateUniqueInviteCode()); myInviteCode.MarkUserAsInvited(); await _inviteCodeRepository.InsertAsync(myInviteCode); } else if (!myInviteCode.IsUserInvited) { myInviteCode.MarkUserAsInvited(); await _inviteCodeRepository.UpdateAsync(myInviteCode); } // 创建邀请记录 var invitationRecord = new InvitationRecordAggregateRoot( inviteCodeEntity.UserId, userId, inviteCode); await _invitationRecordRepository.InsertAsync(invitationRecord); _logger.LogInformation($"用户 {userId} 使用邀请码 {inviteCode} 成功"); return inviteCodeEntity.UserId; } /// /// 检查用户是否已被邀请 /// public async Task IsUserInvitedAsync(Guid userId) { var inviteCode = await _inviteCodeRepository._DbQueryable .Where(x => x.UserId == userId) .FirstAsync(); return inviteCode?.IsUserInvited ?? false; } /// /// 生成唯一邀请码 /// private string GenerateUniqueInviteCode() { const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; var random = new Random(); var code = new char[8]; for (int i = 0; i < code.Length; i++) { code[i] = chars[random.Next(chars.Length)]; } return new string(code); } } /// /// 邀请历史记录DTO /// public class InvitationHistoryDto { /// /// 被邀请人名称(脱敏) /// public string InvitedUserName { get; set; } = string.Empty; /// /// 邀请时间 /// public DateTime InvitationTime { get; set; } }