feat: 增加角色/权限管理 API 与应用层命令
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
using MediatR;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 为用户分配角色(覆盖式)。
|
||||
/// </summary>
|
||||
public sealed record AssignUserRolesCommand : IRequest<bool>
|
||||
{
|
||||
public long UserId { get; init; }
|
||||
public long[] RoleIds { get; init; } = Array.Empty<long>();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using MediatR;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定角色权限(覆盖式)。
|
||||
/// </summary>
|
||||
public sealed record BindRolePermissionsCommand : IRequest<bool>
|
||||
{
|
||||
public long RoleId { get; init; }
|
||||
public long[] PermissionIds { get; init; } = Array.Empty<long>();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 创建权限。
|
||||
/// </summary>
|
||||
public sealed record CreatePermissionCommand : IRequest<PermissionDto>
|
||||
{
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Code { get; init; } = string.Empty;
|
||||
public string? Description { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 创建角色。
|
||||
/// </summary>
|
||||
public sealed record CreateRoleCommand : IRequest<RoleDto>
|
||||
{
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string Code { get; init; } = string.Empty;
|
||||
public string? Description { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using MediatR;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 删除权限。
|
||||
/// </summary>
|
||||
public sealed record DeletePermissionCommand : IRequest<bool>
|
||||
{
|
||||
public long PermissionId { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using MediatR;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 删除角色。
|
||||
/// </summary>
|
||||
public sealed record DeleteRoleCommand : IRequest<bool>
|
||||
{
|
||||
public long RoleId { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 更新权限。
|
||||
/// </summary>
|
||||
public sealed record UpdatePermissionCommand : IRequest<PermissionDto?>
|
||||
{
|
||||
public long PermissionId { get; init; }
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string? Description { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// 更新角色。
|
||||
/// </summary>
|
||||
public sealed record UpdateRoleCommand : IRequest<RoleDto?>
|
||||
{
|
||||
public long RoleId { get; init; }
|
||||
public string Name { get; init; } = string.Empty;
|
||||
public string? Description { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using TakeoutSaaS.Shared.Abstractions.Serialization;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 权限 DTO。
|
||||
/// </summary>
|
||||
public sealed class PermissionDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限 ID(雪花,序列化为字符串)。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
public long Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户 ID。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
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; }
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using TakeoutSaaS.Shared.Abstractions.Serialization;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Contracts;
|
||||
|
||||
/// <summary>
|
||||
/// 角色 DTO。
|
||||
/// </summary>
|
||||
public sealed class RoleDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色 ID(雪花,序列化为字符串)。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
public long Id { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户 ID。
|
||||
/// </summary>
|
||||
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
|
||||
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; }
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 用户角色分配处理器。
|
||||
/// </summary>
|
||||
public sealed class AssignUserRolesCommandHandler(
|
||||
IUserRoleRepository userRoleRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<AssignUserRolesCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(AssignUserRolesCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
await userRoleRepository.ReplaceUserRolesAsync(tenantId, request.UserId, request.RoleIds, cancellationToken);
|
||||
await userRoleRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定角色权限处理器。
|
||||
/// </summary>
|
||||
public sealed class BindRolePermissionsCommandHandler(
|
||||
IRolePermissionRepository rolePermissionRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<BindRolePermissionsCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(BindRolePermissionsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
await rolePermissionRepository.ReplaceRolePermissionsAsync(tenantId, request.RoleId, request.PermissionIds, cancellationToken);
|
||||
await rolePermissionRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 创建权限处理器。
|
||||
/// </summary>
|
||||
public sealed class CreatePermissionCommandHandler(
|
||||
IPermissionRepository permissionRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<CreatePermissionCommand, PermissionDto>
|
||||
{
|
||||
public async Task<PermissionDto> Handle(CreatePermissionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var permission = new Permission
|
||||
{
|
||||
TenantId = tenantId,
|
||||
Name = request.Name,
|
||||
Code = request.Code,
|
||||
Description = request.Description
|
||||
};
|
||||
|
||||
await permissionRepository.AddAsync(permission, cancellationToken);
|
||||
await permissionRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new PermissionDto
|
||||
{
|
||||
Id = permission.Id,
|
||||
TenantId = permission.TenantId,
|
||||
Name = permission.Name,
|
||||
Code = permission.Code,
|
||||
Description = permission.Description
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Domain.Identity.Entities;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 创建角色处理器。
|
||||
/// </summary>
|
||||
public sealed class CreateRoleCommandHandler(
|
||||
IRoleRepository roleRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<CreateRoleCommand, RoleDto>
|
||||
{
|
||||
public async Task<RoleDto> Handle(CreateRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var role = new Role
|
||||
{
|
||||
TenantId = tenantId,
|
||||
Name = request.Name,
|
||||
Code = request.Code,
|
||||
Description = request.Description
|
||||
};
|
||||
|
||||
await roleRepository.AddAsync(role, cancellationToken);
|
||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new RoleDto
|
||||
{
|
||||
Id = role.Id,
|
||||
TenantId = role.TenantId,
|
||||
Name = role.Name,
|
||||
Code = role.Code,
|
||||
Description = role.Description
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 删除权限处理器。
|
||||
/// </summary>
|
||||
public sealed class DeletePermissionCommandHandler(
|
||||
IPermissionRepository permissionRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<DeletePermissionCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(DeletePermissionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
await permissionRepository.DeleteAsync(request.PermissionId, tenantId, cancellationToken);
|
||||
await permissionRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 删除角色处理器。
|
||||
/// </summary>
|
||||
public sealed class DeleteRoleCommandHandler(
|
||||
IRoleRepository roleRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<DeleteRoleCommand, bool>
|
||||
{
|
||||
public async Task<bool> Handle(DeleteRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
await roleRepository.DeleteAsync(request.RoleId, tenantId, cancellationToken);
|
||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Application.Identity.Queries;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 权限分页查询处理器。
|
||||
/// </summary>
|
||||
public sealed class SearchPermissionsQueryHandler(
|
||||
IPermissionRepository permissionRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<SearchPermissionsQuery, PagedResult<PermissionDto>>
|
||||
{
|
||||
public async Task<PagedResult<PermissionDto>> Handle(SearchPermissionsQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var permissions = await permissionRepository.SearchAsync(tenantId, request.Keyword, cancellationToken);
|
||||
|
||||
var sorted = request.SortBy?.ToLowerInvariant() switch
|
||||
{
|
||||
"name" => request.SortDescending
|
||||
? permissions.OrderByDescending(x => x.Name)
|
||||
: permissions.OrderBy(x => x.Name),
|
||||
"code" => request.SortDescending
|
||||
? permissions.OrderByDescending(x => x.Code)
|
||||
: permissions.OrderBy(x => x.Code),
|
||||
_ => request.SortDescending
|
||||
? permissions.OrderByDescending(x => x.CreatedAt)
|
||||
: permissions.OrderBy(x => x.CreatedAt)
|
||||
};
|
||||
|
||||
var paged = sorted
|
||||
.Skip((request.Page - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToList();
|
||||
|
||||
var items = paged.Select(permission => new PermissionDto
|
||||
{
|
||||
Id = permission.Id,
|
||||
TenantId = permission.TenantId,
|
||||
Name = permission.Name,
|
||||
Code = permission.Code,
|
||||
Description = permission.Description
|
||||
}).ToList();
|
||||
|
||||
return new PagedResult<PermissionDto>(items, request.Page, request.PageSize, permissions.Count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Application.Identity.Queries;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 角色分页查询处理器。
|
||||
/// </summary>
|
||||
public sealed class SearchRolesQueryHandler(
|
||||
IRoleRepository roleRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<SearchRolesQuery, PagedResult<RoleDto>>
|
||||
{
|
||||
public async Task<PagedResult<RoleDto>> Handle(SearchRolesQuery request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var roles = await roleRepository.SearchAsync(tenantId, request.Keyword, cancellationToken);
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
var paged = sorted
|
||||
.Skip((request.Page - 1) * request.PageSize)
|
||||
.Take(request.PageSize)
|
||||
.ToList();
|
||||
|
||||
var items = paged.Select(role => new RoleDto
|
||||
{
|
||||
Id = role.Id,
|
||||
TenantId = role.TenantId,
|
||||
Name = role.Name,
|
||||
Code = role.Code,
|
||||
Description = role.Description
|
||||
}).ToList();
|
||||
|
||||
return new PagedResult<RoleDto>(items, request.Page, request.PageSize, roles.Count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 更新权限处理器。
|
||||
/// </summary>
|
||||
public sealed class UpdatePermissionCommandHandler(
|
||||
IPermissionRepository permissionRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<UpdatePermissionCommand, PermissionDto?>
|
||||
{
|
||||
public async Task<PermissionDto?> Handle(UpdatePermissionCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var permission = await permissionRepository.FindByIdAsync(request.PermissionId, tenantId, cancellationToken);
|
||||
if (permission == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
permission.Name = request.Name;
|
||||
permission.Description = request.Description;
|
||||
|
||||
await permissionRepository.UpdateAsync(permission, cancellationToken);
|
||||
await permissionRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new PermissionDto
|
||||
{
|
||||
Id = permission.Id,
|
||||
TenantId = permission.TenantId,
|
||||
Name = permission.Name,
|
||||
Code = permission.Code,
|
||||
Description = permission.Description
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Commands;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Domain.Identity.Repositories;
|
||||
using TakeoutSaaS.Shared.Abstractions.Tenancy;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Handlers;
|
||||
|
||||
/// <summary>
|
||||
/// 更新角色处理器。
|
||||
/// </summary>
|
||||
public sealed class UpdateRoleCommandHandler(
|
||||
IRoleRepository roleRepository,
|
||||
ITenantProvider tenantProvider)
|
||||
: IRequestHandler<UpdateRoleCommand, RoleDto?>
|
||||
{
|
||||
public async Task<RoleDto?> Handle(UpdateRoleCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var tenantId = tenantProvider.GetCurrentTenantId();
|
||||
var role = await roleRepository.FindByIdAsync(request.RoleId, tenantId, cancellationToken);
|
||||
if (role == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
role.Name = request.Name;
|
||||
role.Description = request.Description;
|
||||
|
||||
await roleRepository.UpdateAsync(role, cancellationToken);
|
||||
await roleRepository.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return new RoleDto
|
||||
{
|
||||
Id = role.Id,
|
||||
TenantId = role.TenantId,
|
||||
Name = role.Name,
|
||||
Code = role.Code,
|
||||
Description = role.Description
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using MediatR;
|
||||
using TakeoutSaaS.Application.Identity.Contracts;
|
||||
using TakeoutSaaS.Shared.Abstractions.Results;
|
||||
|
||||
namespace TakeoutSaaS.Application.Identity.Queries;
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询权限。
|
||||
/// </summary>
|
||||
public sealed class SearchPermissionsQuery : IRequest<PagedResult<PermissionDto>>
|
||||
{
|
||||
public string? Keyword { get; init; }
|
||||
public int Page { get; init; } = 1;
|
||||
public int PageSize { get; init; } = 20;
|
||||
public string? SortBy { get; init; }
|
||||
public bool SortDescending { get; init; } = true;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
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>>
|
||||
{
|
||||
public string? Keyword { get; init; }
|
||||
public int Page { get; init; } = 1;
|
||||
public int PageSize { get; init; } = 20;
|
||||
public string? SortBy { get; init; }
|
||||
public bool SortDescending { get; init; } = true;
|
||||
}
|
||||
Reference in New Issue
Block a user