import React, { useState, useEffect, Suspense, lazy } from 'react';
import {
Layout,
Menu,
theme,
Button,
Dropdown,
Avatar,
message,
Space,
Divider,
ConfigProvider as AntdConfigProvider,
} from 'antd';
import {
BarChartOutlined,
DatabaseOutlined,
CloudServerOutlined,
MenuUnfoldOutlined,
MenuFoldOutlined,
EyeOutlined,
BuildOutlined,
HomeOutlined,
ShoppingCartOutlined,
InboxOutlined,
ImportOutlined,
FileTextOutlined,
UserOutlined,
LogoutOutlined,
HistoryOutlined,
AuditOutlined,
ToolOutlined,
ScheduleOutlined,
SettingOutlined,
ApiOutlined,
PartitionOutlined,
CodepenOutlined,
} from '@ant-design/icons';
import {
BrowserRouter as Router,
Routes,
Route,
Link,
Navigate,
useLocation,
useNavigate,
} from 'react-router-dom';
import { useAuth } from './context/AuthContext';
import { ConfigProvider, useConfig } from './context/ConfigContext';
import { Scene3DProvider } from './context/Scene3DContext';
import { useDesignTokens } from './hooks/useDesignTokens';
import useIdleTimeout from './hooks/useIdleTimeout';
import axios from 'axios';
import { Spin } from 'antd';
const Dashboard = lazy(() => import('./pages/Dashboard'));
const DeviceManagement = lazy(() => import('./pages/DeviceManagement'));
const RackManagement = lazy(() => import('./pages/RackManagement'));
const RoomManagement = lazy(() => import('./pages/RoomManagement'));
const DeviceFieldManagement = lazy(() => import('./pages/DeviceFieldManagement'));
const Rack3DVisualization = lazy(() => import('./pages/Rack3DVisualization'));
const ConsumableManagement = lazy(() => import('./pages/ConsumableManagement'));
const ConsumableStatistics = lazy(() => import('./pages/ConsumableStatistics'));
const ConsumableLogs = lazy(() => import('./pages/ConsumableLogs'));
const CategoryManagement = lazy(() => import('./pages/CategoryManagement'));
const UserManagement = lazy(() => import('./pages/UserManagement'));
const Login = lazy(() => import('./pages/Login'));
const TicketManagement = lazy(() => import('./pages/TicketManagement'));
const TicketCategoryManagement = lazy(() => import('./pages/TicketCategoryManagement'));
const TicketStatistics = lazy(() => import('./pages/TicketStatistics'));
const TicketFieldManagement = lazy(() => import('./pages/TicketFieldManagement'));
const SystemSettings = lazy(() => import('./pages/SystemSettings'));
const CableManagement = lazy(() => import('./pages/CableManagement'));
const PortManagement = lazy(() => import('./pages/PortManagement'));
const { Header, Content, Sider } = Layout;
const PageLoading = () => (
正在加载页面...
);
const AuthLoading = () => (
正在加载认证状态...
);
const PrivateRoute = ({ children }) => {
const { token, initialized, loading } = useAuth();
const location = useLocation();
if (!initialized) {
return ;
}
if (!token) {
return ;
}
return {children};
};
const ProtectedRoute = ({ component: Component }) => (
);
// 默认空闲超时配置
const DEFAULT_IDLE_CONFIG = {
timeout: 10 * 60 * 1000, // 10分钟
warningTime: 30 * 1000, // 30秒
};
const AppLayout = ({ children }) => {
const [collapsed, setCollapsed] = useState(false);
const [activeKey, setActiveKey] = useState('dashboard');
const [idleConfig, setIdleConfig] = useState(DEFAULT_IDLE_CONFIG);
const { user, logout } = useAuth();
const { config } = useConfig();
const navigate = useNavigate();
const location = useLocation();
const designTokens = useDesignTokens();
// 获取空闲超时配置
useEffect(() => {
const fetchIdleConfig = async () => {
try {
const response = await axios.get('/api/system-settings/idle-timeout');
setIdleConfig({
timeout: response.data.timeout,
warningTime: response.data.warningTime,
});
} catch (error) {
console.warn('获取空闲超时配置失败,使用默认配置:', error);
}
};
fetchIdleConfig();
}, []);
// 启用空闲超时检测
useIdleTimeout({
timeout: idleConfig.timeout,
warningTime: idleConfig.warningTime,
onLogout: logout,
enabled: true,
});
const handleLogout = () => {
logout();
message.success('已退出登录');
navigate('/login');
};
const getSelectedKey = () => {
const path = location.pathname;
if (path === '/') return 'dashboard';
if (path.startsWith('/visualization-3d')) return 'visualization-3d';
if (path.startsWith('/rooms') || path.startsWith('/racks')) return 'room-management';
if (
path.startsWith('/devices') ||
path.startsWith('/fields') ||
path.startsWith('/cables') ||
path.startsWith('/ports')
)
return 'asset-management';
if (path.startsWith('/consumables')) return 'consumables-management';
if (
path.startsWith('/users') ||
path.startsWith('/login-history') ||
path.startsWith('/operation-logs') ||
path.startsWith('/settings')
)
return 'system-management';
if (path.startsWith('/tickets')) return 'ticket-management';
return 'dashboard';
};
const menuItems = [
{
key: 'dashboard',
icon: ,
label: 仪表盘,
},
{
key: 'room-management',
icon: ,
label: '机房管理',
children: [
{
key: 'rooms',
icon: ,
label: 机房管理,
},
{
key: 'racks',
icon: ,
label: 机柜管理,
},
{
key: 'visualization-3d',
icon: ,
label: 3D机柜可视化,
},
],
},
{
key: 'asset-management',
icon: ,
label: '资产管理',
children: [
{
key: 'devices',
icon: ,
label: 设备管理,
},
{
key: 'fields',
icon: ,
label: 字段管理,
},
{
key: 'cables',
icon: ,
label: 接线管理,
},
{
key: 'ports',
icon: ,
label: 端口管理,
},
],
},
{
key: 'consumables-management',
icon: ,
label: '耗材管理',
children: [
{
key: 'consumables-stats',
icon: ,
label: 耗材统计,
},
{
key: 'consumables',
icon: ,
label: 耗材列表,
},
{
key: 'consumables-categories',
icon: ,
label: 分类管理,
},
{
key: 'consumables-logs',
icon: ,
label: 操作日志,
},
],
},
{
key: 'ticket-management',
icon: ,
label: '工单管理',
children: [
{
key: 'tickets',
icon: ,
label: 工单列表,
},
{
key: 'ticket-categories',
icon: ,
label: 故障分类,
},
{
key: 'ticket-statistics',
icon: ,
label: 统计报表,
},
{
key: 'ticket-fields',
icon: ,
label: 字段管理,
},
],
},
{
key: 'system-management',
icon: ,
label: '系统管理',
children: [
{
key: 'users',
icon: ,
label: 用户管理,
},
{
key: 'system-settings',
icon: ,
label: 系统设置,
},
],
},
];
return (
{!collapsed && (
{config.site_name || 'IDC管理'}
数据中心管理平台
)}
: }
onClick={() => setCollapsed(!collapsed)}
style={{
width: '100%',
height: '40px',
color: designTokens.colors.text.secondary,
fontSize: '16px',
borderRadius: designTokens.borderRadius.small,
display: 'flex',
alignItems: 'center',
justifyContent: collapsed ? 'center' : 'flex-start',
gap: '8px',
}}
>
{!collapsed && (
收起菜单
)}
{children}
);
};
const ThemeConfig = () => {
const designTokens = useDesignTokens();
return (
}>
} />
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
}
/>
} />
);
};
function App() {
return (
);
}
export default App;