diff --git a/src/App.tsx b/src/App.tsx
index 0e33858..b2678ef 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -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 (
- } />
} />
} />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
);
}
diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx
index 07507b4..0581026 100644
--- a/src/pages/HomePage.tsx
+++ b/src/pages/HomePage.tsx
@@ -24,14 +24,6 @@ export default function HomePage() {
const [searchParams] = useSearchParams();
const [userInfo, setUserInfo] = useState(() => getUserInfo());
- // 登录守卫:未登录跳转 /login
- useEffect(() => {
- const token = sessionStorage.getItem('userToken');
- if (!token) {
- navigate('/login', { replace: true });
- }
- }, [navigate]);
-
// 首页模块多时需纵向滚动;离开后恢复全局 overflow:hidden(其他模块自管布局)
useEffect(() => {
document.body.style.overflow = 'auto';
diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx
index 99f9fa2..c0ead1f 100644
--- a/src/pages/LoginPage.tsx
+++ b/src/pages/LoginPage.tsx
@@ -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 {
diff --git a/src/shared/components/RequireAuth.tsx b/src/shared/components/RequireAuth.tsx
new file mode 100644
index 0000000..40e1730
--- /dev/null
+++ b/src/shared/components/RequireAuth.tsx
@@ -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 (
+
+
+
+ );
+ }
+
+ return <>{children}>;
+}