| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- import React from 'react';
- import {
- Card, Spin, Row, Col, Statistic,
- } from 'antd';
- import {
- useQuery,
- } from '@tanstack/react-query';
- import { Line , Pie, Column} from "@ant-design/plots";
- import 'dayjs/locale/zh-cn';
- import { ChartAPI } from './api/index.ts';
- import { useTheme } from './hooks_sys.tsx';
- // 用户活跃度图表组件
- const UserActivityChart: React.FC = () => {
- const { isDark } = useTheme();
- const { data: activityData, isLoading } = useQuery({
- queryKey: ['userActivity'],
- queryFn: async () => {
- const response = await ChartAPI.getUserActivity();
- return response.data;
- }
- });
- if (isLoading) return <Spin />;
- const config = {
- data: activityData || [],
- xField: 'date',
- yField: 'count',
- smooth: true,
- theme: isDark ? 'dark' : 'light',
- color: '#1890ff',
- areaStyle: {
- fill: 'l(270) 0:#1890ff10 1:#1890ff',
- },
- };
- return (
- <Card title="用户活跃度趋势" variant="borderless">
- <Line {...config} />
- </Card>
- );
- };
- // 文件上传统计图表组件
- const FileUploadsChart: React.FC = () => {
- const { isDark } = useTheme();
- const { data: uploadsData, isLoading } = useQuery({
- queryKey: ['fileUploads'],
- queryFn: async () => {
- const response = await ChartAPI.getFileUploads();
- return response.data;
- }
- });
- if (isLoading) return <Spin />;
- const config = {
- data: uploadsData || [],
- xField: 'month',
- yField: 'count',
- theme: isDark ? 'dark' : 'light',
- color: '#52c41a',
- label: {
- position: 'middle',
- style: {
- fill: '#FFFFFF',
- opacity: 0.6,
- },
- },
- meta: {
- month: {
- alias: '月份',
- },
- count: {
- alias: '上传数量',
- },
- },
- };
- return (
- <Card title="文件上传统计" variant="borderless">
- <Column {...config} />
- </Card>
- );
- };
- // 文件类型分布图表组件
- const FileTypesChart: React.FC = () => {
- const { isDark } = useTheme();
- const { data: typesData, isLoading } = useQuery({
- queryKey: ['fileTypes'],
- queryFn: async () => {
- const response = await ChartAPI.getFileTypes();
- return response.data;
- }
- });
- if (isLoading) return <Spin />;
- const config = {
- data: typesData || [],
- angleField: 'value',
- colorField: 'type',
- radius: 0.8,
- theme: isDark ? 'dark' : 'light',
- label: {
- type: 'spider',
- labelHeight: 28,
- content: '{name}\n{percentage}',
- },
- interactions: [
- {
- type: 'element-active',
- },
- ],
- };
- return (
- <Card title="文件类型分布" variant="borderless">
- <Pie {...config} />
- </Card>
- );
- };
- // 仪表盘概览组件
- const DashboardOverview: React.FC = () => {
- const { data: overviewData, isLoading } = useQuery({
- queryKey: ['dashboardOverview'],
- queryFn: async () => {
- const response = await ChartAPI.getDashboardOverview();
- return response.data;
- }
- });
- if (isLoading) return <Spin />;
- return (
- <Row gutter={[16, 16]}>
- <Col xs={12} sm={12} md={6}>
- <Card variant="borderless">
- <Statistic
- title="用户总数"
- value={overviewData?.userCount || 0}
- valueStyle={{ color: '#1890ff' }}
- />
- </Card>
- </Col>
- <Col xs={12} sm={12} md={6}>
- <Card variant="borderless">
- <Statistic
- title="文件总数"
- value={overviewData?.fileCount || 0}
- valueStyle={{ color: '#52c41a' }}
- />
- </Card>
- </Col>
- <Col xs={12} sm={12} md={6}>
- <Card variant="borderless">
- <Statistic
- title="文章总数"
- value={overviewData?.articleCount || 0}
- valueStyle={{ color: '#faad14' }}
- />
- </Card>
- </Col>
- <Col xs={12} sm={12} md={6}>
- <Card variant="borderless">
- <Statistic
- title="今日登录"
- value={overviewData?.todayLoginCount || 0}
- valueStyle={{ color: '#722ed1' }}
- />
- </Card>
- </Col>
- </Row>
- );
- };
- // 图表仪表盘页面组件
- export const ChartDashboardPage: React.FC = () => {
- return (
- <div className="chart-dashboard">
- <DashboardOverview />
- <div style={{ height: 24 }} />
- <Row gutter={[16, 16]}>
- <Col xs={24} lg={12}>
- <UserActivityChart />
- </Col>
- <Col xs={24} lg={12}>
- <FileUploadsChart />
- </Col>
- <Col xs={24}>
- <FileTypesChart />
- </Col>
- </Row>
- </div>
- );
- };
|