'use client'; import { ReactNode, useEffect } from 'react'; import { useRouter, usePathname, useSearchParams } from 'next/navigation'; import { useAuth, SystemPermission } from '@/components/providers/auth-provider'; import { Button } from '@nice/ui/components/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nice/ui/components/card'; import { AlertTriangle, Lock, Loader2, Shield } from 'lucide-react'; import { useRef } from 'react'; // 权限配置选项接口 interface WithAuthOptions { /** * 或权限 - 用户拥有其中任一权限即可访问 */ orPermissions?: SystemPermission[]; /** * 与权限 - 用户必须拥有所有权限才能访问 */ andPermissions?: SystemPermission[]; /** * 或角色 - 用户拥有其中任一角色即可访问 */ orRoles?: string[]; /** * 与角色 - 用户必须拥有所有角色才能访问 */ andRoles?: string[]; /** * 自定义重定向路径(默认为登录页面) */ redirectTo?: string; } // WithAuth 组件属性接口 interface WithAuthProps { children: ReactNode; options?: WithAuthOptions; } /** * 权限拒绝页面组件 */ function AccessDeniedPage() { const router = useRouter(); return (
访问被拒绝 抱歉,您没有权限访问此页面。请联系管理员获取相应权限。

如果您认为这是一个错误,请联系628534

); } /** * 加载状态组件 */ function LoadingPage() { return (
); } export default function WithAuth({ children, options = {} }: WithAuthProps) { const { isAuthenticated, user, hasAnyPermission, hasAllPermissions, hasAnyRole, hasRole, isLoading } = useAuth(); const router = useRouter(); const pathname = usePathname(); const searchParams = useSearchParams(); const { orPermissions, andPermissions, orRoles, andRoles, redirectTo = '/auth/login' } = options; // 使用 useRef 防止重复重定向 const redirectingRef = useRef(false); // 使用 useEffect 处理路由跳转,避免在渲染期间调用 router.push useEffect(() => { // 如果正在加载或已经在重定向中,不执行任何操作 if (isLoading || redirectingRef.current) { return; } // 如果用户未认证且不在登录页面,进行重定向 if (!isAuthenticated && !pathname.includes('/auth/login')) { redirectingRef.current = true; console.log('pathname', pathname); // 获取原始重定向URL,避免嵌套 const getOriginalRedirectUrl = (): string => { const existingRedirectUrl = searchParams.get('redirectUrl'); if (existingRedirectUrl) { try { const decoded = decodeURIComponent(existingRedirectUrl); // 如果已存在的redirectUrl包含登录页面,提取其中的原始redirectUrl if (decoded.includes('/auth/login')) { const url = new URL(decoded, window.location.origin); return url.searchParams.get('redirectUrl') || '/'; } return decoded; } catch { return '/'; } } return pathname + (searchParams.toString() ? `?${searchParams.toString()}` : ''); }; const originalRedirectUrl = getOriginalRedirectUrl(); const loginUrl = `${redirectTo}?redirectUrl=${encodeURIComponent(originalRedirectUrl)}`; router.push(loginUrl); } }, [isAuthenticated, isLoading, pathname, searchParams, redirectTo, router]); // 如果用户未认证,显示加载页面 if (isLoading) { return ; } // 用户已认证但用户信息尚未加载完成,维持页面状态 if (!user) { return <>{children}; } // 检查权限 const hasRequiredPermissions = (() => { // 检查或权限(用户拥有其中任一权限即可) if (orPermissions && orPermissions.length > 0) { if (!hasAnyPermission(orPermissions)) { return false; } } // 检查与权限(用户必须拥有所有权限) if (andPermissions && andPermissions.length > 0) { if (!hasAllPermissions(andPermissions)) { return false; } } // 检查或角色(用户拥有其中任一角色即可) if (orRoles && orRoles.length > 0) { if (!hasAnyRole(orRoles)) { return false; } } // 检查与角色(用户必须拥有所有角色) if (andRoles && andRoles.length > 0) { const hasAllRoles = andRoles.every((role) => hasRole(role)); if (!hasAllRoles) { return false; } } return true; })(); // 权限不足的处理 if (!hasRequiredPermissions) { return ; } // 权限检查通过,渲染子组件 return <>{children}; } // 导出权限相关类型,方便其他组件使用 export type { WithAuthOptions, WithAuthProps };