blob: 2a1441a6797d1369ddb3fd59e3bd0b934dac95e0 [file] [log] [blame] [edit]
import { Navigate, Outlet } from 'react-router-dom'
import React, { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'
import { useApi } from '@/hooks/request'
import request from '@/utils/request'
import { getUserInfo } from '@/api/user'
import { useAppDispatch } from '@/hooks/store'
interface PrivateRouteProps {
role: number
redirectPath?: string
children?: React.ReactNode
}
const PrivateRoute = ({
role,
redirectPath = '/login',
children
}: PrivateRouteProps) => {
const isLogin = useSelector((state: any) => state.user.isLogin)
const userRole = useSelector((state: any) => state.user.role)
const userId = useSelector((state: any) => state.user.userId)
const dispatch = useAppDispatch()
const [hasFetchedUser, setHasFetchedUser] = useState(false) // 防止重复请求
const { refresh: getUserInfoRefresh } = useApi(
() => request.get(getUserInfo),
false
)
useEffect(() => {
if (isLogin && !userId && !hasFetchedUser) {
const fetchUserInfo = async () => {
try {
const userInfo = await getUserInfoRefresh()
if (userInfo && !(userInfo as any).error) {
dispatch({ type: 'user/getUserInfo', payload: userInfo.userInfo })
setHasFetchedUser(true) // 标记已请求
}
} catch (error) {
console.error('获取用户信息失败:', error)
}
}
fetchUserInfo()
}
}, [isLogin, userId, hasFetchedUser, dispatch, getUserInfoRefresh])
if (!isLogin) {
return <Navigate to={redirectPath} replace />
}
if (role && role >= userRole) {
return <Navigate to={redirectPath} replace />
}
return children ? <>{children}</> : <Outlet />
}
export default PrivateRoute