import 'package:blog_app/utils/index.dart'; import 'package:provider/provider.dart'; import 'package:blog_app/provider/blog.dart'; import 'package:blog_app/widget/blog.dart'; import 'package:blog_app/widget/chart.dart'; import 'package:blog_app/widget/common.dart'; import 'package:blog_app/widget/year_selector.dart'; import 'package:flutter/material.dart'; class StatsPage extends StatefulWidget { const StatsPage({super.key}); @override StatsPageState createState() => StatsPageState(); } class StatsPageState extends State { final double chartHeight = 400; final double statsHeight = 120; @override void initState() { super.initState(); // 初始化加载数据 WidgetsBinding.instance.addPostFrameCallback((_) { context.read().refreshBlogStats(); }); } Widget _buildApprovedStats(BlogProvider provider) { return Column( children: [ buildChartTitle(context, '每月博客发布统计', Icons.show_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), Expanded( child: lineChart( context: context, xAxisName: '月份', yAxisName: '数量', unit: '篇', data: provider.approvedStats, ), ), ], ); } Widget _buildVisitStats(BlogProvider provider) { return Column( children: [ buildChartTitle(context, '每月博客访问统计', Icons.show_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), Expanded( child: lineChart( context: context, xAxisName: '月份', yAxisName: '访问量', unit: '人次', data: provider.visitStats, ), ), ], ); } Widget _buildVisitRankStats(BlogProvider provider) { return Column( children: [ buildChartTitle(context, '博客访问数量排行', Icons.bar_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), Expanded( child: barChart( context: context, xAxisName: '名称', yAxisName: '访问量', unit: '人次', data: provider.visitRankStats, ), ), ], ); } Widget _buildCategoryStats(BlogProvider provider) { return Column( children: [ buildChartTitle(context, '博客类别统计', Icons.pie_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), Expanded( child: pieChart( context: context, unit: '篇', data: provider.categoryStats, ), ), ], ); } Widget _buildReadRankStats(BlogProvider provider) { return Column( children: [ buildChartTitle(context, '博客阅读时长排行', Icons.bar_chart), const SizedBox(height: 3), buildChartDivider(context), const SizedBox(height: 3), Expanded( child: barChart( context: context, xAxisName: '名称', yAxisName: '时长', unit: '分钟', data: provider.readRankStats, ), ), ], ); } Widget _buildBlogStatsGrid(BlogProvider provider) { return GridView.count( crossAxisCount: 2, shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), childAspectRatio: 2, mainAxisSpacing: 8, crossAxisSpacing: 8, children: [ buildStatsCard( icon: Icons.article, context: context, title: '博客数量', count: provider.overviewStats.blogCount.toString(), unit: '篇', ), buildStatsCard( icon: Icons.folder, context: context, title: '分类数量', count: provider.overviewStats.categoryCount.toString(), unit: '个', ), buildStatsCard( icon: Icons.remove_red_eye, context: context, title: '访问量', count: formatChineseDecimal(provider.overviewStats.visitCount), unit: '次', ), buildStatsCard( icon: Icons.text_fields, context: context, title: '总字数', count: formatChineseDecimal(provider.overviewStats.wordCount), unit: '字', ), ], ); } Widget _buildContent(BlogProvider provider) { if (provider.error != null) { return buildErrorInfo( errorInfo: provider.error!, onPressed: () => provider.refreshBlogStats(), ); } return Column( children: [ YearSelector( initialYear: provider.currentYear, minYear: 2000, maxYear: 2100, onYearChanged: (year) { setState(() { provider.currentYear = year; provider.refreshBlogStats(); }); }, ), const SizedBox(height: 8), _buildBlogStatsGrid(provider), const SizedBox(height: 8), SizedBox( height: chartHeight, child: BuildCard(child: _buildApprovedStats(provider)), ), const SizedBox(height: 8), SizedBox( height: chartHeight, child: BuildCard(child: _buildVisitStats(provider)), ), const SizedBox(height: 8), SizedBox( height: chartHeight, child: BuildCard(child: _buildVisitRankStats(provider)), ), const SizedBox(height: 8), SizedBox( height: chartHeight, child: BuildCard(child: _buildCategoryStats(provider)), ), const SizedBox(height: 8), SizedBox( height: chartHeight, child: BuildCard(child: _buildReadRankStats(provider)), ), ], ); } @override Widget build(BuildContext context) { final blogProvider = context.watch(); return Stack( children: [ if (blogProvider.isLoading) buildLoadingIndicator() else SingleChildScrollView(child: _buildContent(blogProvider)), ], ); } }