Files
d8d-admin-mobile-starter-pu…/client/admin/pages_chart.tsx
yourname 08ae3b85df 完整API模块结构:
client/admin/api/ ├── auth.ts (认证API) ├── users.ts (用户API) ├── files.ts (文件API) ├── theme.ts (主题API) ├── charts.ts (图表API) ├── messages.ts (消息API) ├── sys.ts (系统API) ├── know_info.ts (知识库API) ├── maps.ts (地图API) └── index.ts (统一入口)
2025-05-13 08:06:34 +00:00

205 lines
4.5 KiB
TypeScript

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>
);
};