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) { var inviterCount= await _invitationRecordRepository._DbQueryable .Where(x => x.InviterId == userId) .Where(x => x.InvitationTime >= weekStart) .CountAsync(); var invitedUserIdCount= await _invitationRecordRepository._DbQueryable .Where(x => x.InvitedUserId == userId) .Where(x => x.InvitationTime >= weekStart) .CountAsync(); return inviterCount + invitedUserIdCount; } /// /// 获取邀请历史记录 /// 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("不能使用自己的邀请码"); } // 检查当前用户是否已经填写过别人的邀请码(一辈子只能填写一次) var hasUsedOthersCode = await IsFilledInviteCodeAsync(userId); if (hasUsedOthersCode) { throw new UserFriendlyException("您已经填写过别人的邀请码了,每个账号只能填写一次"); } // 增加邀请码被使用次数 inviteCodeEntity.UsedCount++; await _inviteCodeRepository.UpdateAsync(inviteCodeEntity); // 创建邀请记录(双方都会因为这条记录增加一次翻牌机会) var invitationRecord = new InvitationRecordAggregateRoot( inviteCodeEntity.UserId, userId, inviteCode); await _invitationRecordRepository.InsertAsync(invitationRecord); _logger.LogInformation($"用户 {userId} 使用邀请码 {inviteCode} 成功,邀请人 {inviteCodeEntity.UserId} 和被邀请人 {userId} 都增加一次翻牌机会"); return inviteCodeEntity.UserId; } /// /// 检查用户是否已填写过邀请码 /// public async Task IsFilledInviteCodeAsync(Guid userId) { // 检查当前用户是否已经填写过别人的邀请码(一辈子只能填写一次) return await _invitationRecordRepository._DbQueryable .Where(x => x.InvitedUserId == userId) .AnyAsync(); } /// /// 生成唯一邀请码 /// 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; } }