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;
-}