* @Link https://gitee.com/xmo/MineAdmin */ declare(strict_types=1); namespace Builder\Aspect; use App\System\Service\SystemUserService; use Hyperf\Di\Annotation\Aspect; use Hyperf\Di\Aop\AbstractAspect; use Hyperf\Di\Aop\ProceedingJoinPoint; use Hyperf\Di\Exception\Exception; use Builder\Annotation\Role; use Builder\Exception\NoPermissionException; use Builder\Helper\LoginUser; use Builder\BaseRequest; /** * Class RoleAspect * @package Builder\Aspect */ #[Aspect] class RoleAspect extends AbstractAspect { public array $annotations = [ Role::class ]; /** * SystemUserService */ protected SystemUserService $service; /** * BaseRequest */ protected BaseRequest $request; /** * LoginUser */ protected LoginUser $loginUser; /** * RoleAspect constructor. * @param SystemUserService $service * @param BaseRequest $request * @param LoginUser $loginUser */ public function __construct( SystemUserService $service, BaseRequest $request, LoginUser $loginUser ) { $this->service = $service; $this->request = $request; $this->loginUser = $loginUser; } /** * @param ProceedingJoinPoint $proceedingJoinPoint * @return mixed * @throws Exception * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface */ public function process(ProceedingJoinPoint $proceedingJoinPoint) { // 是超管角色放行 if ($this->loginUser->isAdminRole()) { return $proceedingJoinPoint->process(); } /** @var Role $role */ if (isset($proceedingJoinPoint->getAnnotationMetadata()->method[Role::class])) { $role = $proceedingJoinPoint->getAnnotationMetadata()->method[Role::class]; } // 没有使用注解,则放行 if (empty($role->code)) { return $proceedingJoinPoint->process(); } $this->checkRole($role->code, $role->where); return $proceedingJoinPoint->process(); } /** * 检查角色 * @param string $codeString * @param string $where * @return bool * @throws \Psr\Container\ContainerExceptionInterface * @throws \Psr\Container\NotFoundExceptionInterface */ protected function checkRole(string $codeString, string $where): bool { $roles = $this->service->getInfo()['roles']; if ($where === 'OR') { foreach (explode(',', $codeString) as $code) { if (in_array(trim($code), $roles)) { return true; } } throw new NoPermissionException( t('system.no_role') . ' -> [ ' . $codeString . ' ]' ); } if ($where === 'AND') { foreach (explode(',', $codeString) as $code) { $code = trim($code); if (! in_array($code, $roles)) { $service = container()->get(\App\System\Service\SystemRoleService::class); throw new NoPermissionException( t('system.no_role') . ' -> [ ' . $service->findNameByCode($code) . ' ]' ); } } } return true; } }