blob: 2a1441a6797d1369ddb3fd59e3bd0b934dac95e0 [file] [log] [blame]
San3yuan4d0e8032025-04-04 17:21:40 +08001import { Navigate, Outlet } from 'react-router-dom'
San3yuan292794c2025-06-08 20:02:46 +08002import React, { useEffect, useState } from 'react'
San3yuan2534d422025-04-08 21:43:18 +08003import { useSelector } from 'react-redux'
San3yuan292794c2025-06-08 20:02:46 +08004import { useApi } from '@/hooks/request'
5import request from '@/utils/request'
6import { getUserInfo } from '@/api/user'
7import { useAppDispatch } from '@/hooks/store'
San3yuan4d0e8032025-04-04 17:21:40 +08008
9interface PrivateRouteProps {
San3yuan2534d422025-04-08 21:43:18 +080010 role: number
San3yuan4d0e8032025-04-04 17:21:40 +080011 redirectPath?: string
12 children?: React.ReactNode
13}
14
15const PrivateRoute = ({
San3yuan2534d422025-04-08 21:43:18 +080016 role,
San3yuan4d0e8032025-04-04 17:21:40 +080017 redirectPath = '/login',
18 children
19}: PrivateRouteProps) => {
San3yuan2534d422025-04-08 21:43:18 +080020 const isLogin = useSelector((state: any) => state.user.isLogin)
21 const userRole = useSelector((state: any) => state.user.role)
San3yuan292794c2025-06-08 20:02:46 +080022 const userId = useSelector((state: any) => state.user.userId)
23 const dispatch = useAppDispatch()
24 const [hasFetchedUser, setHasFetchedUser] = useState(false) // 防止重复请求
25 const { refresh: getUserInfoRefresh } = useApi(
26 () => request.get(getUserInfo),
27 false
28 )
29
30 useEffect(() => {
31 if (isLogin && !userId && !hasFetchedUser) {
32 const fetchUserInfo = async () => {
33 try {
34 const userInfo = await getUserInfoRefresh()
35 if (userInfo && !(userInfo as any).error) {
36 dispatch({ type: 'user/getUserInfo', payload: userInfo.userInfo })
37 setHasFetchedUser(true) // 标记已请求
38 }
39 } catch (error) {
40 console.error('获取用户信息失败:', error)
41 }
42 }
43 fetchUserInfo()
44 }
45 }, [isLogin, userId, hasFetchedUser, dispatch, getUserInfoRefresh])
San3yuan2534d422025-04-08 21:43:18 +080046
47 if (!isLogin) {
San3yuan4d0e8032025-04-04 17:21:40 +080048 return <Navigate to={redirectPath} replace />
49 }
50
San3yuan2534d422025-04-08 21:43:18 +080051 if (role && role >= userRole) {
52 return <Navigate to={redirectPath} replace />
53 }
54
San3yuan292794c2025-06-08 20:02:46 +080055 return children ? <>{children}</> : <Outlet />
San3yuan4d0e8032025-04-04 17:21:40 +080056}
57
58export default PrivateRoute