| 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 |