using MediatR; using TakeoutSaaS.Application.Identity.Abstractions; using TakeoutSaaS.Application.Identity.Contracts; using TakeoutSaaS.Application.Identity.Queries; using TakeoutSaaS.Domain.Identity.Entities; using TakeoutSaaS.Domain.Identity.Enums; using TakeoutSaaS.Domain.Identity.Repositories; using TakeoutSaaS.Shared.Abstractions.Security; using TakeoutSaaS.Shared.Abstractions.Tenancy; namespace TakeoutSaaS.Application.Identity.Handlers; /// /// 获取用户详情处理器。 /// public sealed class GetIdentityUserDetailQueryHandler( IIdentityUserRepository identityUserRepository, IUserRoleRepository userRoleRepository, IRoleRepository roleRepository, IRolePermissionRepository rolePermissionRepository, IPermissionRepository permissionRepository, ITenantProvider tenantProvider, ICurrentUserAccessor currentUserAccessor, IAdminAuthService adminAuthService) : IRequestHandler { /// public async Task Handle(GetIdentityUserDetailQuery request, CancellationToken cancellationToken) { // 1. 获取操作者档案并判断权限 var currentTenantId = tenantProvider.GetCurrentTenantId(); var operatorProfile = await adminAuthService.GetProfileAsync(currentUserAccessor.UserId, cancellationToken); var isSuperAdmin = IdentityUserAccess.IsSuperAdmin(operatorProfile); // 2. 查询用户实体 IdentityUser? user; if (request.IncludeDeleted) { user = await identityUserRepository.GetForUpdateIncludingDeletedAsync(currentTenantId, request.UserId, isSuperAdmin, cancellationToken); } else { user = isSuperAdmin ? await identityUserRepository.GetForUpdateIgnoringTenantAsync(request.UserId, cancellationToken) : await identityUserRepository.GetForUpdateAsync(request.UserId, cancellationToken); } if (user == null) { return null; } if (!isSuperAdmin && user.TenantId != currentTenantId) { return null; } // 3. 加载角色与权限 var roleRelations = await userRoleRepository.GetByUserIdAsync(user.TenantId, user.Id, cancellationToken); var roleIds = roleRelations.Select(x => x.RoleId).Distinct().ToArray(); var roles = roleIds.Length == 0 ? Array.Empty() : await roleRepository.GetByIdsAsync(user.TenantId, roleIds, cancellationToken); var roleCodes = roles.Select(x => x.Code) .Where(code => !string.IsNullOrWhiteSpace(code)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); var permissionIds = roleIds.Length == 0 ? Array.Empty() : (await rolePermissionRepository.GetByRoleIdsAsync(user.TenantId, roleIds, cancellationToken)) .Select(x => x.PermissionId) .Distinct() .ToArray(); var permissions = permissionIds.Length == 0 ? Array.Empty() : (await permissionRepository.GetByIdsAsync(user.TenantId, permissionIds, cancellationToken)) .Select(x => x.Code) .Where(code => !string.IsNullOrWhiteSpace(code)) .Distinct(StringComparer.OrdinalIgnoreCase) .ToArray(); // 4. 组装详情 DTO var now = DateTime.UtcNow; return new UserDetailDto { UserId = user.Id, TenantId = user.TenantId, MerchantId = user.MerchantId, Account = user.Account, DisplayName = user.DisplayName, Phone = user.Phone, Email = user.Email, Status = user.Status, IsLocked = user.Status == IdentityUserStatus.Locked || (user.LockedUntil.HasValue && user.LockedUntil.Value > now), Roles = roleCodes, RoleIds = roleIds.Select(id => id.ToString()).ToArray(), Permissions = permissions, CreatedAt = user.CreatedAt, LastLoginAt = user.LastLoginAt, Avatar = user.Avatar, RowVersion = user.RowVersion }; } }