feat(系统配置): 实现全局配置管理功能

- 新增ConfigContext提供全局配置状态管理
- 重构系统设置页面,移除语言和深色模式选项
- 优化备份功能,支持自定义备份路径
- 应用主题颜色动态更新功能
- 添加配置变更自动重载机制
This commit is contained in:
zhang1106
2026-01-21 10:40:30 +08:00
parent 2af47ee162
commit dfd3d67ca0
5 changed files with 1596 additions and 58 deletions
+141 -27
View File
@@ -1,8 +1,9 @@
import React, { useState, Suspense, lazy } from 'react';
import { Layout, Menu, theme, Button, Dropdown, Avatar, message, Space, Divider } from 'antd';
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 } 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 { Spin } from 'antd';
const Dashboard = lazy(() => import('./pages/Dashboard'));
@@ -131,6 +132,7 @@ const AppLayout = ({ children }) => {
const { user, logout } = useAuth();
const navigate = useNavigate();
const location = useLocation();
const { config } = useConfig();
const handleLogout = () => {
logout();
@@ -149,6 +151,56 @@ const AppLayout = ({ children }) => {
return 'dashboard';
};
// 动态设计令牌
const designTokens = {
colors: {
primary: {
main: config.primary_color || '#667eea',
gradient: `linear-gradient(135deg, ${config.primary_color || '#667eea'} 0%, ${config.secondary_color || '#764ba2'} 100%)`,
light: '#8b9ff0'
},
success: { main: '#10b981' },
warning: { main: '#f59e0b' },
error: { main: '#ef4444' },
text: {
primary: '#1e293b',
secondary: '#64748b',
inverse: '#ffffff'
},
background: {
primary: '#ffffff',
secondary: '#f8fafc',
dark: '#1e293b'
},
border: {
light: '#e2e8f0'
},
sidebar: {
bg: '#ffffff',
bgHover: 'rgba(102, 126, 234, 0.08)',
bgActive: 'rgba(102, 126, 234, 0.15)',
text: '#475569',
textHover: config.primary_color || '#667eea',
textActive: config.primary_color || '#667eea',
border: '#e2e8f0'
}
},
shadows: {
small: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
medium: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',
large: '0 10px 15px -3px rgba(0, 0, 0, 0.1)'
},
borderRadius: {
small: '6px',
medium: '10px'
},
spacing: {
sm: '8px',
md: '16px',
lg: '24px'
}
};
const menuItems = [
{
key: 'dashboard',
@@ -315,7 +367,7 @@ const AppLayout = ({ children }) => {
color: designTokens.colors.primary.main,
lineHeight: 1.2
}}>
IDC管理
{config.site_name || 'IDC管理'}
</div>
<div style={{
fontSize: '11px',
@@ -336,7 +388,7 @@ const AppLayout = ({ children }) => {
<Menu
mode="inline"
selectedKeys={[getSelectedKey()]}
defaultOpenKeys={['room-management', 'asset-management', 'consumables-management', 'system-management', 'ticket-management']}
defaultOpenKeys={[]}
style={{
background: 'transparent',
borderRight: 0,
@@ -451,32 +503,94 @@ const AppLayout = ({ children }) => {
);
};
const ThemeConfig = () => {
const { config } = useConfig();
// 动态设计令牌
const designTokens = {
colors: {
primary: {
main: config.primary_color || '#667eea',
gradient: `linear-gradient(135deg, ${config.primary_color || '#667eea'} 0%, ${config.secondary_color || '#764ba2'} 100%)`,
light: '#8b9ff0'
},
success: { main: '#10b981' },
warning: { main: '#f59e0b' },
error: { main: '#ef4444' },
text: {
primary: '#1e293b',
secondary: '#64748b',
inverse: '#ffffff'
},
background: {
primary: '#ffffff',
secondary: '#f8fafc',
dark: '#1e293b'
},
border: {
light: '#e2e8f0'
},
sidebar: {
bg: '#ffffff',
bgHover: 'rgba(102, 126, 234, 0.08)',
bgActive: 'rgba(102, 126, 234, 0.15)',
text: '#475569',
textHover: config.primary_color || '#667eea',
textActive: config.primary_color || '#667eea',
border: '#e2e8f0'
}
},
shadows: {
small: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
medium: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',
large: '0 10px 15px -3px rgba(0, 0, 0, 0.1)'
},
borderRadius: {
small: '6px',
medium: '10px'
},
spacing: {
sm: '8px',
md: '16px',
lg: '24px'
}
};
return (
<AntdConfigProvider theme={{ token: designTokens }}>
<Router>
<Suspense fallback={<PageLoading />}>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
<Route path="/devices" element={<PrivateRoute><DeviceManagement /></PrivateRoute>} />
<Route path="/racks" element={<PrivateRoute><RackManagement /></PrivateRoute>} />
<Route path="/rooms" element={<PrivateRoute><RoomManagement /></PrivateRoute>} />
<Route path="/fields" element={<PrivateRoute><DeviceFieldManagement /></PrivateRoute>} />
<Route path="/visualization" element={<PrivateRoute><RackVisualization /></PrivateRoute>} />
<Route path="/consumables" element={<PrivateRoute><ConsumableManagement /></PrivateRoute>} />
<Route path="/consumables-categories" element={<PrivateRoute><CategoryManagement /></PrivateRoute>} />
<Route path="/consumables-stats" element={<PrivateRoute><ConsumableStatistics /></PrivateRoute>} />
<Route path="/consumables-logs" element={<PrivateRoute><ConsumableLogs /></PrivateRoute>} />
<Route path="/users" element={<PrivateRoute><UserManagement /></PrivateRoute>} />
<Route path="/tickets" element={<PrivateRoute><TicketManagement /></PrivateRoute>} />
<Route path="/ticket-categories" element={<PrivateRoute><TicketCategoryManagement /></PrivateRoute>} />
<Route path="/ticket-statistics" element={<PrivateRoute><TicketStatistics /></PrivateRoute>} />
<Route path="/ticket-fields" element={<PrivateRoute><TicketFieldManagement /></PrivateRoute>} />
<Route path="/settings" element={<PrivateRoute><SystemSettings /></PrivateRoute>} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</Router>
</AntdConfigProvider>
);
};
function App() {
return (
<Router>
<Suspense fallback={<PageLoading />}>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
<Route path="/devices" element={<PrivateRoute><DeviceManagement /></PrivateRoute>} />
<Route path="/racks" element={<PrivateRoute><RackManagement /></PrivateRoute>} />
<Route path="/rooms" element={<PrivateRoute><RoomManagement /></PrivateRoute>} />
<Route path="/fields" element={<PrivateRoute><DeviceFieldManagement /></PrivateRoute>} />
<Route path="/visualization" element={<PrivateRoute><RackVisualization /></PrivateRoute>} />
<Route path="/consumables" element={<PrivateRoute><ConsumableManagement /></PrivateRoute>} />
<Route path="/consumables-categories" element={<PrivateRoute><CategoryManagement /></PrivateRoute>} />
<Route path="/consumables-stats" element={<PrivateRoute><ConsumableStatistics /></PrivateRoute>} />
<Route path="/consumables-logs" element={<PrivateRoute><ConsumableLogs /></PrivateRoute>} />
<Route path="/users" element={<PrivateRoute><UserManagement /></PrivateRoute>} />
<Route path="/tickets" element={<PrivateRoute><TicketManagement /></PrivateRoute>} />
<Route path="/ticket-categories" element={<PrivateRoute><TicketCategoryManagement /></PrivateRoute>} />
<Route path="/ticket-statistics" element={<PrivateRoute><TicketStatistics /></PrivateRoute>} />
<Route path="/ticket-fields" element={<PrivateRoute><TicketFieldManagement /></PrivateRoute>} />
<Route path="/settings" element={<PrivateRoute><SystemSettings /></PrivateRoute>} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</Suspense>
</Router>
<ConfigProvider>
<ThemeConfig />
</ConfigProvider>
);
}