将项目文件整理到 refer 目录
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { Navigate, useLocation } from 'react-router-dom'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { Loader2 } from 'lucide-react'
|
||||
import { api } from '@/lib/api'
|
||||
|
||||
function getStoredToken(): string | null {
|
||||
try { return localStorage.getItem('access_token') } catch { return null }
|
||||
}
|
||||
|
||||
export function AccessGuard({ children, requireAdmin = false }: { children: React.ReactNode; requireAdmin?: boolean }) {
|
||||
const location = useLocation()
|
||||
const token = getStoredToken()
|
||||
|
||||
const { data: status, isLoading } = useQuery({
|
||||
queryKey: ['access-auth-status', token],
|
||||
queryFn: () => api.accessAuthStatus(),
|
||||
// 即使 token 为空也查询一次,用于确认服务端是否启用了门控
|
||||
enabled: true,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
})
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
<div className="h-screen w-full flex items-center justify-center bg-base text-foreground">
|
||||
<Loader2 className="h-6 w-6 animate-spin text-accent" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
// 未启用门控,直接放行
|
||||
if (!status?.enabled) {
|
||||
return <>{children}</>
|
||||
}
|
||||
|
||||
// 未验证,跳转到登录页
|
||||
if (!status.verified) {
|
||||
return <Navigate to="/verify" state={{ from: location.pathname }} replace />
|
||||
}
|
||||
|
||||
// 需要管理员权限但当前非管理员
|
||||
if (requireAdmin && status.role !== 'admin') {
|
||||
return <Navigate to="/" replace />
|
||||
}
|
||||
|
||||
return <>{children}</>
|
||||
}
|
||||
Reference in New Issue
Block a user