import 'package:flutter/material.dart'; import 'package:food_hub_app/api/stats.dart'; import 'package:food_hub_app/models/stats.dart'; import 'package:food_hub_app/widgets/common/chart.dart'; import 'package:food_hub_app/widgets/stats/card.dart'; class StatsPage extends StatefulWidget { const StatsPage({super.key}); @override State createState() => _StatsPage(); } class _StatsPage extends State { final double chartHeight = 400; SummaryStats summaryStats = SummaryStats( recipeCount: 0, categoryCount: 0, workCount: 0, ); late double averageRecordCount = 0; List recordStats = []; List categoryStats = []; List rankStats = []; @override void initState() { super.initState(); refreshStats(); } Future refreshStats() async { final result1 = await queryStatsApi(); final result2 = await queryRecordStatsApi(); final result3 = await queryCategoryStatsApi(); final result4 = await queryRankStatsApi(); setState(() { summaryStats = result1; recordStats = result2; categoryStats = result3; rankStats = result4; if (recordStats.isNotEmpty) { double sumValue = recordStats.fold(0.0, (sum, item) => sum + item.value); averageRecordCount = sumValue / recordStats.length; } }); } @override Widget build(BuildContext context) { return SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(5), child: Column( children: [ _buildSummaryStats(), SizedBox( height: chartHeight, child: Card( color: Colors.white, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Padding( padding: const EdgeInsets.all(10), child: _buildRecordStats(), ), ), ), SizedBox( height: chartHeight, child: Card( color: Colors.white, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Padding( padding: const EdgeInsets.all(10), child: _buildCategoryStats(), ), ), ), SizedBox( height: chartHeight, child: Card( color: Colors.white, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), child: Padding( padding: const EdgeInsets.all(10), child: _buildRankStats(), ), ), ), ], ), ), ); } Widget _buildSummaryStats() { return GridView.count( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), // 禁用网格自身滚动 crossAxisCount: 2, // crossAxisSpacing: 5, // mainAxisSpacing: 5, childAspectRatio: 2, children: [ StatisticCard( icon: Icons.restaurant_menu, color: Colors.blue, title: '菜谱总数', value: summaryStats.recipeCount, unit: '个', ), StatisticCard( icon: Icons.grid_view_rounded, color: Colors.green, title: '菜谱类别', value: summaryStats.categoryCount, unit: '种', ), StatisticCard( icon: Icons.flag, color: Colors.orange, title: '做菜次数', value: summaryStats.workCount, unit: '个', ), StatisticCard( icon: Icons.show_chart, color: Colors.red, title: '平均次数', value: double.parse(averageRecordCount.toStringAsFixed(2)), unit: '次/月', ), ], ); } Widget _buildRecordStats() { return Column( children: [ _buildTitleSection('记录统计'), const SizedBox(height: 3), _buildDivider(), const SizedBox(height: 3), Expanded( child: lineChart( context: context, xAxisName: '日期', yAxisName: '次数', unit: '次', data: recordStats, ), ), ], ); } Widget _buildCategoryStats() { return Column( children: [ _buildTitleSection('菜谱统计'), const SizedBox(height: 3), _buildDivider(), const SizedBox(height: 3), Expanded( child: pieChart(context: context, unit: '个', data: categoryStats), ), ], ); } Widget _buildRankStats() { return Column( children: [ _buildTitleSection('排行榜'), const SizedBox(height: 3), _buildDivider(), const SizedBox(height: 3), Expanded(child: rankChart(rankStats)), ], ); } // 构建标题区域 Widget _buildTitleSection(String title) { return Row( children: [ Icon(Icons.insert_chart, color: Theme.of(context).primaryColor), Text(title), ], ); } Widget _buildDivider() { return Divider( height: 1, thickness: 1, color: Theme.of(context).primaryColor, indent: 0, endIndent: 0, ); } }