所有模块添加路由守卫
This commit is contained in:
+11
-10
@@ -2,6 +2,7 @@ import { Routes, Route } from 'react-router-dom';
|
||||
import HomePage from '@/pages/HomePage';
|
||||
import SSOLogin from '@/pages/SSOLogin';
|
||||
import LoginPage from '@/pages/LoginPage';
|
||||
import RequireAuth from '@/shared/components/RequireAuth';
|
||||
import AIMCockpit from '@/modules/ai-matching/pages/AIMCockpit';
|
||||
import CostCockpit from '@/modules/cost-analysis/pages/CostCockpit';
|
||||
import KnowledgeGraphHome from '@/modules/knowledge-graph/pages/KnowledgeGraphHome';
|
||||
@@ -15,18 +16,18 @@ import SanruiAIDesignHome from '@/modules/sanrui-ai-design/pages/SanruiAIDesignH
|
||||
export default function App() {
|
||||
return (
|
||||
<Routes>
|
||||
<Route path="/" element={<HomePage />} />
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route path="/sso-login" element={<SSOLogin />} />
|
||||
<Route path="/ai-matching" element={<AIMCockpit />} />
|
||||
<Route path="/cost-analysis" element={<CostCockpit />} />
|
||||
<Route path="/knowledge-graph" element={<KnowledgeGraphHome />} />
|
||||
<Route path="/knowledge-graph/space" element={<SpaceCockpit />} />
|
||||
<Route path="/bomx-reuse-analyzer" element={<BomxReuseHome />} />
|
||||
<Route path="/order-cost-analysis" element={<CostCockpitFull />} />
|
||||
<Route path="/order-cost-analysis/aim" element={<AIMCockpitFull />} />
|
||||
<Route path="/bexell-scheduling-ai/*" element={<BexellSchedulingApp />} />
|
||||
<Route path="/sanrui-ai-design" element={<SanruiAIDesignHome />} />
|
||||
<Route path="/" element={<RequireAuth><HomePage /></RequireAuth>} />
|
||||
<Route path="/ai-matching" element={<RequireAuth><AIMCockpit /></RequireAuth>} />
|
||||
<Route path="/cost-analysis" element={<RequireAuth><CostCockpit /></RequireAuth>} />
|
||||
<Route path="/knowledge-graph" element={<RequireAuth><KnowledgeGraphHome /></RequireAuth>} />
|
||||
<Route path="/knowledge-graph/space" element={<RequireAuth><SpaceCockpit /></RequireAuth>} />
|
||||
<Route path="/bomx-reuse-analyzer" element={<RequireAuth><BomxReuseHome /></RequireAuth>} />
|
||||
<Route path="/order-cost-analysis" element={<RequireAuth><CostCockpitFull /></RequireAuth>} />
|
||||
<Route path="/order-cost-analysis/aim" element={<RequireAuth><AIMCockpitFull /></RequireAuth>} />
|
||||
<Route path="/bexell-scheduling-ai/*" element={<RequireAuth><BexellSchedulingApp /></RequireAuth>} />
|
||||
<Route path="/sanrui-ai-design" element={<RequireAuth><SanruiAIDesignHome /></RequireAuth>} />
|
||||
</Routes>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -24,14 +24,6 @@ export default function HomePage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const [userInfo, setUserInfo] = useState<SessionUserInfo | null>(() => getUserInfo());
|
||||
|
||||
// 登录守卫:未登录跳转 /login
|
||||
useEffect(() => {
|
||||
const token = sessionStorage.getItem('userToken');
|
||||
if (!token) {
|
||||
navigate('/login', { replace: true });
|
||||
}
|
||||
}, [navigate]);
|
||||
|
||||
// 首页模块多时需纵向滚动;离开后恢复全局 overflow:hidden(其他模块自管布局)
|
||||
useEffect(() => {
|
||||
document.body.style.overflow = 'auto';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { useNavigate, useLocation } from 'react-router-dom';
|
||||
import { User, Lock, LogIn, AlertCircle, Loader2 } from 'lucide-react';
|
||||
import StarBackground from '@/shared/components/StarBackground';
|
||||
import { iamLogin, saveSession } from '@/shared/services/iamAuth';
|
||||
@@ -28,6 +28,7 @@ const iconStyle = (isDark: boolean): React.CSSProperties => ({
|
||||
|
||||
export default function LoginPage() {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const { theme } = useTheme();
|
||||
const isDark = theme === 'dark';
|
||||
|
||||
@@ -52,7 +53,9 @@ export default function LoginPage() {
|
||||
try {
|
||||
const result = await iamLogin({ userId: userId.trim(), password });
|
||||
saveSession(result.token, result.userInfo);
|
||||
navigate('/', { replace: true });
|
||||
// 回跳原页面(RequireAuth 记录的 from),否则去首页
|
||||
const from = (location.state as { from?: string })?.from ?? '/';
|
||||
navigate(from, { replace: true });
|
||||
} catch (ex) {
|
||||
setError(ex instanceof Error ? ex.message : '登录失败,请稍后重试');
|
||||
} finally {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import { ReactNode, useEffect, useState } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Spin } from 'antd';
|
||||
|
||||
/**
|
||||
* 登录守卫:未登录跳转 /login
|
||||
*
|
||||
* 检查 sessionStorage 中的 userToken,若不存在则跳转登录页。
|
||||
* 登录后会带上 from state,便于登录成功后回跳原页面。
|
||||
*/
|
||||
export default function RequireAuth({ children }: { children: ReactNode }) {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const [checked, setChecked] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const token = sessionStorage.getItem('userToken');
|
||||
if (!token) {
|
||||
// 记录原路径,登录后可回跳
|
||||
navigate('/login', { replace: true, state: { from: location.pathname + location.search } });
|
||||
return;
|
||||
}
|
||||
setChecked(true);
|
||||
}, [navigate, location]);
|
||||
|
||||
if (!checked) {
|
||||
return (
|
||||
<div style={{
|
||||
width: '100vw', height: '100vh',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
background: '#0a1628',
|
||||
}}>
|
||||
<Spin size="large" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return <>{children}</>;
|
||||
}
|
||||
Reference in New Issue
Block a user