141 lines
4.2 KiB
React
141 lines
4.2 KiB
React
import React, { useState, useEffect } from 'react'
|
||||
|
|
import { Card, Row, Col, Statistic, Spin } from 'antd'
|
|||
|
|
import {
|
|||
|
|
DesktopOutlined,
|
|||
|
|
TeamOutlined,
|
|||
|
|
BellOutlined,
|
|||
|
|
CheckCircleOutlined,
|
|||
|
|
ToolOutlined,
|
|||
|
|
CloseCircleOutlined,
|
|||
|
|
ExclamationCircleOutlined
|
|||
|
|
} from '@ant-design/icons'
|
|||
|
|
import axios from 'axios'
|
|||
|
|
|
|||
|
|
function Dashboard({ onNavigate }) {
|
|||
|
|
const [stats, setStats] = useState(null)
|
|||
|
|
const [loading, setLoading] = useState(true)
|
|||
|
|
|
|||
|
|
useEffect(() => {
|
|||
|
|
fetchStats()
|
|||
|
|
}, [])
|
|||
|
|
|
|||
|
|
const fetchStats = async () => {
|
|||
|
|
try {
|
|||
|
|
const res = await axios.get('/api/dashboard/stats')
|
|||
|
|
if (res.data.success) {
|
|||
|
|
setStats(res.data.data)
|
|||
|
|
}
|
|||
|
|
} catch (err) {
|
|||
|
|
console.error('获取统计数据失败:', err)
|
|||
|
|
} finally {
|
|||
|
|
setLoading(false)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (loading) {
|
|||
|
|
return <div style={{ textAlign: 'center', padding: 60 }}><Spin size="large" tip="加载中..." /></div>
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div>
|
|||
|
|
<h2 style={{ marginBottom: 24 }}>数据概览</h2>
|
|||
|
|
<Row gutter={[16, 16]}>
|
|||
|
|
<Col xs={24} sm={12} lg={6}>
|
|||
|
|
<Card className="dashboard-card" onClick={() => onNavigate('devices')}>
|
|||
|
|
<Statistic
|
|||
|
|
title="设备总数"
|
|||
|
|
value={stats?.deviceTotal || 0}
|
|||
|
|
prefix={<DesktopOutlined />}
|
|||
|
|
valueStyle={{ color: '#1890ff' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
<Col xs={24} sm={12} lg={6}>
|
|||
|
|
<Card className="dashboard-card">
|
|||
|
|
<Statistic
|
|||
|
|
title="正常运行"
|
|||
|
|
value={stats?.deviceNormal || 0}
|
|||
|
|
prefix={<CheckCircleOutlined />}
|
|||
|
|
valueStyle={{ color: '#52c41a' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
<Col xs={24} sm={12} lg={6}>
|
|||
|
|
<Card className="dashboard-card">
|
|||
|
|
<Statistic
|
|||
|
|
title="维修中"
|
|||
|
|
value={stats?.deviceRepairing || 0}
|
|||
|
|
prefix={<ToolOutlined />}
|
|||
|
|
valueStyle={{ color: '#faad14' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
<Col xs={24} sm={12} lg={6}>
|
|||
|
|
<Card className="dashboard-card">
|
|||
|
|
<Statistic
|
|||
|
|
title="已报废"
|
|||
|
|
value={stats?.deviceScrapped || 0}
|
|||
|
|
prefix={<CloseCircleOutlined />}
|
|||
|
|
valueStyle={{ color: '#f5222d' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
</Row>
|
|||
|
|
|
|||
|
|
<Row gutter={[16, 16]} style={{ marginTop: 16 }}>
|
|||
|
|
<Col xs={24} sm={12} lg={8}>
|
|||
|
|
<Card className="dashboard-card" onClick={() => onNavigate('personnel')}>
|
|||
|
|
<Statistic
|
|||
|
|
title="人员总数"
|
|||
|
|
value={stats?.personnelTotal || 0}
|
|||
|
|
prefix={<TeamOutlined />}
|
|||
|
|
valueStyle={{ color: '#722ed1' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
<Col xs={24} sm={12} lg={8}>
|
|||
|
|
<Card className="dashboard-card">
|
|||
|
|
<Statistic
|
|||
|
|
title="在职人员"
|
|||
|
|
value={stats?.personnelActive || 0}
|
|||
|
|
prefix={<CheckCircleOutlined />}
|
|||
|
|
valueStyle={{ color: '#13c2c2' }}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
<Col xs={24} sm={12} lg={8}>
|
|||
|
|
<Card className="dashboard-card" onClick={() => onNavigate('notifications')}>
|
|||
|
|
<Statistic
|
|||
|
|
title="未读通知"
|
|||
|
|
value={stats?.notifUnread || 0}
|
|||
|
|
prefix={<ExclamationCircleOutlined />}
|
|||
|
|
valueStyle={{ color: '#fa541c' }}
|
|||
|
|
suffix={<span style={{ fontSize: 14, color: '#999' }}>/ {stats?.notifTotal || 0}</span>}
|
|||
|
|
/>
|
|||
|
|
</Card>
|
|||
|
|
</Col>
|
|||
|
|
</Row>
|
|||
|
|
|
|||
|
|
<Card style={{ marginTop: 24 }}>
|
|||
|
|
<h3>系统信息</h3>
|
|||
|
|
<Row gutter={16} style={{ marginTop: 12 }}>
|
|||
|
|
<Col span={8}>
|
|||
|
|
<p><strong>系统版本:</strong>v1.0.0</p>
|
|||
|
|
<p><strong>系统名称:</strong>设备管理系统</p>
|
|||
|
|
</Col>
|
|||
|
|
<Col span={8}>
|
|||
|
|
<p><strong>数据库:</strong>SQLite</p>
|
|||
|
|
<p><strong>前端框架:</strong>React + Ant Design</p>
|
|||
|
|
</Col>
|
|||
|
|
<Col span={8}>
|
|||
|
|
<p><strong>后端框架:</strong>Express.js</p>
|
|||
|
|
<p><strong>部署方式:</strong>服务器 / 桌面应用</p>
|
|||
|
|
</Col>
|
|||
|
|
</Row>
|
|||
|
|
</Card>
|
|||
|
|
</div>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
export default Dashboard
|