Files
MYXY_Web/src/pages/AdminDashboard.tsx

441 lines
13 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react';
import {
Card,
Row,
Col,
Statistic,
Progress,
Typography,
Space,
Button,
Tag,
theme
} from 'antd';
import {
UserOutlined,
DollarOutlined,
TeamOutlined,
WarningOutlined,
CheckCircleOutlined,
CloseCircleOutlined,
ClockCircleOutlined,
TrophyOutlined,
FireOutlined,
ShoppingCartOutlined,
NotificationOutlined,
RiseOutlined
} from '@ant-design/icons';
import { useAuth } from '../contexts/AuthContext';
const { Title, Text } = Typography;
/**
* 模拟数据接口
*/
interface DashboardStats {
totalUsers: number;
activeUsers: number;
todayRevenue: number;
monthlyRevenue: number;
totalServers: number;
onlineServers: number;
}
interface QuickAction {
title: string;
icon: React.ReactNode;
color: string;
action: () => void;
}
interface RecentActivity {
id: string;
user: string;
action: string;
time: string;
status: 'success' | 'warning' | 'error' | 'info';
}
interface SystemAlert {
id: string;
type: 'info' | 'warning' | 'error';
message: string;
time: string;
resolved: boolean;
}
/**
* 默认工作台页面
* 管理员登录后的首页
*/
const AdminDashboard: React.FC = () => {
const { user } = useAuth();
const { token } = theme.useToken();
// 模拟数据
const dashboardStats: DashboardStats = {
totalUsers: 125840,
activeUsers: 8756,
todayRevenue: 125680.50,
monthlyRevenue: 3756000.00,
totalServers: 24,
onlineServers: 23
};
// 快速操作
const quickActions: QuickAction[] = [
{
title: '用户管理',
icon: <UserOutlined />,
color: '#1890ff',
action: () => console.log('跳转到用户管理')
},
{
title: '服务器监控',
icon: <FireOutlined />,
color: '#fa541c',
action: () => console.log('跳转到服务器监控')
},
{
title: '订单处理',
icon: <ShoppingCartOutlined />,
color: '#52c41a',
action: () => console.log('跳转到订单处理')
},
{
title: '系统公告',
icon: <NotificationOutlined />,
color: '#722ed1',
action: () => console.log('跳转到系统公告')
}
];
// 最近活动数据
const recentActivities: RecentActivity[] = [
{
id: '1',
user: '张三',
action: '完成了用户充值审核',
time: '2分钟前',
status: 'success'
},
{
id: '2',
user: '李四',
action: '提交了服务器维护申请',
time: '5分钟前',
status: 'warning'
},
{
id: '3',
user: '王五',
action: '处理了玩家投诉',
time: '10分钟前',
status: 'info'
},
{
id: '4',
user: '赵六',
action: '更新了游戏道具信息',
time: '15分钟前',
status: 'success'
},
{
id: '5',
user: '孙七',
action: '删除了异常订单',
time: '20分钟前',
status: 'error'
}
];
// 系统告警数据
const systemAlerts: SystemAlert[] = [
{
id: '1',
type: 'warning',
message: '服务器 CPU 使用率超过 80%',
time: '5分钟前',
resolved: false
},
{
id: '2',
type: 'info',
message: '今日玩家活跃度较昨日增长 15%',
time: '10分钟前',
resolved: false
},
{
id: '3',
type: 'error',
message: '支付接口响应异常',
time: '30分钟前',
resolved: true
}
];
// 获取状态图标
const getStatusIcon = (status: RecentActivity['status']) => {
switch (status) {
case 'success':
return <CheckCircleOutlined style={{ color: '#52c41a' }} />;
case 'warning':
return <WarningOutlined style={{ color: '#faad14' }} />;
case 'error':
return <CloseCircleOutlined style={{ color: '#ff4d4f' }} />;
case 'info':
default:
return <ClockCircleOutlined style={{ color: '#1890ff' }} />;
}
};
// 获取告警标签颜色
const getAlertColor = (type: SystemAlert['type']) => {
switch (type) {
case 'error':
return 'error';
case 'warning':
return 'warning';
case 'info':
default:
return 'processing';
}
};
return (
<div style={{ padding: '0' }}>
{/* 欢迎标题 */}
<div style={{ marginBottom: '24px' }}>
<Title level={2} style={{ margin: 0, color: token.colorText }}>
{user?.real_name || user?.username}
</Title>
<Text type="secondary">
{new Date().toLocaleDateString('zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
weekday: 'long'
})}
</Text>
</div>
{/* 统计卡片 */}
<Row gutter={[16, 16]} style={{ marginBottom: '24px' }}>
<Col xs={24} sm={12} lg={6}>
<Card>
<Statistic
title="总用户数"
value={dashboardStats.totalUsers}
prefix={<UserOutlined style={{ color: '#1890ff' }} />}
suffix="人"
styles={{ content: { color: '#1890ff' } }}
/>
<div style={{ marginTop: '8px' }}>
<Text type="secondary" style={{ fontSize: '12px' }}>
<Text type="success">+12.5%</Text>
</Text>
</div>
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card>
<Statistic
title="在线用户"
value={dashboardStats.activeUsers}
prefix={<TeamOutlined style={{ color: '#52c41a' }} />}
suffix="人"
styles={{ content: { color: '#52c41a' } }}
/>
<div style={{ marginTop: '8px' }}>
<Progress
percent={Math.round((dashboardStats.activeUsers / dashboardStats.totalUsers) * 100)}
size="small"
showInfo={false}
strokeColor="#52c41a"
/>
</div>
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card>
<Statistic
title="今日收入"
value={dashboardStats.todayRevenue}
prefix={<DollarOutlined style={{ color: '#fa8c16' }} />}
suffix="元"
precision={2}
styles={{ content: { color: '#fa8c16' } }}
/>
<div style={{ marginTop: '8px' }}>
<Text type="secondary" style={{ fontSize: '12px' }}>
<Text type="success">+8.3%</Text>
</Text>
</div>
</Card>
</Col>
<Col xs={24} sm={12} lg={6}>
<Card>
<Statistic
title="月度收入"
value={dashboardStats.monthlyRevenue}
prefix={<RiseOutlined style={{ color: '#722ed1' }} />}
suffix="元"
precision={2}
styles={{ content: { color: '#722ed1' } }}
/>
<div style={{ marginTop: '8px' }}>
<Text type="secondary" style={{ fontSize: '12px' }}>
<Text type="success">85.6%</Text>
</Text>
</div>
</Card>
</Col>
</Row>
{/* 主要内容区域 */}
<Row gutter={[16, 16]}>
{/* 快速操作 */}
<Col xs={24} lg={8}>
<Card title="快速操作" style={{ height: '100%' }}>
<Row gutter={[16, 16]}>
{quickActions.map((action, index) => (
<Col xs={12} key={index}>
<Button
type="default"
icon={action.icon}
style={{
height: '80px',
width: '100%',
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
justifyContent: 'center',
borderColor: action.color,
color: action.color
}}
onClick={action.action}
>
<div style={{ fontSize: '18px', marginBottom: '4px' }}>
{action.icon}
</div>
<span style={{ fontSize: '12px' }}>{action.title}</span>
</Button>
</Col>
))}
</Row>
</Card>
</Col>
{/* 最近活动 */}
<Col xs={24} lg={8}>
<Card title="最近活动" style={{ height: '100%' }}>
<div style={{ maxHeight: '300px', overflow: 'auto' }}>
{recentActivities.map((item) => (
<div key={item.id} style={{
padding: '12px 0',
borderBottom: '1px solid #f0f0f0',
display: 'flex',
alignItems: 'flex-start',
gap: '8px'
}}>
<div style={{ marginTop: '2px' }}>
{getStatusIcon(item.status)}
</div>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{
display: 'flex',
justifyContent: 'space-between',
marginBottom: '4px'
}}>
<Text strong style={{ fontSize: '13px' }}>{item.user}</Text>
<Text type="secondary" style={{ fontSize: '12px' }}>{item.time}</Text>
</div>
<Text type="secondary" style={{ fontSize: '12px' }}>
{item.action}
</Text>
</div>
</div>
))}
</div>
<div style={{ textAlign: 'center', marginTop: '16px' }}>
<Button type="link" size="small"></Button>
</div>
</Card>
</Col>
{/* 系统状态 */}
<Col xs={24} lg={8}>
<Card title="系统状态" style={{ height: '100%' }}>
<div style={{ marginBottom: '16px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '8px' }}>
<Text>线</Text>
<Text strong>
{Math.round((dashboardStats.onlineServers / dashboardStats.totalServers) * 100)}%
</Text>
</div>
<Progress
percent={Math.round((dashboardStats.onlineServers / dashboardStats.totalServers) * 100)}
strokeColor={dashboardStats.onlineServers === dashboardStats.totalServers ? '#52c41a' : '#faad14'}
size="small"
/>
</div>
<div style={{ marginBottom: '16px' }}>
<Text strong style={{ fontSize: '13px' }}></Text>
</div>
<div style={{ maxHeight: '200px', overflow: 'auto' }}>
{systemAlerts.map((alert) => (
<div key={alert.id} style={{ padding: '8px 0', display: 'flex', alignItems: 'center', gap: '8px' }}>
<Tag color={getAlertColor(alert.type)} style={{ margin: 0 }}>
{alert.type === 'error' ? '错误' : alert.type === 'warning' ? '警告' : '信息'}
</Tag>
<Text style={{ fontSize: '12px', flex: 1 }}>
{alert.message}
</Text>
<Text type="secondary" style={{ fontSize: '11px' }}>
{alert.time}
</Text>
</div>
))}
</div>
<div style={{ textAlign: 'center', marginTop: '16px' }}>
<Button type="link" size="small"></Button>
</div>
</Card>
</Col>
</Row>
{/* 底部信息 */}
<Row style={{ marginTop: '24px' }}>
<Col span={24}>
<Card>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
<Space>
<TrophyOutlined style={{ color: '#faad14', fontSize: '18px' }} />
<div>
<Text strong></Text>
<br />
<Text type="secondary" style={{ fontSize: '12px' }}>
- 1,256
</Text>
</div>
</Space>
<Space>
<Text type="secondary" style={{ fontSize: '12px' }}>
v1.0.0 | 2025-12-12
</Text>
</Space>
</div>
</Card>
</Col>
</Row>
</div>
);
};
export default AdminDashboard;