import 'package:flutter/material.dart'; import '../../models/record.dart'; class MonthlyOverview extends StatelessWidget { final List records; final bool isYearView; const MonthlyOverview({ Key? key, required this.records, this.isYearView = false, }) : super(key: key); @override Widget build(BuildContext context) { final totalExpense = records .where((r) => r.type == RecordType.expense) .fold(0.0, (sum, r) => sum + r.amount); final totalIncome = records .where((r) => r.type == RecordType.income) .fold(0.0, (sum, r) => sum + r.amount); final balance = totalIncome - totalExpense; // 计算日均支出 final daysInPeriod = isYearView ? (records.isNotEmpty ? _getDaysInYear(records.first.createTime.year) : 365) : (records.isNotEmpty ? _getDaysInMonth(records.first.createTime) : 30); final dailyAverage = totalExpense / daysInPeriod; return Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 8, offset: const Offset(0, 2), ), ], ), child: Column( children: [ Row( children: [ Expanded( child: _buildOverviewItem( label: '${isYearView ? "年" : "月"}支出', amount: totalExpense, textColor: Colors.red, ), ), Expanded( child: _buildOverviewItem( label: '${isYearView ? "年" : "月"}收入', amount: totalIncome, textColor: Colors.green, ), ), ], ), const SizedBox(height: 16), Row( children: [ Expanded( child: _buildOverviewItem( label: '结余', amount: balance, textColor: balance >= 0 ? Colors.green : Colors.red, showSign: true, ), ), Expanded( child: _buildOverviewItem( label: '日均支出', amount: dailyAverage, textColor: Colors.grey[800]!, ), ), ], ), ], ), ); } int _getDaysInMonth(DateTime date) { return DateTime(date.year, date.month + 1, 0).day; } int _getDaysInYear(int year) { return DateTime(year).isLeapYear ? 366 : 365; } Widget _buildOverviewItem({ required String label, required double amount, required Color textColor, bool showSign = false, }) { String amountText = '¥${amount.toStringAsFixed(2)}'; if (showSign && amount > 0) { amountText = '+$amountText'; } return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( label, style: TextStyle( fontSize: 14, color: Colors.grey[600], ), ), const SizedBox(height: 4), Text( amountText, style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: textColor, ), ), ], ); } } extension DateTimeExtension on DateTime { bool get isLeapYear { return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); } }