refactor: 用户管理仅平台管理员

This commit is contained in:
2026-01-30 02:10:32 +00:00
parent 45d08a79df
commit 6143943bf0
23 changed files with 429 additions and 342 deletions

View File

@@ -40,52 +40,50 @@ public sealed class UpdateIdentityUserCommandHandler(
return null;
}
// 3. (空行后) 规范化输入并校验唯一性
var portal = user.Portal;
var tenantId = user.TenantId;
if (portal == PortalType.Tenant && (!tenantId.HasValue || tenantId.Value == 0))
// 3. (空行后) 限定仅允许更新平台管理员账号
if (user.Portal != PortalType.Admin || user.TenantId is not null)
{
throw new BusinessException(ErrorCodes.InternalServerError, "用户缺少有效的租户标识");
return null;
}
// 4. (空行后) 规范化输入并校验唯一性
var portal = PortalType.Admin;
var displayName = request.DisplayName.Trim();
var phone = string.IsNullOrWhiteSpace(request.Phone) ? null : request.Phone.Trim();
var email = string.IsNullOrWhiteSpace(request.Email) ? null : request.Email.Trim();
var roleIds = request.RoleIds == null ? null : ParseIds(request.RoleIds, "角色");
if (portal == PortalType.Tenant
&& !string.IsNullOrWhiteSpace(phone)
if (!string.IsNullOrWhiteSpace(phone)
&& !string.Equals(phone, user.Phone, StringComparison.OrdinalIgnoreCase)
&& await identityUserRepository.ExistsByPhoneAsync(tenantId!.Value, phone, user.Id, cancellationToken))
&& await identityUserRepository.ExistsByPhoneAsync(portal, null, phone, user.Id, cancellationToken))
{
throw new BusinessException(ErrorCodes.Conflict, "手机号已存在");
}
if (portal == PortalType.Tenant
&& !string.IsNullOrWhiteSpace(email)
if (!string.IsNullOrWhiteSpace(email)
&& !string.Equals(email, user.Email, StringComparison.OrdinalIgnoreCase)
&& await identityUserRepository.ExistsByEmailAsync(tenantId!.Value, email, user.Id, cancellationToken))
&& await identityUserRepository.ExistsByEmailAsync(portal, null, email, user.Id, cancellationToken))
{
throw new BusinessException(ErrorCodes.Conflict, "邮箱已存在");
}
if (roleIds is { Length: > 0 })
{
var roles = await roleRepository.GetByIdsAsync(portal, tenantId, roleIds, cancellationToken);
var roles = await roleRepository.GetByIdsAsync(portal, null, roleIds, cancellationToken);
if (roles.Count != roleIds.Length)
{
throw new BusinessException(ErrorCodes.BadRequest, "角色列表包含无效项");
}
}
// 4. 更新用户字段
// 5. 更新用户字段
user.DisplayName = displayName;
user.Phone = phone;
user.Email = email;
user.Avatar = string.IsNullOrWhiteSpace(request.Avatar) ? null : request.Avatar.Trim();
user.RowVersion = request.RowVersion;
// 5. 构建操作日志消息
// 6. 构建操作日志消息
var operatorName = string.IsNullOrWhiteSpace(operatorProfile.DisplayName)
? operatorProfile.Account
: operatorProfile.DisplayName;
@@ -104,6 +102,7 @@ public sealed class UpdateIdentityUserCommandHandler(
Parameters = JsonSerializer.Serialize(new
{
userId = user.Id,
portal = portal.ToString(),
displayName,
phone,
email,
@@ -113,7 +112,7 @@ public sealed class UpdateIdentityUserCommandHandler(
Success = true
};
// 6. 持久化用户更新并写入 Outbox
// 7. 持久化用户更新并写入 Outbox
try
{
await operationLogPublisher.PublishAsync(logMessage, cancellationToken);
@@ -124,13 +123,13 @@ public sealed class UpdateIdentityUserCommandHandler(
throw new BusinessException(ErrorCodes.Conflict, "用户数据已被修改,请刷新后重试");
}
// 7. 覆盖角色绑定(仅当显式传入时)
// 8. 覆盖角色绑定(仅当显式传入时)
if (roleIds != null)
{
await userRoleRepository.ReplaceUserRolesAsync(portal, tenantId, user.Id, roleIds, cancellationToken);
await userRoleRepository.ReplaceUserRolesAsync(portal, null, user.Id, roleIds, cancellationToken);
}
// 8. 返回用户详情
// 9. 返回用户详情
return await mediator.Send(new GetIdentityUserDetailQuery { UserId = user.Id }, cancellationToken);
}