using Microsoft.Extensions.Logging; using XiangYi.Application.DTOs.Requests; using XiangYi.Application.DTOs.Responses; using XiangYi.Application.Interfaces; using XiangYi.Core.Constants; using XiangYi.Core.Entities.Biz; using XiangYi.Core.Exceptions; using XiangYi.Core.Interfaces; namespace XiangYi.Application.Services; /// /// 后台会员管理服务实现 /// public class AdminMemberService : IAdminMemberService { private readonly IRepository _memberRepository; private readonly IRepository _memberFamilyRepository; private readonly IRepository _userRepository; private readonly IRepository _orderRepository; private readonly ILogger _logger; /// /// 会员等级名称 /// private static readonly Dictionary MemberLevelNames = new() { { 1, "不限时会员" }, { 2, "诚意会员" }, { 3, "家庭版会员" }, { 4, "限时会员" } }; /// /// 会员状态名称 /// private static readonly Dictionary MemberStatusNames = new() { { 1, "生效中" }, { 2, "已过期" } }; public AdminMemberService( IRepository memberRepository, IRepository memberFamilyRepository, IRepository userRepository, IRepository orderRepository, ILogger logger) { _memberRepository = memberRepository; _memberFamilyRepository = memberFamilyRepository; _userRepository = userRepository; _orderRepository = orderRepository; _logger = logger; } /// public async Task> GetMemberListAsync(AdminMemberQueryRequest request) { // Get all members var members = await _memberRepository.GetAllAsync(); var query = members.AsQueryable(); // Filter by member level if (request.MemberLevel.HasValue) { query = query.Where(m => m.MemberLevel == request.MemberLevel.Value); } // Filter by status if (request.Status.HasValue) { query = query.Where(m => m.Status == request.Status.Value); } // Filter by start time range if (request.StartTimeBegin.HasValue) { query = query.Where(m => m.StartTime >= request.StartTimeBegin.Value); } if (request.StartTimeEnd.HasValue) { var endTime = request.StartTimeEnd.Value.Date.AddDays(1); query = query.Where(m => m.StartTime < endTime); } // Get user IDs for keyword search var memberList = query.ToList(); var userIds = memberList.Select(m => m.UserId).Distinct().ToList(); var users = await _userRepository.GetListAsync(u => userIds.Contains(u.Id)); var userDict = users.ToDictionary(u => u.Id); // Filter by keyword (XiangQinNo, Nickname, Phone) if (!string.IsNullOrWhiteSpace(request.Keyword)) { var keyword = request.Keyword.Trim(); var matchedUserIds = users .Where(u => (u.XiangQinNo != null && u.XiangQinNo.Contains(keyword)) || (u.Nickname != null && u.Nickname.Contains(keyword)) || (u.Phone != null && u.Phone.Contains(keyword))) .Select(u => u.Id) .ToHashSet(); memberList = memberList.Where(m => matchedUserIds.Contains(m.UserId)).ToList(); } var total = memberList.Count; // Order by CreateTime descending and paginate var items = memberList .OrderByDescending(m => m.CreateTime) .Skip((request.PageIndex - 1) * request.PageSize) .Take(request.PageSize) .ToList(); // Get order IDs for order info lookup var orderIds = items.Select(m => m.OrderId).Distinct().ToList(); var orders = await _orderRepository.GetListAsync(o => orderIds.Contains(o.Id)); var orderDict = orders.ToDictionary(o => o.Id); // Get family bind counts for family members var memberIds = items.Where(m => m.MemberLevel == 3).Select(m => m.Id).ToList(); var familyBinds = await _memberFamilyRepository.GetListAsync(f => memberIds.Contains(f.MemberId)); var familyBindCountDict = familyBinds.GroupBy(f => f.MemberId).ToDictionary(g => g.Key, g => g.Count()); // Map to DTOs - 过滤掉没有关联用户的会员记录 var dtos = items .Where(m => userDict.ContainsKey(m.UserId)) // 只保留有关联用户的会员 .Select(m => { userDict.TryGetValue(m.UserId, out var user); orderDict.TryGetValue(m.OrderId, out var order); familyBindCountDict.TryGetValue(m.Id, out var familyBindCount); return MapToMemberListDto(m, user, order, familyBindCount); }).ToList(); return new PagedResult { Items = dtos, Total = total, PageIndex = request.PageIndex, PageSize = request.PageSize }; } /// public async Task GetMemberDetailAsync(long memberId) { var member = await _memberRepository.GetByIdAsync(memberId); if (member == null) { throw new BusinessException(ErrorCodes.UserNotFound, "会员记录不存在"); } // Get user info var user = await _userRepository.GetByIdAsync(member.UserId); // Get order info var order = await _orderRepository.GetByIdAsync(member.OrderId); // Get family members if family version List? familyMembers = null; if (member.MemberLevel == 3) { var familyBinds = await _memberFamilyRepository.GetListAsync(f => f.MemberId == memberId); if (familyBinds.Any()) { var bindUserIds = familyBinds.Select(f => f.BindUserId).ToList(); var bindUsers = await _userRepository.GetListAsync(u => bindUserIds.Contains(u.Id)); var bindUserDict = bindUsers.ToDictionary(u => u.Id); familyMembers = familyBinds.Select(f => { bindUserDict.TryGetValue(f.BindUserId, out var bindUser); return new AdminFamilyMemberDto { BindId = f.Id, UserId = f.BindUserId, XiangQinNo = bindUser?.XiangQinNo, Nickname = bindUser?.Nickname, Avatar = bindUser?.Avatar, BindTime = f.CreateTime }; }).ToList(); } } return MapToMemberDetailDto(member, user, order, familyMembers); } #region Private Helper Methods private static AdminMemberListDto MapToMemberListDto(Member member, User? user, Order? order, int familyBindCount) { return new AdminMemberListDto { MemberId = member.Id, UserId = member.UserId, XiangQinNo = user?.XiangQinNo, Nickname = user?.Nickname, Avatar = user?.Avatar, Phone = MaskPhone(user?.Phone), MemberLevel = member.MemberLevel, MemberLevelText = GetMemberLevelText(member.MemberLevel), OrderId = member.OrderId, OrderNo = order?.OrderNo, StartTime = member.StartTime, ExpireTime = member.ExpireTime, Status = member.Status, StatusText = GetMemberStatusText(member.Status), FamilyBindCount = familyBindCount, CreateTime = member.CreateTime }; } private static AdminMemberDetailDto MapToMemberDetailDto( Member member, User? user, Order? order, List? familyMembers) { return new AdminMemberDetailDto { MemberId = member.Id, UserId = member.UserId, XiangQinNo = user?.XiangQinNo, Nickname = user?.Nickname, Avatar = user?.Avatar, Phone = MaskPhone(user?.Phone), MemberLevel = member.MemberLevel, MemberLevelText = GetMemberLevelText(member.MemberLevel), OrderId = member.OrderId, OrderNo = order?.OrderNo, OrderAmount = order?.PayAmount, PayTime = order?.PayTime, StartTime = member.StartTime, ExpireTime = member.ExpireTime, Status = member.Status, StatusText = GetMemberStatusText(member.Status), FamilyMembers = familyMembers, CreateTime = member.CreateTime }; } /// /// 手机号脱敏 /// private static string? MaskPhone(string? phone) { return phone; } /// /// 获取会员等级文本 /// private static string GetMemberLevelText(int memberLevel) { return MemberLevelNames.TryGetValue(memberLevel, out var name) ? name : "未知"; } /// /// 获取会员状态文本 /// private static string GetMemberStatusText(int status) { return MemberStatusNames.TryGetValue(status, out var name) ? name : "未知"; } #endregion }