refactor: 移除租户角色管理CQRS
This commit is contained in:
@@ -1,24 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 绑定角色权限(覆盖式)。
|
|
||||||
/// </summary>
|
|
||||||
public sealed record BindRolePermissionsCommand : IRequest<bool>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 角色 ID。
|
|
||||||
/// </summary>
|
|
||||||
public long RoleId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(可选,空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 权限 ID 集合。
|
|
||||||
/// </summary>
|
|
||||||
public long[] PermissionIds { get; init; } = Array.Empty<long>();
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建角色。
|
|
||||||
/// </summary>
|
|
||||||
public sealed record CreateRoleCommand : IRequest<RoleDto>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色名称。
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色编码。
|
|
||||||
/// </summary>
|
|
||||||
public string Code { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 描述。
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除角色。
|
|
||||||
/// </summary>
|
|
||||||
public sealed record DeleteRoleCommand : IRequest<bool>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 角色 ID。
|
|
||||||
/// </summary>
|
|
||||||
public long RoleId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新角色。
|
|
||||||
/// </summary>
|
|
||||||
public sealed record UpdateRoleCommand : IRequest<RoleDto?>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 角色 ID。
|
|
||||||
/// </summary>
|
|
||||||
public long RoleId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色名称。
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色描述。
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色详情 DTO。
|
|
||||||
/// </summary>
|
|
||||||
public sealed record RoleDetailDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 角色所属 Portal。
|
|
||||||
/// </summary>
|
|
||||||
public PortalType Portal { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色 ID。
|
|
||||||
/// </summary>
|
|
||||||
public long Id { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(Portal=Tenant 必填;Portal=Admin 为空)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色名称。
|
|
||||||
/// </summary>
|
|
||||||
public string Name { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色编码。
|
|
||||||
/// </summary>
|
|
||||||
public string Code { get; init; } = string.Empty;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 描述。
|
|
||||||
/// </summary>
|
|
||||||
public string? Description { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 权限列表。
|
|
||||||
/// </summary>
|
|
||||||
public IReadOnlyList<PermissionDto> Permissions { get; init; } = [];
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 绑定角色权限处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class BindRolePermissionsCommandHandler(
|
|
||||||
IRolePermissionRepository rolePermissionRepository)
|
|
||||||
: IRequestHandler<BindRolePermissionsCommand, bool>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 处理角色权限绑定请求。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">绑定命令。</param>
|
|
||||||
/// <param name="cancellationToken">取消标记。</param>
|
|
||||||
/// <returns>执行结果。</returns>
|
|
||||||
public async Task<bool> Handle(BindRolePermissionsCommand request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定绑定租户侧角色权限
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
|
|
||||||
// 4. (空行后) 覆盖式绑定权限
|
|
||||||
var distinctPermissionIds = request.PermissionIds
|
|
||||||
.Where(id => id > 0)
|
|
||||||
.Distinct()
|
|
||||||
.ToArray();
|
|
||||||
|
|
||||||
await rolePermissionRepository.ReplaceRolePermissionsAsync(portal, tenantId, request.RoleId, distinctPermissionIds, cancellationToken);
|
|
||||||
await rolePermissionRepository.SaveChangesAsync(cancellationToken);
|
|
||||||
|
|
||||||
// 5. 返回执行结果
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Entities;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 创建角色处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class CreateRoleCommandHandler(
|
|
||||||
IRoleRepository roleRepository)
|
|
||||||
: IRequestHandler<CreateRoleCommand, RoleDto>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 处理创建角色请求。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">创建命令。</param>
|
|
||||||
/// <param name="cancellationToken">取消标记。</param>
|
|
||||||
/// <returns>创建后的角色 DTO。</returns>
|
|
||||||
public async Task<RoleDto> Handle(CreateRoleCommand request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定创建租户侧角色
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
|
|
||||||
// 4. (空行后) 归一化输入并校验唯一
|
|
||||||
var name = request.Name?.Trim() ?? string.Empty;
|
|
||||||
var code = request.Code?.Trim() ?? string.Empty;
|
|
||||||
if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(code))
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.BadRequest, "角色名称与编码不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
var exists = await roleRepository.FindByCodeAsync(portal, tenantId, code, cancellationToken);
|
|
||||||
if (exists is not null)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.Conflict, "角色编码已存在");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 构建角色实体
|
|
||||||
var role = new Role
|
|
||||||
{
|
|
||||||
Portal = portal,
|
|
||||||
TenantId = tenantId,
|
|
||||||
Name = name,
|
|
||||||
Code = code,
|
|
||||||
Description = request.Description
|
|
||||||
};
|
|
||||||
|
|
||||||
// 6. 持久化
|
|
||||||
await roleRepository.AddAsync(role, cancellationToken);
|
|
||||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
|
||||||
|
|
||||||
// 7. 返回 DTO
|
|
||||||
return new RoleDto
|
|
||||||
{
|
|
||||||
Id = role.Id,
|
|
||||||
Portal = role.Portal,
|
|
||||||
TenantId = role.TenantId,
|
|
||||||
Name = role.Name,
|
|
||||||
Code = role.Code,
|
|
||||||
Description = role.Description
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 删除角色处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class DeleteRoleCommandHandler(
|
|
||||||
IRoleRepository roleRepository)
|
|
||||||
: IRequestHandler<DeleteRoleCommand, bool>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 处理删除角色请求。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">删除命令。</param>
|
|
||||||
/// <param name="cancellationToken">取消标记。</param>
|
|
||||||
/// <returns>执行结果。</returns>
|
|
||||||
public async Task<bool> Handle(DeleteRoleCommand request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定删除租户侧角色
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识并删除角色
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
|
|
||||||
await roleRepository.DeleteAsync(portal, tenantId, request.RoleId, cancellationToken);
|
|
||||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
|
||||||
|
|
||||||
// 4. (空行后) 返回执行结果
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
using TakeoutSaaS.Application.Identity.Queries;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色详情查询处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class RoleDetailQueryHandler(
|
|
||||||
IRoleRepository roleRepository,
|
|
||||||
IRolePermissionRepository rolePermissionRepository,
|
|
||||||
IPermissionRepository permissionRepository)
|
|
||||||
: IRequestHandler<RoleDetailQuery, RoleDetailDto?>
|
|
||||||
{
|
|
||||||
/// <inheritdoc />
|
|
||||||
public async Task<RoleDetailDto?> Handle(RoleDetailQuery request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定查询租户侧角色详情
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识并查询角色
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
var role = await roleRepository.FindByIdAsync(portal, tenantId, request.RoleId, cancellationToken);
|
|
||||||
if (role is null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 查询角色权限关系
|
|
||||||
var relations = await rolePermissionRepository.GetByRoleIdsAsync(portal, tenantId, new[] { role.Id }, cancellationToken);
|
|
||||||
var permissionIds = relations.Select(x => x.PermissionId).ToArray();
|
|
||||||
|
|
||||||
// 5. 拉取权限实体
|
|
||||||
var permissions = permissionIds.Length == 0
|
|
||||||
? Array.Empty<Domain.Identity.Entities.Permission>()
|
|
||||||
: await permissionRepository.GetByIdsAsync(permissionIds, cancellationToken);
|
|
||||||
|
|
||||||
// 6. 映射 DTO
|
|
||||||
var permissionDtos = permissions
|
|
||||||
.Select(x => new PermissionDto
|
|
||||||
{
|
|
||||||
Portal = x.Portal,
|
|
||||||
Id = x.Id,
|
|
||||||
ParentId = x.ParentId,
|
|
||||||
SortOrder = x.SortOrder,
|
|
||||||
Type = x.Type,
|
|
||||||
Code = x.Code,
|
|
||||||
Name = x.Name,
|
|
||||||
Description = x.Description
|
|
||||||
})
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// 7. (空行后) 返回角色详情
|
|
||||||
return new RoleDetailDto
|
|
||||||
{
|
|
||||||
Id = role.Id,
|
|
||||||
Portal = role.Portal,
|
|
||||||
TenantId = role.TenantId,
|
|
||||||
Name = role.Name,
|
|
||||||
Code = role.Code,
|
|
||||||
Description = role.Description,
|
|
||||||
Permissions = permissionDtos
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
using TakeoutSaaS.Application.Identity.Queries;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 角色分页查询处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class SearchRolesQueryHandler(
|
|
||||||
IRoleRepository roleRepository)
|
|
||||||
: IRequestHandler<SearchRolesQuery, PagedResult<RoleDto>>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 执行角色分页查询。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">查询参数。</param>
|
|
||||||
/// <param name="cancellationToken">取消标记。</param>
|
|
||||||
/// <returns>分页结果。</returns>
|
|
||||||
public async Task<PagedResult<RoleDto>> Handle(SearchRolesQuery request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定查询租户侧角色
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识并查询角色
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
var roles = await roleRepository.SearchAsync(portal, tenantId, request.Keyword, cancellationToken);
|
|
||||||
|
|
||||||
// 4. 排序
|
|
||||||
var sorted = request.SortBy?.ToLowerInvariant() switch
|
|
||||||
{
|
|
||||||
"name" => request.SortDescending
|
|
||||||
? roles.OrderByDescending(x => x.Name)
|
|
||||||
: roles.OrderBy(x => x.Name),
|
|
||||||
_ => request.SortDescending
|
|
||||||
? roles.OrderByDescending(x => x.CreatedAt)
|
|
||||||
: roles.OrderBy(x => x.CreatedAt)
|
|
||||||
};
|
|
||||||
|
|
||||||
// 5. 分页
|
|
||||||
var paged = sorted
|
|
||||||
.Skip((request.Page - 1) * request.PageSize)
|
|
||||||
.Take(request.PageSize)
|
|
||||||
.ToList();
|
|
||||||
|
|
||||||
// 6. 映射 DTO
|
|
||||||
var items = paged.Select(role => new RoleDto
|
|
||||||
{
|
|
||||||
Id = role.Id,
|
|
||||||
Portal = role.Portal,
|
|
||||||
TenantId = role.TenantId,
|
|
||||||
Name = role.Name,
|
|
||||||
Code = role.Code,
|
|
||||||
Description = role.Description
|
|
||||||
}).ToList();
|
|
||||||
|
|
||||||
// 7. 返回分页结果
|
|
||||||
return new PagedResult<RoleDto>(items, request.Page, request.PageSize, roles.Count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Commands;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Enums;
|
|
||||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Constants;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Exceptions;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 更新角色处理器。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class UpdateRoleCommandHandler(
|
|
||||||
IRoleRepository roleRepository)
|
|
||||||
: IRequestHandler<UpdateRoleCommand, RoleDto?>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 执行角色更新。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request">更新命令。</param>
|
|
||||||
/// <param name="cancellationToken">取消标记。</param>
|
|
||||||
/// <returns>更新后的角色 DTO 或 null。</returns>
|
|
||||||
public async Task<RoleDto?> Handle(UpdateRoleCommand request, CancellationToken cancellationToken)
|
|
||||||
{
|
|
||||||
// 1. 固定更新租户侧角色
|
|
||||||
var portal = PortalType.Tenant;
|
|
||||||
|
|
||||||
// 2. (空行后) 校验租户参数
|
|
||||||
if (!request.TenantId.HasValue || request.TenantId.Value <= 0)
|
|
||||||
{
|
|
||||||
throw new BusinessException(ErrorCodes.ValidationFailed, "TenantId 不能为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. (空行后) 获取租户标识并查询角色
|
|
||||||
var tenantId = request.TenantId.Value;
|
|
||||||
var role = await roleRepository.FindByIdAsync(portal, tenantId, request.RoleId, cancellationToken);
|
|
||||||
if (role == null)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 更新字段
|
|
||||||
role.Name = request.Name;
|
|
||||||
role.Description = request.Description;
|
|
||||||
|
|
||||||
// 5. 持久化
|
|
||||||
await roleRepository.UpdateAsync(role, cancellationToken);
|
|
||||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
|
||||||
|
|
||||||
// 6. 返回 DTO
|
|
||||||
return new RoleDto
|
|
||||||
{
|
|
||||||
Id = role.Id,
|
|
||||||
Portal = role.Portal,
|
|
||||||
TenantId = role.TenantId,
|
|
||||||
Name = role.Name,
|
|
||||||
Code = role.Code,
|
|
||||||
Description = role.Description
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Queries;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查询角色详情(含权限)。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class RoleDetailQuery : IRequest<RoleDetailDto?>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 角色 ID。
|
|
||||||
/// </summary>
|
|
||||||
public long RoleId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 租户 ID(空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using MediatR;
|
|
||||||
using TakeoutSaaS.Application.Identity.Contracts;
|
|
||||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
|
||||||
|
|
||||||
namespace TakeoutSaaS.Application.Identity.Queries;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 分页查询角色。
|
|
||||||
/// </summary>
|
|
||||||
public sealed class SearchRolesQuery : IRequest<PagedResult<RoleDto>>
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 指定查询的租户 ID(空则取当前上下文)。
|
|
||||||
/// </summary>
|
|
||||||
public long? TenantId { get; init; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 搜索关键字。
|
|
||||||
/// </summary>
|
|
||||||
public string? Keyword { get; init; }
|
|
||||||
/// <summary>
|
|
||||||
/// 页码(从 1 开始)。
|
|
||||||
/// </summary>
|
|
||||||
public int Page { get; init; } = 1;
|
|
||||||
/// <summary>
|
|
||||||
/// 每页条数。
|
|
||||||
/// </summary>
|
|
||||||
public int PageSize { get; init; } = 20;
|
|
||||||
/// <summary>
|
|
||||||
/// 排序字段。
|
|
||||||
/// </summary>
|
|
||||||
public string? SortBy { get; init; }
|
|
||||||
/// <summary>
|
|
||||||
/// 是否降序。
|
|
||||||
/// </summary>
|
|
||||||
public bool SortDescending { get; init; } = true;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user