using F9WebAiTest.Application.Common.Exceptions; using F9WebAiTest.Application.Interfaces.SnowflakeID; using F9WebAiTest.Application.Interfaces.UOW; using F9WebAiTest.Domain.Common; using F9WebAiTest.Domain.Entities.SYS.RBAC; using F9WebAiTest.Domain.Enums.SYS.RBAC; using NotificationTypeEntity = F9WebAiTest.Domain.Entities.Notice.NotificationType; using MenuEntity = F9WebAiTest.Domain.Entities.SYS.RBAC.Menu; using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Permissions; using F9WebAiTest.Domain.Interfaces.SYS.RBAC.Roles; using MediatR; namespace F9WebAiTest.Application.CQRS.SYS.RBAC.Roles.Commands; /// 命令定义 public record RolePermission_AssignCommand(long RoleId, Permission_Type_Enum PermissionType, Resource_Type_Enum ResourceType, string ResourceIdentity, long ResourceId) : IRequest; /// 命令处理器 public class AssignRolePermissionCommandHandler( IRoleWriteRepository roleRepository, IUnitOfWork_F9 unitOfWork, IRolePermissionWriteRepository rolePermissionRep, IPermissionWriteRepository permissionWriteRepository, IRepository notificationTypeRepository, IRepository menuRepository, ISnowflakeIdGenerator snowflakeIdGenerator, IPublisher eventBus) : IRequestHandler { public async Task Handle(RolePermission_AssignCommand command, CancellationToken cancellationToken) { if (command.RoleId <= 0) throw new F9OperationException("角色ID不能为空"); if (command.ResourceId <= 0) throw new F9OperationException("资源ID不能为空"); if (string.IsNullOrWhiteSpace(command.ResourceIdentity)) throw new F9OperationException("资源标识不能为空"); Role role = null; long rolePermissionId = 0; var ok = await unitOfWork.ExecuteWithUow(async () => { // 查或创建权限 var dbPermission = await permissionWriteRepository.GetByIdAsync(command.PermissionType, command.ResourceType, command.ResourceId); if (dbPermission == null) { dbPermission = new Permission( snowflakeIdGenerator.CreateId(), command.PermissionType, command.ResourceType, command.ResourceIdentity, command.ResourceId); // 菜单/操作权限:Code 对齐菜单上声明的权限标识(如 sys:user:add), // 否则 v-permission 之类按业务权限码判断的地方永远匹配不上 if (command.ResourceType is Resource_Type_Enum.菜单 or Resource_Type_Enum.操作) { var menu = await menuRepository.GetByIdAsync(command.ResourceId); if (menu != null && !string.IsNullOrEmpty(menu.Permission)) dbPermission.SetCode(menu.Permission); } // 消息订阅权限:Code 对齐消息类型的 RequiredPermission(业务权限码),保证订阅校验一致 if (command.ResourceType == Resource_Type_Enum.消息订阅) { var type = await notificationTypeRepository.GetByIdAsync(command.ResourceId); if (type != null && !string.IsNullOrEmpty(type.RequiredPermission)) dbPermission.SetCode(type.RequiredPermission); } await permissionWriteRepository.AddRangeAsync(new[] { dbPermission }); } // 绑定角色权限 var rolePermission = new RolePermission(snowflakeIdGenerator.CreateId(), command.RoleId, dbPermission.Id); var result = await rolePermissionRep.AssignAsync(rolePermission); role = await roleRepository.GetByIdAsync(command.RoleId); role.AddPermission(dbPermission.Id, command.ResourceType); rolePermissionId = rolePermission.Id; return result; }); if (!ok) throw new F9OperationException("权限", "绑定"); // 发布领域事件 foreach (var domainEvent in role.DomainEvents) await eventBus.Publish(domainEvent, cancellationToken); role.ClearDomainEvents(); return rolePermissionId; } }