import 'package:flutter/material.dart'; import 'package:food_hub_app/models/recipe.dart'; import 'package:food_hub_app/provider/food_provider.dart'; import 'package:food_hub_app/utils/index.dart'; import 'package:food_hub_app/widgets/common/index.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:provider/provider.dart'; class RecipeCalendar extends StatefulWidget { const RecipeCalendar({super.key}); @override State createState() => _RecipeCalendarState(); } class _RecipeCalendarState extends State { TableCalendar _recipeCalendar(FoodProvider provider) { return TableCalendar( locale: 'zh_CN', headerStyle: const HeaderStyle( headerPadding: EdgeInsets.symmetric(vertical: 0), formatButtonVisible: false, titleCentered: true, ), firstDay: DateTime.utc(2010, 1, 1), lastDay: DateTime.utc(2100, 12, 31), focusedDay: provider.focusedDay, selectedDayPredicate: (day) => isSameDay(provider.selectedDay, day), onDaySelected: (selectedDay, focusedDay) { if (!isSameDay(provider.selectedDay, selectedDay)) { setState(() { provider.selectedDay = selectedDay; provider.focusedDay = focusedDay; provider.refreshSelectRecord(); }); } }, onPageChanged: (focusedDay) { provider.focusedDay = focusedDay; provider.refreshRecordList(null, null); }, // 自定义日期单元格构建器 calendarBuilders: CalendarBuilders( defaultBuilder: (context, day, focusedDay) => _buildDateItem(day, false, false, provider), selectedBuilder: (context, day, focusedDay) => _buildDateItem(day, true, false, provider), todayBuilder: (context, day, focusedDay) => _buildDateItem(day, false, true, provider), ), ); } Widget _dailyItem(BuildContext context, FoodProvider provider) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(formatDateTime(provider.selectedDay, 'MM月dd日 EEEE')), SizedBox(height: 4), if (provider.selectRecordList.isEmpty) buildEmptyData() else Expanded( child: ListView.separated( itemCount: provider.selectRecordList.length, separatorBuilder: (context, index) => SizedBox(height: 8), itemBuilder: (context, index) { return _buildRecordItem( context, provider.selectRecordList[index], ); }, ), ), ], ); } Widget _buildRecordItemAvatar(String name, Color color) { return CircleAvatar( radius: 20, backgroundColor: color, child: Text( name, style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ); } Widget _buildRecordItemBody(String name, String category) { return Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(name, style: TextStyle(fontWeight: FontWeight.bold)), SizedBox(height: 5), Text(category, style: TextStyle(color: Colors.grey)), ], ); } void _handleEditRecord(BuildContext context, FoodRecord record) { final provider = context.read(); provider.initRecordForm(record); provider.isEditing = true; Navigator.pushNamed(context, "/recordForm"); } Widget _buildRecordItem(BuildContext context, FoodRecord record) { final colors = Theme.of(context).colorScheme; return Card( elevation: 0, color: colors.primary.withAlpha(50), margin: EdgeInsets.zero, child: Padding( padding: EdgeInsets.all(10), child: Row( children: [ _buildRecordItemAvatar(record.category[0], colors.primary), SizedBox(width: 10), Expanded(child: _buildRecordItemBody(record.name, record.category)), circleIconButton( context: context, icon: Icons.chevron_right, onPressed: () => _handleEditRecord(context, record), ), ], ), ), ); } Widget _buildDateItem( DateTime day, bool isSelected, bool isToday, FoodProvider provider, ) { // 检查当前日期是否在需要显示红点的列表中 bool shouldShowRedDot = provider.recordList.any( (item) => item.date == formatDateTime(day), ); return Container( width: 40, height: 40, margin: EdgeInsets.all(2), decoration: BoxDecoration( color: isSelected ? Theme.of(context).primaryColor : isToday ? Colors.grey[300] : Colors.transparent, shape: BoxShape.circle, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ // 日期数字 Text( day.day.toString(), style: TextStyle(color: isSelected ? Colors.white : Colors.black), ), // 底部红点 - 只在指定日期显示 if (shouldShowRedDot) Container( margin: EdgeInsets.only(top: 2), width: 6, height: 6, decoration: BoxDecoration( color: Colors.red, shape: BoxShape.circle, ), ), ], ), ); } Widget _buildContent(FoodProvider provider) { return Column( children: [ BuildCard(child: _recipeCalendar(provider)), SizedBox(height: 8), Expanded(child: BuildCard(child: _dailyItem(context, provider))), ], ); } @override Widget build(BuildContext context) { final provider = context.watch(); return Stack( children: [ if (provider.isLoading) buildLoadingIndicator(context) else _buildContent(provider), ], ); } }