From c10e8e5ffb4643832e5233c8d58b8c0bf23d9e0c Mon Sep 17 00:00:00 2001 From: Cxx0822 <1556464090@qq.com> Date: Sun, 28 Jun 2026 19:54:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=9B=B4=E6=96=B0=E5=A5=BD=E5=8F=8B?= =?UTF-8?q?=E8=8F=9C=E8=B0=B1=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/apis/recipe.dart | 6 +++--- lib/models/recipe.dart | 2 -- lib/models/recipe.g.dart | 2 -- lib/provider/food_provider.dart | 20 ++++++++++++++++++++ lib/views/login.dart | 2 +- lib/views/profile.dart | 5 ++++- lib/views/profile_user.dart | 8 ++++---- lib/views/recipe_detail.dart | 11 ++++++++++- lib/views/record.dart | 2 +- lib/views/stats.dart | 15 ++++++++------- lib/widgets/profile/basic_info.dart | 2 +- lib/widgets/recipe/card.dart | 8 ++++++-- lib/widgets/recipe/list.dart | 13 +++++++++---- 13 files changed, 67 insertions(+), 29 deletions(-) diff --git a/lib/apis/recipe.dart b/lib/apis/recipe.dart index 3926656..da62fe9 100644 --- a/lib/apis/recipe.dart +++ b/lib/apis/recipe.dart @@ -25,10 +25,10 @@ Future deleteRecipeApi(int id) { return httpUtil.delete("/food/recipe/$id"); } -Future> queryRecipeByUserApi(int id) { - return httpUtil.get>( +Future> queryRecipeByUserApi(int id) { + return httpUtil.get>( "/food/recipe/user/$id", - converter: (data) => convertList(data, Recipe.fromJson), + converter: (data) => convertList(data, RecipeSummary.fromJson), ); } diff --git a/lib/models/recipe.dart b/lib/models/recipe.dart index 6678390..7ba6a29 100644 --- a/lib/models/recipe.dart +++ b/lib/models/recipe.dart @@ -176,7 +176,6 @@ class RecipeSummary { int commentCount; int userId; String username; - String avatar; RecipeSummary({ required this.id, @@ -186,7 +185,6 @@ class RecipeSummary { required this.isShare, required this.userId, required this.username, - required this.avatar, required this.recordList, required this.likeCount, required this.favouriteCount, diff --git a/lib/models/recipe.g.dart b/lib/models/recipe.g.dart index 04a2051..0cc2b44 100644 --- a/lib/models/recipe.g.dart +++ b/lib/models/recipe.g.dart @@ -149,7 +149,6 @@ RecipeSummary _$RecipeSummaryFromJson(Map json) => isShare: json['isShare'] as bool, userId: (json['userId'] as num).toInt(), username: json['username'] as String, - avatar: json['avatar'] as String, recordList: (json['recordList'] as List) .map((e) => FoodRecord.fromJson(e as Map)) @@ -172,7 +171,6 @@ Map _$RecipeSummaryToJson(RecipeSummary instance) => 'commentCount': instance.commentCount, 'userId': instance.userId, 'username': instance.username, - 'avatar': instance.avatar, }; RecipeDetail _$RecipeDetailFromJson(Map json) => RecipeDetail( diff --git a/lib/provider/food_provider.dart b/lib/provider/food_provider.dart index 94fbd27..8fb3d6d 100644 --- a/lib/provider/food_provider.dart +++ b/lib/provider/food_provider.dart @@ -116,6 +116,26 @@ class FoodProvider with ChangeNotifier { } } + Future queryRecipeByUserId(int userId) async { + if (isLoading) return; + + try { + isLoading = true; + error = null; + notifyListeners(); + + final result = await queryRecipeByUserApi(userId); + recipeSummaryList = result; + notifyListeners(); + } catch (e) { + error = '加载数据失败: $e'; + debugPrint('加载数据失败: $e'); + } finally { + isLoading = false; + notifyListeners(); + } + } + Future refreshRecipeList() async { if (isLoading) return; diff --git a/lib/views/login.dart b/lib/views/login.dart index af40d2b..e8660e6 100644 --- a/lib/views/login.dart +++ b/lib/views/login.dart @@ -19,7 +19,7 @@ class LoginPage extends StatefulWidget { class _LoginPage extends State { final GlobalKey _formKey = GlobalKey(); - String _username = "Cxx0822", _password = "19940822Cxx"; + String _username = "", _password = ""; bool _isRemember = false; bool _isObscure = true; bool _isLoading = false; diff --git a/lib/views/profile.dart b/lib/views/profile.dart index d602c0a..f9806c3 100644 --- a/lib/views/profile.dart +++ b/lib/views/profile.dart @@ -158,7 +158,10 @@ class ProfilePageState extends State { else if (provider.error.isNotEmpty) Text(provider.error) else - SingleChildScrollView(child: _buildContent(provider, context)), + SingleChildScrollView( + padding: const EdgeInsets.only(bottom: 90), + child: _buildContent(provider, context), + ), ], ), ), diff --git a/lib/views/profile_user.dart b/lib/views/profile_user.dart index b9afdc3..f71b522 100644 --- a/lib/views/profile_user.dart +++ b/lib/views/profile_user.dart @@ -74,7 +74,7 @@ class ProfileUserPageState extends State { index: currentTab.index, children: [ MomentList(momentList: provider.momentList, isUser: false), - Text('个人菜谱'), + RecipeList(userId: provider.currentUser.id!), ], ), ), @@ -91,11 +91,11 @@ class ProfileUserPageState extends State { appBar: AppBar( title: Text( '${provider.currentUser.username}的个人信息', - style: const TextStyle(color: Colors.white), + style: Theme.of(context).textTheme.titleLarge, ), - backgroundColor: colors.primary, + backgroundColor: Theme.of(context).scaffoldBackgroundColor, leading: IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.white), + icon: Icon(Icons.arrow_back, color: colors.primary), onPressed: () => Navigator.pop(context), ), ), diff --git a/lib/views/recipe_detail.dart b/lib/views/recipe_detail.dart index 2df5519..0d66111 100644 --- a/lib/views/recipe_detail.dart +++ b/lib/views/recipe_detail.dart @@ -82,8 +82,17 @@ class _RecipeDetailState extends State { @override Widget build(BuildContext context) { + final colors = Theme.of(context).colorScheme; + return Scaffold( - appBar: AppBar(title: Text('菜谱信息')), + appBar: AppBar( + title: Text('菜谱信息', style: Theme.of(context).textTheme.titleLarge), + backgroundColor: Theme.of(context).scaffoldBackgroundColor, + leading: IconButton( + icon: Icon(Icons.arrow_back, color: colors.primary), + onPressed: () => Navigator.pop(context), + ), + ), body: SingleChildScrollView( child: Column( children: [ diff --git a/lib/views/record.dart b/lib/views/record.dart index d1243a2..e16cddd 100644 --- a/lib/views/record.dart +++ b/lib/views/record.dart @@ -36,7 +36,7 @@ class _RecordPageState extends State { final ScrollController _scrollController = ScrollController(); bool _showScrollToTop = false; final List _tabPages = [ - RecipeList(), + RecipeList(userId: 0), RecipeCalendar(), RecipeTimeline(), ]; diff --git a/lib/views/stats.dart b/lib/views/stats.dart index c79dba8..2e48c41 100644 --- a/lib/views/stats.dart +++ b/lib/views/stats.dart @@ -40,6 +40,7 @@ class _StatsPage extends State { GlassCard( useOwnLayer: true, settings: LiquidGlassSettings(glassColor: colors.surface), + padding: EdgeInsetsGeometry.all(10), child: StatsCard( icon: Icons.restaurant_menu, title: '菜谱总数', @@ -50,6 +51,7 @@ class _StatsPage extends State { GlassCard( useOwnLayer: true, settings: LiquidGlassSettings(glassColor: colors.surface), + padding: EdgeInsetsGeometry.all(10), child: StatsCard( icon: Icons.grid_view_rounded, title: '菜谱类别', @@ -60,6 +62,7 @@ class _StatsPage extends State { GlassCard( useOwnLayer: true, settings: LiquidGlassSettings(glassColor: colors.surface), + padding: EdgeInsetsGeometry.all(10), child: StatsCard( icon: Icons.flag, title: '做菜次数', @@ -70,6 +73,7 @@ class _StatsPage extends State { GlassCard( useOwnLayer: true, settings: LiquidGlassSettings(glassColor: colors.surface), + padding: EdgeInsetsGeometry.all(10), child: StatsCard( icon: Icons.show_chart, title: '平均次数', @@ -116,13 +120,10 @@ class _StatsPage extends State { ), ), SizedBox(height: 8), - SizedBox( - height: chartHeight, - child: GlassCard( - useOwnLayer: true, - settings: LiquidGlassSettings(glassColor: colors.surface), - child: RankChart(title: '排行榜', data: provider.rankStats, unit: '次'), - ), + GlassCard( + useOwnLayer: true, + settings: LiquidGlassSettings(glassColor: colors.surface), + child: RankChart(title: '排行榜', data: provider.rankStats, unit: '次'), ), ], ); diff --git a/lib/widgets/profile/basic_info.dart b/lib/widgets/profile/basic_info.dart index a7ae219..e16317d 100644 --- a/lib/widgets/profile/basic_info.dart +++ b/lib/widgets/profile/basic_info.dart @@ -44,7 +44,7 @@ class ProfileInfo extends StatelessWidget { children: [ Icon(icon, size: 16, color: colors.primary), const SizedBox(width: 6), - Text(text, style: Theme.of(context).textTheme.bodyMedium), + Text(text, style: Theme.of(context).textTheme.bodySmall), ], ); } diff --git a/lib/widgets/recipe/card.dart b/lib/widgets/recipe/card.dart index 196f620..02c0469 100644 --- a/lib/widgets/recipe/card.dart +++ b/lib/widgets/recipe/card.dart @@ -29,7 +29,6 @@ class RecipeCard extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ CommonImage(imageUrls: imageUrls, index: 0), - SizedBox(height: 8), InkWell( onTap: () => navigatorToRecipeDetail(context), child: _buildRecipeContent(context), @@ -56,6 +55,11 @@ class RecipeCard extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, ), + _buildIconText( + icon: Icons.star, + text: recipe.recommendRate.toString(), + color: colors.primary, + ), ], ), SizedBox(height: 5), @@ -70,7 +74,7 @@ class RecipeCard extends StatelessWidget { const SizedBox(width: 12), _buildIconText( icon: Icons.note_add, - text: recipe.recordList.length.toString(), + text: '${recipe.recordList.length.toString()}次', color: colors.primary, ), ], diff --git a/lib/widgets/recipe/list.dart b/lib/widgets/recipe/list.dart index a2bbe4e..afe7470 100644 --- a/lib/widgets/recipe/list.dart +++ b/lib/widgets/recipe/list.dart @@ -5,7 +5,9 @@ import 'package:food_hub_app/widgets/recipe/card.dart'; import 'package:provider/provider.dart'; class RecipeList extends StatefulWidget { - const RecipeList({super.key}); + final int userId; + + const RecipeList({super.key, required this.userId}); @override State createState() => _RecipeListState(); @@ -18,8 +20,11 @@ class _RecipeListState extends State { // 初始化加载数据 WidgetsBinding.instance.addPostFrameCallback((_) { - context.read().refreshRecipeList(); - context.read().queryCategoryList(); + if (widget.userId == 0) { + context.read().refreshRecipeList(); + } else { + context.read().queryRecipeByUserId(widget.userId); + } }); } @@ -30,7 +35,7 @@ class _RecipeListState extends State { crossAxisCount: 2, crossAxisSpacing: 8, mainAxisSpacing: 8, - childAspectRatio: 0.9, + childAspectRatio: 0.85, ), itemCount: provider.recipeSummaryList.length, itemBuilder: (context, index) {