using Application.Abstractions.Messaging; using Application.Abstractions.Data; using Microsoft.EntityFrameworkCore; namespace Application.Features.Admin.Member.List.Update; public sealed class Handler(IAppDbContext db) : ICommandHandler { public async Task Handle(Command request, CancellationToken ct) { var member = await db.Member.AsNoTracking().FirstOrDefaultAsync(x => x.ID == request.ID, ct); if (member is null) { throw new KeyNotFoundException("회원을 찾을 수 없습니다."); } // 이메일 중복 체크 if (member.Email != request.Email && await db.Member.AnyAsync(x => x.Email == request.Email && x.ID != request.ID, ct)) { throw new InvalidOperationException("이미 등록된 이메일입니다."); } // 별명 중복 체크 if (request.Name is not null && member.Name != request.Name && await db.Member.AnyAsync(x => x.Name == request.Name && x.ID != request.ID, ct)) { throw new InvalidOperationException("이미 등록된 별명입니다."); } // Thumb 처리 string? thumbPath = request.IsThumbRemove ? null : (request.ThumbUrl ?? member.Thumb); // Icon 처리 string? iconPath = request.IsIconRemove ? null : (request.IconUrl ?? member.Icon); // 기본 정보 + 비밀번호 업데이트 (단일 쿼리) if (!string.IsNullOrWhiteSpace(request.Password)) { await db.Member.Where(x => x.ID == request.ID).ExecuteUpdateAsync(s => s .SetProperty(x => x.MemberGradeID, request.MemberGradeID) .SetProperty(x => x.Email, request.Email) .SetProperty(x => x.Name, request.Name) .SetProperty(x => x.FirstName, request.FirstName) .SetProperty(x => x.LastName, request.LastName) .SetProperty(x => x.Intro, request.Intro) .SetProperty(x => x.Summary, request.Summary) .SetProperty(x => x.Phone, request.Phone) .SetProperty(x => x.Birthday, request.Birthday) .SetProperty(x => x.Gender, request.Gender) .SetProperty(x => x.Thumb, thumbPath) .SetProperty(x => x.Icon, iconPath) .SetProperty(x => x.IsEmailVerified, request.IsEmailVerified) .SetProperty(x => x.IsAuthCertified, request.IsAuthCertified) .SetProperty(x => x.IsDenied, request.IsDenied) .SetProperty(x => x.IsAdmin, request.IsAdmin) .SetProperty(x => x.IsWithdraw, request.IsWithdraw) .SetProperty(x => x.Password, request.Password) .SetProperty(x => x.PasswordUpdatedAt, DateTime.UtcNow) .SetProperty(x => x.UpdatedAt, DateTime.UtcNow), ct); } else { await db.Member.Where(x => x.ID == request.ID).ExecuteUpdateAsync(s => s .SetProperty(x => x.MemberGradeID, request.MemberGradeID) .SetProperty(x => x.Email, request.Email) .SetProperty(x => x.Name, request.Name) .SetProperty(x => x.FirstName, request.FirstName) .SetProperty(x => x.LastName, request.LastName) .SetProperty(x => x.Intro, request.Intro) .SetProperty(x => x.Summary, request.Summary) .SetProperty(x => x.Phone, request.Phone) .SetProperty(x => x.Birthday, request.Birthday) .SetProperty(x => x.Gender, request.Gender) .SetProperty(x => x.Thumb, thumbPath) .SetProperty(x => x.Icon, iconPath) .SetProperty(x => x.IsEmailVerified, request.IsEmailVerified) .SetProperty(x => x.IsAuthCertified, request.IsAuthCertified) .SetProperty(x => x.IsDenied, request.IsDenied) .SetProperty(x => x.IsAdmin, request.IsAdmin) .SetProperty(x => x.IsWithdraw, request.IsWithdraw) .SetProperty(x => x.UpdatedAt, DateTime.UtcNow), ct); } } }