105 lines
4.2 KiB
C#
105 lines
4.2 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 获取用户详情处理器。
|
|
/// </summary>
|
|
public sealed class GetIdentityUserDetailQueryHandler(
|
|
IIdentityUserRepository identityUserRepository,
|
|
IUserRoleRepository userRoleRepository,
|
|
IRoleRepository roleRepository,
|
|
IRolePermissionRepository rolePermissionRepository,
|
|
IPermissionRepository permissionRepository,
|
|
ITenantProvider tenantProvider,
|
|
ICurrentUserAccessor currentUserAccessor,
|
|
IAdminAuthService adminAuthService)
|
|
: IRequestHandler<GetIdentityUserDetailQuery, UserDetailDto?>
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<UserDetailDto?> 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<Role>()
|
|
: 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<long>()
|
|
: (await rolePermissionRepository.GetByRoleIdsAsync(user.TenantId, roleIds, cancellationToken))
|
|
.Select(x => x.PermissionId)
|
|
.Distinct()
|
|
.ToArray();
|
|
var permissions = permissionIds.Length == 0
|
|
? Array.Empty<string>()
|
|
: (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
|
|
};
|
|
}
|
|
}
|