diff --git a/src/Application/TakeoutSaaS.Application/Identity/Commands/BindRolePermissionsCommand.cs b/src/Application/TakeoutSaaS.Application/Identity/Commands/BindRolePermissionsCommand.cs deleted file mode 100644 index 51eb4bf..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Commands/BindRolePermissionsCommand.cs +++ /dev/null @@ -1,24 +0,0 @@ -using MediatR; - -namespace TakeoutSaaS.Application.Identity.Commands; - -/// -/// 绑定角色权限(覆盖式)。 -/// -public sealed record BindRolePermissionsCommand : IRequest -{ - /// - /// 角色 ID。 - /// - public long RoleId { get; init; } - - /// - /// 租户 ID(可选,空则取当前上下文)。 - /// - public long? TenantId { get; init; } - - /// - /// 权限 ID 集合。 - /// - public long[] PermissionIds { get; init; } = Array.Empty(); -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Commands/CreateRoleCommand.cs b/src/Application/TakeoutSaaS.Application/Identity/Commands/CreateRoleCommand.cs deleted file mode 100644 index d6318c5..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Commands/CreateRoleCommand.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MediatR; -using TakeoutSaaS.Application.Identity.Contracts; - -namespace TakeoutSaaS.Application.Identity.Commands; - -/// -/// 创建角色。 -/// -public sealed record CreateRoleCommand : IRequest -{ - /// - /// 租户 ID(空则取当前上下文)。 - /// - public long? TenantId { get; init; } - - /// - /// 角色名称。 - /// - public string Name { get; init; } = string.Empty; - - /// - /// 角色编码。 - /// - public string Code { get; init; } = string.Empty; - - /// - /// 描述。 - /// - public string? Description { get; init; } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Commands/DeleteRoleCommand.cs b/src/Application/TakeoutSaaS.Application/Identity/Commands/DeleteRoleCommand.cs deleted file mode 100644 index d23a216..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Commands/DeleteRoleCommand.cs +++ /dev/null @@ -1,19 +0,0 @@ -using MediatR; - -namespace TakeoutSaaS.Application.Identity.Commands; - -/// -/// 删除角色。 -/// -public sealed record DeleteRoleCommand : IRequest -{ - /// - /// 角色 ID。 - /// - public long RoleId { get; init; } - - /// - /// 租户 ID(空则取当前上下文)。 - /// - public long? TenantId { get; init; } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Commands/UpdateRoleCommand.cs b/src/Application/TakeoutSaaS.Application/Identity/Commands/UpdateRoleCommand.cs deleted file mode 100644 index caa5d0d..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Commands/UpdateRoleCommand.cs +++ /dev/null @@ -1,30 +0,0 @@ -using MediatR; -using TakeoutSaaS.Application.Identity.Contracts; - -namespace TakeoutSaaS.Application.Identity.Commands; - -/// -/// 更新角色。 -/// -public sealed record UpdateRoleCommand : IRequest -{ - /// - /// 角色 ID。 - /// - public long RoleId { get; init; } - - /// - /// 租户 ID(空则取当前上下文)。 - /// - public long? TenantId { get; init; } - - /// - /// 角色名称。 - /// - public string Name { get; init; } = string.Empty; - - /// - /// 角色描述。 - /// - public string? Description { get; init; } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Contracts/RoleDetailDto.cs b/src/Application/TakeoutSaaS.Application/Identity/Contracts/RoleDetailDto.cs deleted file mode 100644 index cea3b8c..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Contracts/RoleDetailDto.cs +++ /dev/null @@ -1,44 +0,0 @@ -using TakeoutSaaS.Domain.Identity.Enums; - -namespace TakeoutSaaS.Application.Identity.Contracts; - -/// -/// 角色详情 DTO。 -/// -public sealed record RoleDetailDto -{ - /// - /// 角色所属 Portal。 - /// - public PortalType Portal { get; init; } - - /// - /// 角色 ID。 - /// - public long Id { get; init; } - - /// - /// 租户 ID(Portal=Tenant 必填;Portal=Admin 为空)。 - /// - public long? TenantId { get; init; } - - /// - /// 角色名称。 - /// - public string Name { get; init; } = string.Empty; - - /// - /// 角色编码。 - /// - public string Code { get; init; } = string.Empty; - - /// - /// 描述。 - /// - public string? Description { get; init; } - - /// - /// 权限列表。 - /// - public IReadOnlyList Permissions { get; init; } = []; -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/BindRolePermissionsCommandHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/BindRolePermissionsCommandHandler.cs deleted file mode 100644 index a4641e1..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/BindRolePermissionsCommandHandler.cs +++ /dev/null @@ -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; - -/// -/// 绑定角色权限处理器。 -/// -public sealed class BindRolePermissionsCommandHandler( - IRolePermissionRepository rolePermissionRepository) - : IRequestHandler -{ - /// - /// 处理角色权限绑定请求。 - /// - /// 绑定命令。 - /// 取消标记。 - /// 执行结果。 - public async Task 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; - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/CreateRoleCommandHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/CreateRoleCommandHandler.cs deleted file mode 100644 index 0acd571..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/CreateRoleCommandHandler.cs +++ /dev/null @@ -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; - -/// -/// 创建角色处理器。 -/// -public sealed class CreateRoleCommandHandler( - IRoleRepository roleRepository) - : IRequestHandler -{ - /// - /// 处理创建角色请求。 - /// - /// 创建命令。 - /// 取消标记。 - /// 创建后的角色 DTO。 - public async Task 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 - }; - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/DeleteRoleCommandHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/DeleteRoleCommandHandler.cs deleted file mode 100644 index 874cc7b..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/DeleteRoleCommandHandler.cs +++ /dev/null @@ -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; - -/// -/// 删除角色处理器。 -/// -public sealed class DeleteRoleCommandHandler( - IRoleRepository roleRepository) - : IRequestHandler -{ - /// - /// 处理删除角色请求。 - /// - /// 删除命令。 - /// 取消标记。 - /// 执行结果。 - public async Task 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; - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/RoleDetailQueryHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/RoleDetailQueryHandler.cs deleted file mode 100644 index 179295e..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/RoleDetailQueryHandler.cs +++ /dev/null @@ -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; - -/// -/// 角色详情查询处理器。 -/// -public sealed class RoleDetailQueryHandler( - IRoleRepository roleRepository, - IRolePermissionRepository rolePermissionRepository, - IPermissionRepository permissionRepository) - : IRequestHandler -{ - /// - public async Task 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() - : 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 - }; - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/SearchRolesQueryHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/SearchRolesQueryHandler.cs deleted file mode 100644 index 4f3f84e..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/SearchRolesQueryHandler.cs +++ /dev/null @@ -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; - -/// -/// 角色分页查询处理器。 -/// -public sealed class SearchRolesQueryHandler( - IRoleRepository roleRepository) - : IRequestHandler> -{ - /// - /// 执行角色分页查询。 - /// - /// 查询参数。 - /// 取消标记。 - /// 分页结果。 - public async Task> 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(items, request.Page, request.PageSize, roles.Count); - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Handlers/UpdateRoleCommandHandler.cs b/src/Application/TakeoutSaaS.Application/Identity/Handlers/UpdateRoleCommandHandler.cs deleted file mode 100644 index d37fd1d..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Handlers/UpdateRoleCommandHandler.cs +++ /dev/null @@ -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; - -/// -/// 更新角色处理器。 -/// -public sealed class UpdateRoleCommandHandler( - IRoleRepository roleRepository) - : IRequestHandler -{ - /// - /// 执行角色更新。 - /// - /// 更新命令。 - /// 取消标记。 - /// 更新后的角色 DTO 或 null。 - public async Task 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 - }; - } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Queries/RoleDetailQuery.cs b/src/Application/TakeoutSaaS.Application/Identity/Queries/RoleDetailQuery.cs deleted file mode 100644 index e1d00ad..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Queries/RoleDetailQuery.cs +++ /dev/null @@ -1,20 +0,0 @@ -using MediatR; -using TakeoutSaaS.Application.Identity.Contracts; - -namespace TakeoutSaaS.Application.Identity.Queries; - -/// -/// 查询角色详情(含权限)。 -/// -public sealed class RoleDetailQuery : IRequest -{ - /// - /// 角色 ID。 - /// - public long RoleId { get; init; } - - /// - /// 租户 ID(空则取当前上下文)。 - /// - public long? TenantId { get; init; } -} diff --git a/src/Application/TakeoutSaaS.Application/Identity/Queries/SearchRolesQuery.cs b/src/Application/TakeoutSaaS.Application/Identity/Queries/SearchRolesQuery.cs deleted file mode 100644 index 7fccd3a..0000000 --- a/src/Application/TakeoutSaaS.Application/Identity/Queries/SearchRolesQuery.cs +++ /dev/null @@ -1,37 +0,0 @@ -using MediatR; -using TakeoutSaaS.Application.Identity.Contracts; -using TakeoutSaaS.Shared.Abstractions.Results; - -namespace TakeoutSaaS.Application.Identity.Queries; - -/// -/// 分页查询角色。 -/// -public sealed class SearchRolesQuery : IRequest> -{ - /// - /// 指定查询的租户 ID(空则取当前上下文)。 - /// - public long? TenantId { get; init; } - - /// - /// 搜索关键字。 - /// - public string? Keyword { get; init; } - /// - /// 页码(从 1 开始)。 - /// - public int Page { get; init; } = 1; - /// - /// 每页条数。 - /// - public int PageSize { get; init; } = 20; - /// - /// 排序字段。 - /// - public string? SortBy { get; init; } - /// - /// 是否降序。 - /// - public bool SortDescending { get; init; } = true; -}