import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common'; import { Reflector } from '@nestjs/core'; import { PrismaService } from '../../prisma/prisma.service'; @Injectable() export class RolesGuard implements CanActivate { constructor( private reflector: Reflector, private prisma: PrismaService, ) {} async canActivate(context: ExecutionContext): Promise { const requiredRoles = this.reflector.getAllAndOverride('roles', [ context.getHandler(), context.getClass(), ]); if (!requiredRoles) { return true; } const request = context.switchToHttp().getRequest(); const user = request.user; if (!user || !user.userId) { throw new ForbiddenException('未授权访问'); } // 从数据库获取用户的角色 const userWithRoles = await this.prisma.user.findUnique({ where: { id: user.userId }, include: { roles: { include: { role: true, }, }, }, }); if (!userWithRoles) { throw new ForbiddenException('用户不存在'); } const userRoles = userWithRoles.roles?.map((ur: any) => ur.role.code) || []; // 检查用户是否有任一所需角色 const hasRequiredRole = requiredRoles.some((role) => userRoles.includes(role)); if (!hasRequiredRole) { throw new ForbiddenException(`需要以下角色之一: ${requiredRoles.join(', ')}`); } return true; } }