feat(web): wire Home dashboard to real API data
Replace hardcoded placeholder values with live data fetched from /users, /roles, /workflow/instances, and message store unread count. Uses Promise.allSettled for resilient parallel loading.
This commit is contained in:
@@ -1,37 +1,97 @@
|
|||||||
import { Typography, Card, Row, Col, Statistic } from 'antd';
|
import { useEffect, useState } from 'react';
|
||||||
|
import { Typography, Card, Row, Col, Statistic, Spin } from 'antd';
|
||||||
import {
|
import {
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
TeamOutlined,
|
TeamOutlined,
|
||||||
FileTextOutlined,
|
FileTextOutlined,
|
||||||
BellOutlined,
|
BellOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
|
import client from '../api/client';
|
||||||
|
import { useMessageStore } from '../stores/message';
|
||||||
|
|
||||||
|
interface DashboardStats {
|
||||||
|
userCount: number;
|
||||||
|
roleCount: number;
|
||||||
|
processInstanceCount: number;
|
||||||
|
unreadMessages: number;
|
||||||
|
}
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
const [stats, setStats] = useState<DashboardStats>({
|
||||||
|
userCount: 0,
|
||||||
|
roleCount: 0,
|
||||||
|
processInstanceCount: 0,
|
||||||
|
unreadMessages: 0,
|
||||||
|
});
|
||||||
|
const [loading, setLoading] = useState(true);
|
||||||
|
const { unreadCount, fetchUnreadCount } = useMessageStore();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
async function loadStats() {
|
||||||
|
setLoading(true);
|
||||||
|
try {
|
||||||
|
// 并行请求各模块统计数据
|
||||||
|
const [usersRes, rolesRes, instancesRes] = await Promise.allSettled([
|
||||||
|
client.get('/users', { params: { page: 1, page_size: 1 } }),
|
||||||
|
client.get('/roles', { params: { page: 1, page_size: 1 } }),
|
||||||
|
client.get('/workflow/instances', { params: { page: 1, page_size: 1 } }),
|
||||||
|
]);
|
||||||
|
|
||||||
|
const extractTotal = (res: PromiseSettledResult<{ data: { data?: { total?: number } } }>) =>
|
||||||
|
res.status === 'fulfilled' ? (res.value.data?.data?.total ?? 0) : 0;
|
||||||
|
|
||||||
|
setStats({
|
||||||
|
userCount: extractTotal(usersRes),
|
||||||
|
roleCount: extractTotal(rolesRes),
|
||||||
|
processInstanceCount: extractTotal(instancesRes),
|
||||||
|
unreadMessages: unreadCount,
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
// 静默处理,显示默认值
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchUnreadCount();
|
||||||
|
loadStats();
|
||||||
|
}, [fetchUnreadCount, unreadCount]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Typography.Title level={4}>工作台</Typography.Title>
|
<Typography.Title level={4}>工作台</Typography.Title>
|
||||||
|
<Spin spinning={loading}>
|
||||||
<Row gutter={[16, 16]}>
|
<Row gutter={[16, 16]}>
|
||||||
<Col xs={24} sm={12} md={6}>
|
<Col xs={24} sm={12} md={6}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic title="用户总数" value={0} prefix={<UserOutlined />} />
|
<Statistic title="用户总数" value={stats.userCount} prefix={<UserOutlined />} />
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={12} md={6}>
|
<Col xs={24} sm={12} md={6}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic title="角色数量" value={0} prefix={<TeamOutlined />} />
|
<Statistic title="角色数量" value={stats.roleCount} prefix={<TeamOutlined />} />
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={12} md={6}>
|
<Col xs={24} sm={12} md={6}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic title="流程实例" value={0} prefix={<FileTextOutlined />} />
|
<Statistic
|
||||||
|
title="流程实例"
|
||||||
|
value={stats.processInstanceCount}
|
||||||
|
prefix={<FileTextOutlined />}
|
||||||
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
<Col xs={24} sm={12} md={6}>
|
<Col xs={24} sm={12} md={6}>
|
||||||
<Card>
|
<Card>
|
||||||
<Statistic title="未读消息" value={0} prefix={<BellOutlined />} />
|
<Statistic
|
||||||
|
title="未读消息"
|
||||||
|
value={stats.unreadMessages}
|
||||||
|
prefix={<BellOutlined />}
|
||||||
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
</Spin>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user