Files
xiaoxia-saas/apps/web/src/pages/admin/Analytics.tsx
T

191 lines
5.9 KiB
TypeScript

/**
* Admin Analytics 数据分析页面
*/
import React from 'react';
import { Card, Row, Col, Statistic, Table, DatePicker, Space } from 'antd';
import {
LineChart,
Line,
BarChart,
Bar,
PieChart,
Pie,
Cell,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
import {
ArrowUpOutlined,
UserAddOutlined,
DollarOutlined,
ProjectOutlined,
} from '@ant-design/icons';
const { RangePicker } = DatePicker;
const Analytics: React.FC = () => {
// 模拟用户增长数据
const userGrowthData = [
{ month: '1月', users: 120, paid: 15 },
{ month: '2月', users: 180, paid: 28 },
{ month: '3月', users: 240, paid: 42 },
{ month: '4月', users: 320, paid: 58 },
{ month: '5月', users: 450, paid: 89 },
{ month: '6月', users: 620, paid: 135 },
];
// 模拟营收数据
const revenueData = [
{ month: '1月', revenue: 1480 },
{ month: '2月', revenue: 2770 },
{ month: '3月', revenue: 4160 },
{ month: '4月', revenue: 5740 },
{ month: '5月', revenue: 8810 },
{ month: '6月', revenue: 13365 },
];
// 订阅计划分布
const planDistribution = [
{ name: 'Free', value: 485, color: '#8884d8' },
{ name: 'Pro', value: 120, color: '#82ca9d' },
{ name: 'Enterprise', value: 15, color: '#ffc658' },
];
// 活跃度统计
const activityStats = [
{ metric: '日活跃用户 (DAU)', value: 892, growth: '+12.5%', icon: <UserAddOutlined /> },
{ metric: '月活跃用户 (MAU)', value: 3456, growth: '+8.3%', icon: <ArrowUpOutlined /> },
{ metric: '本月收入', value: 13365, prefix: '¥', growth: '+51.6%', icon: <DollarOutlined /> },
{ metric: '活跃项目数', value: 2341, growth: '+18.2%', icon: <ProjectOutlined /> },
];
// 用户留存表格
const retentionData = [
{ cohort: '2024-01', day1: '100%', day7: '68%', day30: '45%', day90: '28%' },
{ cohort: '2024-02', day1: '100%', day7: '72%', day30: '48%', day90: '31%' },
{ cohort: '2024-03', day1: '100%', day7: '75%', day30: '52%', day90: '-' },
{ cohort: '2024-04', day1: '100%', day7: '78%', day30: '55%', day90: '-' },
{ cohort: '2024-05', day1: '100%', day7: '80%', day30: '-', day90: '-' },
];
const retentionColumns = [
{ title: 'Cohort', dataIndex: 'cohort', key: 'cohort' },
{ title: 'Day 1', dataIndex: 'day1', key: 'day1' },
{ title: 'Day 7', dataIndex: 'day7', key: 'day7' },
{ title: 'Day 30', dataIndex: 'day30', key: 'day30' },
{ title: 'Day 90', dataIndex: 'day90', key: 'day90' },
];
return (
<div style={{ padding: '24px' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 24 }}>
<h1>数据分析</h1>
<Space>
<RangePicker />
</Space>
</div>
{/* 关键指标 */}
<Row gutter={16} style={{ marginBottom: 24 }}>
{activityStats.map((stat, index) => (
<Col span={6} key={index}>
<Card>
<Statistic
title={stat.metric}
value={stat.value}
prefix={stat.prefix}
suffix={stat.icon}
valueStyle={{ color: '#3f8600' }}
/>
<div style={{ marginTop: 8, color: '#52c41a', fontSize: 14 }}>
{stat.growth} vs 上月
</div>
</Card>
</Col>
))}
</Row>
{/* 图表区域 */}
<Row gutter={16} style={{ marginBottom: 24 }}>
{/* 用户增长趋势 */}
<Col span={16}>
<Card title="用户增长趋势">
<ResponsiveContainer width="100%" height={300}>
<LineChart data={userGrowthData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Line type="monotone" dataKey="users" stroke="#8884d8" name="总用户" />
<Line type="monotone" dataKey="paid" stroke="#82ca9d" name="付费用户" />
</LineChart>
</ResponsiveContainer>
</Card>
</Col>
{/* 订阅计划分布 */}
<Col span={8}>
<Card title="订阅计划分布">
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={planDistribution}
cx="50%"
cy="50%"
labelLine={false}
label={(entry) => `${entry.name}: ${entry.value}`}
outerRadius={80}
fill="#8884d8"
dataKey="value"
>
{planDistribution.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip />
</PieChart>
</ResponsiveContainer>
</Card>
</Col>
</Row>
{/* 营收趋势 */}
<Row gutter={16} style={{ marginBottom: 24 }}>
<Col span={24}>
<Card title="营收趋势">
<ResponsiveContainer width="100%" height={300}>
<BarChart data={revenueData}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Bar dataKey="revenue" fill="#ffc658" name="收入 (¥)" />
</BarChart>
</ResponsiveContainer>
</Card>
</Col>
</Row>
{/* 用户留存表 */}
<Card title="用户留存率 (Cohort Analysis)">
<Table
columns={retentionColumns}
dataSource={retentionData}
rowKey="cohort"
pagination={false}
/>
</Card>
</div>
);
};
export default Analytics;
export const Component = Analytics;