登录1
This commit is contained in:
+63
-4
@@ -1,10 +1,11 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNavigate, useSearchParams } from 'react-router-dom';
|
||||
import { BrainCircuit, Calculator, Network, Boxes, ReceiptText, CalendarClock, Sparkles } from 'lucide-react';
|
||||
import { BrainCircuit, Calculator, Network, Boxes, ReceiptText, CalendarClock, Sparkles, LogOut } from 'lucide-react';
|
||||
import { useTheme } from '@/shared/context/ThemeContext';
|
||||
import StarBackground from '@/shared/components/StarBackground';
|
||||
import ThemeToggle from '@/shared/components/ThemeToggle';
|
||||
import { modules } from '@/modules/registry';
|
||||
import { getUserInfo, clearSession, type SessionUserInfo } from '@/shared/services/iamAuth';
|
||||
|
||||
const ICON_MAP: Record<string, React.ComponentType<{ size?: number; color?: string }>> = {
|
||||
BrainCircuit,
|
||||
@@ -21,6 +22,15 @@ export default function HomePage() {
|
||||
const { theme } = useTheme();
|
||||
const isDark = theme === 'dark';
|
||||
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(() => {
|
||||
@@ -36,6 +46,12 @@ export default function HomePage() {
|
||||
}
|
||||
}, [searchParams]);
|
||||
|
||||
const handleLogout = () => {
|
||||
clearSession();
|
||||
setUserInfo(null);
|
||||
navigate('/login', { replace: true });
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
width: '100vw', minHeight: '100vh',
|
||||
@@ -112,8 +128,51 @@ export default function HomePage() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右上角主题切换 */}
|
||||
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center' }}>
|
||||
{/* 右上角:用户信息 + 主题切换 */}
|
||||
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 16 }}>
|
||||
{userInfo && (
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
||||
<div style={{
|
||||
width: 28, height: 28, borderRadius: '50%',
|
||||
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
||||
fontSize: 13, fontWeight: 700,
|
||||
color: '#04121f',
|
||||
background: 'linear-gradient(135deg, #00d4ff, #4f9eff)',
|
||||
}}>
|
||||
{userInfo.userId.charAt(0).toUpperCase()}
|
||||
</div>
|
||||
<span style={{
|
||||
fontSize: 13,
|
||||
...(isDark ? { color: 'rgba(168,216,255,0.85)' } : { color: '#334155' }),
|
||||
}}>
|
||||
{userInfo.userId}
|
||||
</span>
|
||||
<button
|
||||
onClick={handleLogout}
|
||||
title="退出登录"
|
||||
style={{
|
||||
marginLeft: 4,
|
||||
display: 'flex', alignItems: 'center', gap: 4,
|
||||
padding: '5px 12px',
|
||||
borderRadius: 8,
|
||||
border: `1px solid ${isDark ? 'rgba(0,212,255,0.3)' : 'rgba(0,0,0,0.12)'}`,
|
||||
background: isDark ? 'rgba(0,212,255,0.06)' : '#fff',
|
||||
color: isDark ? 'rgba(168,216,255,0.8)' : '#475569',
|
||||
fontSize: 12,
|
||||
cursor: 'pointer',
|
||||
transition: 'border-color 0.2s, color 0.2s',
|
||||
}}
|
||||
onMouseEnter={(e) => { e.currentTarget.style.borderColor = '#ef4444'; e.currentTarget.style.color = '#ef4444'; }}
|
||||
onMouseLeave={(e) => {
|
||||
e.currentTarget.style.borderColor = isDark ? 'rgba(0,212,255,0.3)' : 'rgba(0,0,0,0.12)';
|
||||
e.currentTarget.style.color = isDark ? 'rgba(168,216,255,0.8)' : '#475569';
|
||||
}}
|
||||
>
|
||||
<LogOut size={13} />
|
||||
退出
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
<ThemeToggle />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user