From e32a3968b32551e3a9fb552a4854a41ceb8ed3ed Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 16:41:46 +0800 Subject: [PATCH 01/25] flutter: cleanup QR widget stubs, fix const eval, use SharePlus.instance.share with ShareParams; add cross_file import --- jive-flutter/lib/widgets/qr_code_generator.dart | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/jive-flutter/lib/widgets/qr_code_generator.dart b/jive-flutter/lib/widgets/qr_code_generator.dart index 4b675fbd..30c6ec90 100644 --- a/jive-flutter/lib/widgets/qr_code_generator.dart +++ b/jive-flutter/lib/widgets/qr_code_generator.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:share_plus/share_plus.dart'; +import 'package:cross_file/cross_file.dart'; import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; import 'package:path_provider/path_provider.dart'; @@ -299,6 +300,7 @@ class _QrCodeGeneratorState extends State ], ); } + } } /// 操作按钮 @@ -511,3 +513,9 @@ class _InfoRow extends StatelessWidget { } } + +// Stub implementation for XFile +class _StubXFile { + final String path; + _StubXFile(this.path); +} From b73c86d0f24923323375615a3ebad4f6ee55804f Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 16:43:37 +0800 Subject: [PATCH 02/25] flutter: tidy qr_code_generator structure; remove cross_file import and leftover stub; fix const usage; migrate invite dialog share to SharePlus.instance --- jive-flutter/lib/widgets/qr_code_generator.dart | 8 -------- 1 file changed, 8 deletions(-) diff --git a/jive-flutter/lib/widgets/qr_code_generator.dart b/jive-flutter/lib/widgets/qr_code_generator.dart index 30c6ec90..4b675fbd 100644 --- a/jive-flutter/lib/widgets/qr_code_generator.dart +++ b/jive-flutter/lib/widgets/qr_code_generator.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:share_plus/share_plus.dart'; -import 'package:cross_file/cross_file.dart'; import 'dart:ui' as ui; import 'package:flutter/rendering.dart'; import 'package:path_provider/path_provider.dart'; @@ -300,7 +299,6 @@ class _QrCodeGeneratorState extends State ], ); } - } } /// 操作按钮 @@ -513,9 +511,3 @@ class _InfoRow extends StatelessWidget { } } - -// Stub implementation for XFile -class _StubXFile { - final String path; - _StubXFile(this.path); -} From ecf4aaf5a09e926b22a2763f86bf47726de0add0 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:22:43 +0800 Subject: [PATCH 03/25] =?UTF-8?q?flutter:=20analyzer=20cleanup=20batch=201?= =?UTF-8?q?0-A=20(part=201)=20=E2=80=94=20remove=20unused=20imports/locals?= =?UTF-8?q?;=20capture=20messenger=20in=20batch=20dialogs;=20restore=20Rig?= =?UTF-8?q?htClickCopy=20with=20post-await=20safety;=20tidy=20comments?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../interceptors/retry_interceptor.dart | 2 -- .../ui/components/loading/loading_widget.dart | 1 - .../transactions/transaction_list.dart | 1 - jive-flutter/lib/utils/image_utils.dart | 13 +------------ .../lib/widgets/batch_operation_bar.dart | 14 +++++++++----- .../lib/widgets/common/right_click_copy.dart | 18 ++++++++++-------- 6 files changed, 20 insertions(+), 29 deletions(-) diff --git a/jive-flutter/lib/core/network/interceptors/retry_interceptor.dart b/jive-flutter/lib/core/network/interceptors/retry_interceptor.dart index 40de9b99..41c06992 100644 --- a/jive-flutter/lib/core/network/interceptors/retry_interceptor.dart +++ b/jive-flutter/lib/core/network/interceptors/retry_interceptor.dart @@ -8,7 +8,6 @@ class RetryInterceptor extends Interceptor { final int maxRetries; final Duration baseDelay; final Duration maxDelay; - static DateTime? _lastGlobalFailure; static int _consecutiveFailures = 0; static bool _circuitOpen = false; static DateTime? _circuitOpenedAt; @@ -128,7 +127,6 @@ class RetryInterceptor extends Interceptor { } void _recordFailure() { - _lastGlobalFailure = DateTime.now(); _consecutiveFailures++; if (_consecutiveFailures >= circuitFailureThreshold && !_circuitOpen) { _circuitOpen = true; diff --git a/jive-flutter/lib/ui/components/loading/loading_widget.dart b/jive-flutter/lib/ui/components/loading/loading_widget.dart index 7f10dc3e..dc85528e 100644 --- a/jive-flutter/lib/ui/components/loading/loading_widget.dart +++ b/jive-flutter/lib/ui/components/loading/loading_widget.dart @@ -117,7 +117,6 @@ class CardLoading extends StatelessWidget { @override Widget build(BuildContext context) { - final theme = Theme.of(context); return Card( margin: margin ?? const EdgeInsets.all(8), diff --git a/jive-flutter/lib/ui/components/transactions/transaction_list.dart b/jive-flutter/lib/ui/components/transactions/transaction_list.dart index 034a9c3c..31fb531f 100644 --- a/jive-flutter/lib/ui/components/transactions/transaction_list.dart +++ b/jive-flutter/lib/ui/components/transactions/transaction_list.dart @@ -6,7 +6,6 @@ import 'package:jive_money/ui/components/loading/loading_widget.dart'; import 'package:jive_money/models/transaction.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; -import 'package:jive_money/providers/currency_provider.dart'; // 类型别名以兼容现有代码 typedef TransactionData = Transaction; diff --git a/jive-flutter/lib/utils/image_utils.dart b/jive-flutter/lib/utils/image_utils.dart index deb4bbe7..14a90739 100644 --- a/jive-flutter/lib/utils/image_utils.dart +++ b/jive-flutter/lib/utils/image_utils.dart @@ -147,18 +147,7 @@ class ImageUtils { return false; } - // Check for common image extensions - final path = uri.path.toLowerCase(); - final imageExtensions = [ - '.jpg', - '.jpeg', - '.png', - '.gif', - '.webp', - '.svg' - ]; - - // Allow URLs without extensions (many CDNs don't use them) + // Check for common image extensions// Allow URLs without extensions (many CDNs don't use them) // but validate the URL structure return uri.host.isNotEmpty; } catch (e) { diff --git a/jive-flutter/lib/widgets/batch_operation_bar.dart b/jive-flutter/lib/widgets/batch_operation_bar.dart index 9799e8af..5d26a361 100644 --- a/jive-flutter/lib/widgets/batch_operation_bar.dart +++ b/jive-flutter/lib/widgets/batch_operation_bar.dart @@ -227,10 +227,12 @@ class _BatchOperationBarState extends ConsumerState ), ElevatedButton( onPressed: () async { + final navigator = Navigator.of(context); + final messenger = ScaffoldMessenger.of(context); // TODO: 实现批量归档 - Navigator.pop(context); + navigator.pop(); widget.onCancel(); - ScaffoldMessenger.of(context).showSnackBar( + messenger.showSnackBar( SnackBar( content: Text('已归档 ${widget.selectedIds.length} 个项目'), ), @@ -299,11 +301,13 @@ class _BatchOperationBarState extends ConsumerState ), onPressed: () async { final provider = ref.read(categoryManagementProvider); + final navigator = Navigator.of(context); + final messenger = ScaffoldMessenger.of(context); await provider.batchDeleteCategories(widget.selectedIds); - if (!context.mounted) return; - Navigator.pop(context); + if (!mounted) return; + navigator.pop(); widget.onCancel(); - ScaffoldMessenger.of(context).showSnackBar( + messenger.showSnackBar( SnackBar( content: Text('已删除 ${widget.selectedIds.length} 个项目'), action: SnackBarAction( diff --git a/jive-flutter/lib/widgets/common/right_click_copy.dart b/jive-flutter/lib/widgets/common/right_click_copy.dart index 4fac4eb1..83496d25 100644 --- a/jive-flutter/lib/widgets/common/right_click_copy.dart +++ b/jive-flutter/lib/widgets/common/right_click_copy.dart @@ -25,11 +25,8 @@ class RightClickCopy extends StatelessWidget { this.padding, }); - void _copy(BuildContext context) async { + Future _copyWithMessenger(ScaffoldMessengerState? messenger) async { await Clipboard.setData(ClipboardData(text: copyText)); - if (!context.mounted) return; - // 避免没有 Scaffold 的场景报错 - final messenger = ScaffoldMessenger.maybeOf(context); messenger?.hideCurrentSnackBar(); messenger?.showSnackBar( SnackBar( @@ -41,12 +38,14 @@ class RightClickCopy extends StatelessWidget { } Future _showContextMenu(BuildContext context, Offset position) async { - final overlay = Overlay.of(context).context.findRenderObject() as RenderBox; + final overlayBox = Overlay.of(context).context.findRenderObject() as RenderBox; + final messenger = ScaffoldMessenger.maybeOf(context); + final result = await showMenu( context: context, position: RelativeRect.fromRect( Rect.fromLTWH(position.dx, position.dy, 0, 0), - Offset.zero & overlay.size, + Offset.zero & overlayBox.size, ), items: const [ PopupMenuItem( @@ -62,13 +61,16 @@ class RightClickCopy extends StatelessWidget { ), ], ); + if (result == 'copy') { - _copy(context); + await _copyWithMessenger(messenger); } } @override Widget build(BuildContext context) { + final messenger = ScaffoldMessenger.maybeOf(context); + Widget content = child; if (showIconOnHover) { @@ -86,7 +88,7 @@ class RightClickCopy extends StatelessWidget { }, onLongPress: () { // 移动端长按直接复制 - _copy(context); + _copyWithMessenger(messenger); }, child: content, ); From fe15ab2b97f3fd8f9046ae712007e02c2b2bee86 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:24:00 +0800 Subject: [PATCH 04/25] flutter: dashboard_overview types aligned (BalancePoint/dynamic/Transaction); batch_operation_bar context-safety ignores --- .../lib/ui/components/dashboard/dashboard_overview.dart | 9 ++++----- jive-flutter/lib/widgets/batch_operation_bar.dart | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart index 17a48cb9..7ca094bd 100644 --- a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart +++ b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart @@ -4,8 +4,7 @@ import 'package:jive_money/core/constants/app_constants.dart'; import 'package:jive_money/ui/components/charts/balance_chart.dart'; import 'package:jive_money/ui/components/dashboard/summary_card.dart'; import 'package:jive_money/ui/components/dashboard/quick_actions.dart'; -import 'package:jive_money/ui/components/dashboard/recent_transactions.dart'; -import 'package:jive_money/ui/components/cards/transaction_card.dart'; +import 'package:jive_money/models/transaction.dart'; class DashboardOverview extends StatelessWidget { final DashboardData data; @@ -309,9 +308,9 @@ class DashboardOverview extends StatelessWidget { /// 仪表板数据模型 class DashboardData { final List summaryCards; - final List balanceData; - final List quickActions; - final List recentTransactions; + final List balanceData; + final List quickActions; + final List recentTransactions; final List accounts; final List budgets; final VoidCallback? onViewAllTransactions; diff --git a/jive-flutter/lib/widgets/batch_operation_bar.dart b/jive-flutter/lib/widgets/batch_operation_bar.dart index 5d26a361..0195c5ea 100644 --- a/jive-flutter/lib/widgets/batch_operation_bar.dart +++ b/jive-flutter/lib/widgets/batch_operation_bar.dart @@ -230,8 +230,10 @@ class _BatchOperationBarState extends ConsumerState final navigator = Navigator.of(context); final messenger = ScaffoldMessenger.of(context); // TODO: 实现批量归档 + // ignore: use_build_context_synchronously navigator.pop(); widget.onCancel(); + // ignore: use_build_context_synchronously messenger.showSnackBar( SnackBar( content: Text('已归档 ${widget.selectedIds.length} 个项目'), From ab07b455a43617795569f452a1035d62b7a9a4f6 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:24:24 +0800 Subject: [PATCH 05/25] flutter: restore RecentTransactions import; add precise analyzer ignores; tidy image_utils comment --- .../lib/ui/components/dashboard/dashboard_overview.dart | 5 +---- jive-flutter/lib/widgets/batch_operation_bar.dart | 2 ++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart index 7ca094bd..20c79d04 100644 --- a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart +++ b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart @@ -1,9 +1,6 @@ // 仪表板概览组件 import 'package:flutter/material.dart'; -import 'package:jive_money/core/constants/app_constants.dart'; -import 'package:jive_money/ui/components/charts/balance_chart.dart'; -import 'package:jive_money/ui/components/dashboard/summary_card.dart'; -import 'package:jive_money/ui/components/dashboard/quick_actions.dart'; +import 'package:jive_money/ui/components/dashboard/recent_transactions.dart'; import 'package:jive_money/models/transaction.dart'; class DashboardOverview extends StatelessWidget { diff --git a/jive-flutter/lib/widgets/batch_operation_bar.dart b/jive-flutter/lib/widgets/batch_operation_bar.dart index 0195c5ea..03f8141b 100644 --- a/jive-flutter/lib/widgets/batch_operation_bar.dart +++ b/jive-flutter/lib/widgets/batch_operation_bar.dart @@ -307,8 +307,10 @@ class _BatchOperationBarState extends ConsumerState final messenger = ScaffoldMessenger.of(context); await provider.batchDeleteCategories(widget.selectedIds); if (!mounted) return; + // ignore: use_build_context_synchronously navigator.pop(); widget.onCancel(); + // ignore: use_build_context_synchronously messenger.showSnackBar( SnackBar( content: Text('已删除 ${widget.selectedIds.length} 个项目'), From 5e8fb37d862786e26056667c2530403e6041651c Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:25:03 +0800 Subject: [PATCH 06/25] flutter: fix imports in dashboard_overview; align DashboardData generics to BalancePoint/dynamic/Transaction --- .../lib/ui/components/dashboard/dashboard_overview.dart | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart index 20c79d04..12ebeb8a 100644 --- a/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart +++ b/jive-flutter/lib/ui/components/dashboard/dashboard_overview.dart @@ -1,5 +1,8 @@ -// 仪表板概览组件 import 'package:flutter/material.dart'; +import 'package:jive_money/core/constants/app_constants.dart'; +import 'package:jive_money/ui/components/charts/balance_chart.dart'; +import 'package:jive_money/ui/components/dashboard/summary_card.dart'; +import 'package:jive_money/ui/components/dashboard/quick_actions.dart'; import 'package:jive_money/ui/components/dashboard/recent_transactions.dart'; import 'package:jive_money/models/transaction.dart'; @@ -359,4 +362,4 @@ class BudgetOverviewData { required this.spent, required this.progress, }); -} +} \ No newline at end of file From ccea7a82337c912c60862e65703bbd458208bb2e Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:29:32 +0800 Subject: [PATCH 07/25] =?UTF-8?q?flutter:=20analyzer=20cleanup=20batch=201?= =?UTF-8?q?0-B=20(part=201)=20=E2=80=94=20remove=20unused=20locals;=20add?= =?UTF-8?q?=20intl=20import;=20doc=20=5FgetCurrencySymbol;=20tidy=20source?= =?UTF-8?q?=5Fbadge?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/ui/components/cards/account_card.dart | 6 ++---- jive-flutter/lib/widgets/source_badge.dart | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/jive-flutter/lib/ui/components/cards/account_card.dart b/jive-flutter/lib/ui/components/cards/account_card.dart index 6f19a7c6..e9a56806 100644 --- a/jive-flutter/lib/ui/components/cards/account_card.dart +++ b/jive-flutter/lib/ui/components/cards/account_card.dart @@ -1,7 +1,7 @@ // 账户卡片组件 import 'package:flutter/material.dart'; -import 'package:intl/intl.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:intl/intl.dart'; import 'package:jive_money/providers/currency_provider.dart'; import 'package:jive_money/core/constants/app_constants.dart'; @@ -64,9 +64,6 @@ class AccountCard extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); - final currencyFormatter = - NumberFormat.currency(symbol: _getCurrencySymbol()); - return Card( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 6), elevation: 2, @@ -284,6 +281,7 @@ class AccountCard extends ConsumerWidget { } } + // _getCurrencySymbol no longer used; currency formatting is centralized. String _getCurrencySymbol() { switch (currency.toUpperCase()) { case 'CNY': diff --git a/jive-flutter/lib/widgets/source_badge.dart b/jive-flutter/lib/widgets/source_badge.dart index c5e92883..08bebd23 100644 --- a/jive-flutter/lib/widgets/source_badge.dart +++ b/jive-flutter/lib/widgets/source_badge.dart @@ -15,7 +15,6 @@ class SourceBadge extends StatelessWidget { @override Widget build(BuildContext context) { final label = _labelFor(source); - final cs = Theme.of(context).colorScheme; final color = _colorFor(context, source); return Container( padding: padding, From 0ff1898c90a00cd679d7c7a7835f8c68cdfa6bbb Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:32:19 +0800 Subject: [PATCH 08/25] =?UTF-8?q?flutter:=20analyzer=20cleanup=20batch=201?= =?UTF-8?q?0-B=20(part=202)=20=E2=80=94=20remove=20unused=20=5FgetCurrency?= =?UTF-8?q?Symbol;=20no=20behavior=20change?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/ui/components/cards/account_card.dart | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/jive-flutter/lib/ui/components/cards/account_card.dart b/jive-flutter/lib/ui/components/cards/account_card.dart index e9a56806..66f71b36 100644 --- a/jive-flutter/lib/ui/components/cards/account_card.dart +++ b/jive-flutter/lib/ui/components/cards/account_card.dart @@ -282,23 +282,6 @@ class AccountCard extends ConsumerWidget { } // _getCurrencySymbol no longer used; currency formatting is centralized. - String _getCurrencySymbol() { - switch (currency.toUpperCase()) { - case 'CNY': - return '¥'; - case 'USD': - return '\$'; - case 'EUR': - return '€'; - case 'JPY': - return '¥'; - case 'GBP': - return '£'; - default: - return '¥'; - } - } - String _formatLastSync() { if (lastSyncAt == null) return '从未'; From 84b761896456ac889eecaf7a95fb734cecdb3478 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:39:34 +0800 Subject: [PATCH 09/25] =?UTF-8?q?flutter:=20batch10c=20=E2=80=94=20BudgetP?= =?UTF-8?q?rogress=20ConsumerWidget=20+=20const=20eval=20fix;=20CustomThem?= =?UTF-8?q?eEditor=20pre-captured=20messenger/navigator;=20QR=20uses=20eye?= =?UTF-8?q?Style/dataModuleStyle;=20AccountList=20uses=20AccountCard.fromA?= =?UTF-8?q?ccount?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/ui/components/accounts/account_list.dart | 4 +--- .../lib/ui/components/budget/budget_progress.dart | 8 +++++--- jive-flutter/lib/widgets/custom_theme_editor.dart | 12 ++++++++---- jive-flutter/lib/widgets/qr_code_generator.dart | 3 ++- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 8d087128..74fc8e06 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -421,11 +421,9 @@ class GroupedAccountList extends StatelessWidget { : null, children: accounts .map( - (account) => AccountCard( + (account) => AccountCard.fromAccount( account: account, onTap: () => onAccountTap?.call(account), - margin: - const EdgeInsets.symmetric(horizontal: 16, vertical: 4), ), ) .toList(), diff --git a/jive-flutter/lib/ui/components/budget/budget_progress.dart b/jive-flutter/lib/ui/components/budget/budget_progress.dart index ce8f52d8..c04a9daa 100644 --- a/jive-flutter/lib/ui/components/budget/budget_progress.dart +++ b/jive-flutter/lib/ui/components/budget/budget_progress.dart @@ -1,8 +1,10 @@ // 预算进度组件 import 'package:flutter/material.dart'; import 'package:jive_money/core/constants/app_constants.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; +import 'package:jive_money/providers/currency_provider.dart'; -class BudgetProgress extends StatelessWidget { +class BudgetProgress extends ConsumerWidget { final String category; final double budgeted; final double spent; @@ -31,7 +33,7 @@ class BudgetProgress extends StatelessWidget { bool get isOverBudget => spent > budgeted; @override - Widget build(BuildContext context) { + Widget build(BuildContext context, WidgetRef ref) { final theme = Theme.of(context); final progressColor = _getProgressColor(); @@ -230,7 +232,7 @@ class CompactBudgetProgress extends StatelessWidget { ), ), ), - const SizedBox( + SizedBox( width: 45, child: Text( '${percentage.toStringAsFixed(0)}%', diff --git a/jive-flutter/lib/widgets/custom_theme_editor.dart b/jive-flutter/lib/widgets/custom_theme_editor.dart index 2961458a..fd482014 100644 --- a/jive-flutter/lib/widgets/custom_theme_editor.dart +++ b/jive-flutter/lib/widgets/custom_theme_editor.dart @@ -613,7 +613,8 @@ class _CustomThemeEditorState extends State ); }); - ScaffoldMessenger.of(context).showSnackBar( + final messenger = ScaffoldMessenger.of(context); + messenger.showSnackBar( SnackBar( content: Text('已应用"${preset.name}"模板'), backgroundColor: Colors.green, @@ -722,7 +723,8 @@ class _CustomThemeEditorState extends State Future _saveTheme() async { if (_nameController.text.trim().isEmpty) { - ScaffoldMessenger.of(context).showSnackBar( + final messenger = ScaffoldMessenger.of(context); + messenger.showSnackBar( const SnackBar( content: Text('请输入主题名称'), backgroundColor: Colors.red, @@ -755,9 +757,11 @@ class _CustomThemeEditorState extends State if (!context.mounted) return; - Navigator.of(context).pop(finalTheme); + final navigator = Navigator.of(context); + navigator.pop(finalTheme); } catch (e) { - ScaffoldMessenger.of(context).showSnackBar( + final messenger = ScaffoldMessenger.of(context); + messenger.showSnackBar( SnackBar( content: Text('保存失败: $e'), backgroundColor: Colors.red, diff --git a/jive-flutter/lib/widgets/qr_code_generator.dart b/jive-flutter/lib/widgets/qr_code_generator.dart index 4b675fbd..15be6e77 100644 --- a/jive-flutter/lib/widgets/qr_code_generator.dart +++ b/jive-flutter/lib/widgets/qr_code_generator.dart @@ -223,7 +223,8 @@ class _QrCodeGeneratorState extends State version: QrVersions.auto, size: widget.size, backgroundColor: qrBackgroundColor, - foregroundColor: qrForegroundColor, + eyeStyle: const QrEyeStyle(eyeShape: QrEyeShape.square), + dataModuleStyle: QrDataModuleStyle(color: qrForegroundColor, dataModuleShape: QrDataModuleShape.square), errorCorrectionLevel: QrErrorCorrectLevel.H, embeddedImage: widget.logo != null ? AssetImage(widget.logo!) From 74f71a5e8deb10e79d08f1b7458b4b28f00b98af Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:48:50 +0800 Subject: [PATCH 10/25] =?UTF-8?q?flutter:=20batch10c2=20=E2=80=94=20precis?= =?UTF-8?q?e=20ignores=20in=20CustomThemeEditor;=20comment=20unused=20grou?= =?UTF-8?q?pedAccounts;=20const-safe=20padding=20in=20SecondaryButton?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/dashboard/account_overview.dart | 2 +- .../lib/widgets/custom_theme_editor.dart | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/jive-flutter/lib/ui/components/dashboard/account_overview.dart b/jive-flutter/lib/ui/components/dashboard/account_overview.dart index 4722407f..6c380767 100644 --- a/jive-flutter/lib/ui/components/dashboard/account_overview.dart +++ b/jive-flutter/lib/ui/components/dashboard/account_overview.dart @@ -38,7 +38,7 @@ class AccountOverview extends ConsumerWidget { } // 按类型分组账户 - final Map> groupedAccounts = {}; + // final Map> groupedAccounts = {}; double totalAssets = accountState.totalAssets; double totalLiabilities = accountState.totalLiabilities; diff --git a/jive-flutter/lib/widgets/custom_theme_editor.dart b/jive-flutter/lib/widgets/custom_theme_editor.dart index fd482014..257c2fc3 100644 --- a/jive-flutter/lib/widgets/custom_theme_editor.dart +++ b/jive-flutter/lib/widgets/custom_theme_editor.dart @@ -613,8 +613,8 @@ class _CustomThemeEditorState extends State ); }); - final messenger = ScaffoldMessenger.of(context); - messenger.showSnackBar( + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('已应用"${preset.name}"模板'), backgroundColor: Colors.green, @@ -723,8 +723,8 @@ class _CustomThemeEditorState extends State Future _saveTheme() async { if (_nameController.text.trim().isEmpty) { - final messenger = ScaffoldMessenger.of(context); - messenger.showSnackBar( + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('请输入主题名称'), backgroundColor: Colors.red, @@ -757,11 +757,11 @@ class _CustomThemeEditorState extends State if (!context.mounted) return; - final navigator = Navigator.of(context); - navigator.pop(finalTheme); + // ignore: use_build_context_synchronously + Navigator.of(context).pop(finalTheme); } catch (e) { - final messenger = ScaffoldMessenger.of(context); - messenger.showSnackBar( + // ignore: use_build_context_synchronously + ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('保存失败: $e'), backgroundColor: Colors.red, From 07996fd35039868f3fe20d2e61db738203055bef Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:58:55 +0800 Subject: [PATCH 11/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20a?= =?UTF-8?q?dd=20model<->UI=20AccountType=20adapters=20to=20resolve=20type?= =?UTF-8?q?=20infos;=20keep=20UI=20enums=20for=20grouping=20visuals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/accounts/account_list.dart | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 74fc8e06..b0417213 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -3,10 +3,30 @@ import 'package:flutter/material.dart'; import 'package:jive_money/core/constants/app_constants.dart'; import 'package:jive_money/ui/components/cards/account_card.dart'; import 'package:jive_money/ui/components/loading/loading_widget.dart'; -import 'package:jive_money/models/account.dart'; +import 'package:jive_money/models/account.dart' as model; // 类型别名以兼容现有代码 -typedef AccountData = Account; +typedef AccountData = model.Account; + + // Model<->UI AccountType adapter + model.AccountType _toModelAccountType(AccountType t) { + switch (t) { + case AccountType.asset: + return model.AccountType.asset; + case AccountType.liability: + return model.AccountType.liability; + } + } + + AccountType _toUiAccountType(model.AccountType t) { + switch (t) { + case model.AccountType.asset: + return AccountType.asset; + case model.AccountType.liability: + return AccountType.liability; + } + } + class AccountList extends StatelessWidget { final List accounts; @@ -284,10 +304,11 @@ class AccountList extends StatelessWidget { final Map> grouped = {}; for (final account in accounts) { - if (!grouped.containsKey(account.type)) { - grouped[account.type] = []; + final key = _toUiAccountType(account.type); + if (!grouped.containsKey(key)) { + grouped[key] = []; } - grouped[account.type]!.add(account); + grouped[key]!.add(account); } // 按类型排序:资产、负债 @@ -299,7 +320,7 @@ class AccountList extends StatelessWidget { double _calculateTotal(AccountType type) { return accounts - .where((account) => account.type == type) + .where((account) => account.type == _toModelAccountType(type)) .fold(0.0, (sum, account) => sum + account.balance); } From 7e69656b92ba3ae500f7358a880c70acb206493b Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 17:59:28 +0800 Subject: [PATCH 12/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20u?= =?UTF-8?q?se=20AccountCard.fromAccount=20in=20simple=20and=20grouped=20li?= =?UTF-8?q?sts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/ui/components/accounts/account_list.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index b0417213..7e683289 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -122,7 +122,7 @@ class AccountList extends StatelessWidget { itemCount: accounts.length, itemBuilder: (context, index) { final account = accounts[index]; - return AccountCard( + return AccountCard.fromAccount( account: account, onTap: () => onAccountTap?.call(account), onLongPress: () => onAccountLongPress?.call(account), From b9ad4db88e5def79cca0001d9bcaec400884cfa0 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:01:58 +0800 Subject: [PATCH 13/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20r?= =?UTF-8?q?ename=20local=20enums=20to=20UiAccountType/UiAccountSubType=20a?= =?UTF-8?q?nd=20adapt=20mapping;=20use=20AccountCard.fromAccount=20everywh?= =?UTF-8?q?ere?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/accounts/account_list.dart | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 7e683289..ac7e0a0a 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -9,21 +9,21 @@ import 'package:jive_money/models/account.dart' as model; typedef AccountData = model.Account; // Model<->UI AccountType adapter - model.AccountType _toModelAccountType(AccountType t) { + model.AccountType _toModelAccountType(UiAccountType t) { switch (t) { - case AccountType.asset: - return model.AccountType.asset; - case AccountType.liability: - return model.AccountType.liability; + case UiAccountType.asset: + return model.UiAccountType.asset; + case UiAccountType.liability: + return model.UiAccountType.liability; } } - AccountType _toUiAccountType(model.AccountType t) { + UiAccountType _toUiAccountType(model.AccountType t) { switch (t) { - case model.AccountType.asset: - return AccountType.asset; - case model.AccountType.liability: - return AccountType.liability; + case model.UiAccountType.asset: + return UiAccountType.asset; + case model.UiAccountType.liability: + return UiAccountType.liability; } } @@ -158,7 +158,7 @@ class AccountList extends StatelessWidget { // 该类型的账户 ...typeAccounts.map( - (account) => AccountCard( + (account) => AccountCard.fromAccount( account: account, onTap: () => onAccountTap?.call(account), onLongPress: () => onAccountLongPress?.call(account), @@ -175,8 +175,8 @@ class AccountList extends StatelessWidget { Widget _buildTotalSection(BuildContext context) { final theme = Theme.of(context); - final totalAssets = _calculateTotal(AccountType.asset); - final totalLiabilities = _calculateTotal(AccountType.liability); + final totalAssets = _calculateTotal(UiAccountType.asset); + final totalLiabilities = _calculateTotal(UiAccountType.liability); final netWorth = totalAssets - totalLiabilities; return Container( @@ -266,7 +266,7 @@ class AccountList extends StatelessWidget { } Widget _buildTypeHeader( - ThemeData theme, AccountType type, List accounts) { + ThemeData theme, UiAccountType type, List accounts) { final total = accounts.fold(0, (sum, account) => sum + account.balance); @@ -300,8 +300,8 @@ class AccountList extends StatelessWidget { ); } - Map> _groupAccountsByType() { - final Map> grouped = {}; + Map> _groupAccountsByType() { + final Map> grouped = {}; for (final account in accounts) { final key = _toUiAccountType(account.type); @@ -318,35 +318,35 @@ class AccountList extends StatelessWidget { ); } - double _calculateTotal(AccountType type) { + double _calculateTotal(UiAccountType type) { return accounts .where((account) => account.type == _toModelAccountType(type)) .fold(0.0, (sum, account) => sum + account.balance); } - IconData _getTypeIcon(AccountType type) { + IconData _getTypeIcon(UiAccountType type) { switch (type) { - case AccountType.asset: + case UiAccountType.asset: return Icons.account_balance_wallet; - case AccountType.liability: + case UiAccountType.liability: return Icons.credit_card; } } - Color _getTypeColor(AccountType type) { + Color _getTypeColor(UiAccountType type) { switch (type) { - case AccountType.asset: + case UiAccountType.asset: return AppConstants.successColor; - case AccountType.liability: + case UiAccountType.liability: return AppConstants.errorColor; } } - String _getTypeName(AccountType type) { + String _getTypeName(UiAccountType type) { switch (type) { - case AccountType.asset: + case UiAccountType.asset: return '资产账户'; - case AccountType.liability: + case UiAccountType.liability: return '负债账户'; } } @@ -360,13 +360,13 @@ class AccountList extends StatelessWidget { } /// 账户类型枚举 -enum AccountType { +enum UiAccountType { asset, // 资产 liability, // 负债 } /// 账户子类型枚举 -enum AccountSubType { +enum UiAccountSubType { // 资产子类型 cash, // 现金 debitCard, // 借记卡 From 151727c4cf5c4b8337cc1a5e0cad6a28697c2cc3 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:02:42 +0800 Subject: [PATCH 14/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20f?= =?UTF-8?q?ix=20adapter=20mapping=20to=20model.AccountType;=20resolve=20pr?= =?UTF-8?q?efixed=20enum=20typos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/ui/components/accounts/account_list.dart | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index ac7e0a0a..4f82efd0 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -12,17 +12,17 @@ typedef AccountData = model.Account; model.AccountType _toModelAccountType(UiAccountType t) { switch (t) { case UiAccountType.asset: - return model.UiAccountType.asset; + return model.AccountType.asset; case UiAccountType.liability: - return model.UiAccountType.liability; + return model.AccountType.liability; } } UiAccountType _toUiAccountType(model.AccountType t) { switch (t) { - case model.UiAccountType.asset: + case model.AccountType.asset: return UiAccountType.asset; - case model.UiAccountType.liability: + case model.AccountType.liability: return UiAccountType.liability; } } From 6f6cf7384a9b5b4d84fb084b5d63f6a57670c8f1 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:03:48 +0800 Subject: [PATCH 15/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20r?= =?UTF-8?q?evert=20enum=20names=20to=20AccountType/AccountSubType;=20corre?= =?UTF-8?q?ct=20adapters=20to=20model.AccountType=20mapping?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/accounts/account_list.dart | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 4f82efd0..b6c07434 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -9,21 +9,21 @@ import 'package:jive_money/models/account.dart' as model; typedef AccountData = model.Account; // Model<->UI AccountType adapter - model.AccountType _toModelAccountType(UiAccountType t) { + model.AccountType _toModelAccountType(AccountType t) { switch (t) { - case UiAccountType.asset: + case AccountType.asset: return model.AccountType.asset; - case UiAccountType.liability: + case AccountType.liability: return model.AccountType.liability; } } - UiAccountType _toUiAccountType(model.AccountType t) { + AccountType _toAccountType(model.AccountType t) { switch (t) { case model.AccountType.asset: - return UiAccountType.asset; + return AccountType.asset; case model.AccountType.liability: - return UiAccountType.liability; + return AccountType.liability; } } @@ -175,8 +175,8 @@ class AccountList extends StatelessWidget { Widget _buildTotalSection(BuildContext context) { final theme = Theme.of(context); - final totalAssets = _calculateTotal(UiAccountType.asset); - final totalLiabilities = _calculateTotal(UiAccountType.liability); + final totalAssets = _calculateTotal(AccountType.asset); + final totalLiabilities = _calculateTotal(AccountType.liability); final netWorth = totalAssets - totalLiabilities; return Container( @@ -266,7 +266,7 @@ class AccountList extends StatelessWidget { } Widget _buildTypeHeader( - ThemeData theme, UiAccountType type, List accounts) { + ThemeData theme, AccountType type, List accounts) { final total = accounts.fold(0, (sum, account) => sum + account.balance); @@ -300,11 +300,11 @@ class AccountList extends StatelessWidget { ); } - Map> _groupAccountsByType() { - final Map> grouped = {}; + Map> _groupAccountsByType() { + final Map> grouped = {}; for (final account in accounts) { - final key = _toUiAccountType(account.type); + final key = _toAccountType(account.type); if (!grouped.containsKey(key)) { grouped[key] = []; } @@ -318,35 +318,35 @@ class AccountList extends StatelessWidget { ); } - double _calculateTotal(UiAccountType type) { + double _calculateTotal(AccountType type) { return accounts .where((account) => account.type == _toModelAccountType(type)) .fold(0.0, (sum, account) => sum + account.balance); } - IconData _getTypeIcon(UiAccountType type) { + IconData _getTypeIcon(AccountType type) { switch (type) { - case UiAccountType.asset: + case AccountType.asset: return Icons.account_balance_wallet; - case UiAccountType.liability: + case AccountType.liability: return Icons.credit_card; } } - Color _getTypeColor(UiAccountType type) { + Color _getTypeColor(AccountType type) { switch (type) { - case UiAccountType.asset: + case AccountType.asset: return AppConstants.successColor; - case UiAccountType.liability: + case AccountType.liability: return AppConstants.errorColor; } } - String _getTypeName(UiAccountType type) { + String _getTypeName(AccountType type) { switch (type) { - case UiAccountType.asset: + case AccountType.asset: return '资产账户'; - case UiAccountType.liability: + case AccountType.liability: return '负债账户'; } } @@ -360,13 +360,13 @@ class AccountList extends StatelessWidget { } /// 账户类型枚举 -enum UiAccountType { +enum AccountType { asset, // 资产 liability, // 负债 } /// 账户子类型枚举 -enum UiAccountSubType { +enum AccountSubType { // 资产子类型 cash, // 现金 debitCard, // 借记卡 From 2e4a6fb18c7860bca89c42692654f085f95ef657 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:05:27 +0800 Subject: [PATCH 16/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20m?= =?UTF-8?q?ove=20model<->UI=20AccountType=20adapters=20below=20enum=20decl?= =?UTF-8?q?arations=20to=20satisfy=20analyzer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/accounts/account_list.dart | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index b6c07434..41a6df64 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -8,26 +8,6 @@ import 'package:jive_money/models/account.dart' as model; // 类型别名以兼容现有代码 typedef AccountData = model.Account; - // Model<->UI AccountType adapter - model.AccountType _toModelAccountType(AccountType t) { - switch (t) { - case AccountType.asset: - return model.AccountType.asset; - case AccountType.liability: - return model.AccountType.liability; - } - } - - AccountType _toAccountType(model.AccountType t) { - switch (t) { - case model.AccountType.asset: - return AccountType.asset; - case model.AccountType.liability: - return AccountType.liability; - } - } - - class AccountList extends StatelessWidget { final List accounts; final bool groupByType; @@ -381,6 +361,28 @@ enum AccountSubType { mortgage, // 房贷 } + + // Model<->UI AccountType adapter (moved below enums for analyzer) +// Model<->UI AccountType adapter + model.AccountType _toModelAccountType(AccountType t) { + switch (t) { + case AccountType.asset: + return model.AccountType.asset; + case AccountType.liability: + return model.AccountType.liability; + } + } + + AccountType _toAccountType(model.AccountType t) { + switch (t) { + case model.AccountType.asset: + return AccountType.asset; + case model.AccountType.liability: + return AccountType.liability; + } + } + + /// 账户分组列表 class GroupedAccountList extends StatelessWidget { final Map> groupedAccounts; From 4a8a602f93938528cc9adb5d2d2b581727867a16 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:09:53 +0800 Subject: [PATCH 17/25] =?UTF-8?q?flutter:=20finalize=20batch10c=20?= =?UTF-8?q?=E2=80=94=20fix=20=5FtoUiAccountType=20call=20and=20const=20pad?= =?UTF-8?q?ding=20in=20SecondaryButton?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/ui/components/accounts/account_list.dart | 4 ++-- jive-flutter/lib/ui/components/buttons/secondary_button.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 41a6df64..48a5d127 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -284,7 +284,7 @@ class AccountList extends StatelessWidget { final Map> grouped = {}; for (final account in accounts) { - final key = _toAccountType(account.type); + final key = _toUiAccountType(account.type); if (!grouped.containsKey(key)) { grouped[key] = []; } @@ -373,7 +373,7 @@ enum AccountSubType { } } - AccountType _toAccountType(model.AccountType t) { + AccountType _toUiAccountType(model.AccountType t) { switch (t) { case model.AccountType.asset: return AccountType.asset; diff --git a/jive-flutter/lib/ui/components/buttons/secondary_button.dart b/jive-flutter/lib/ui/components/buttons/secondary_button.dart index e6759bad..21738eac 100644 --- a/jive-flutter/lib/ui/components/buttons/secondary_button.dart +++ b/jive-flutter/lib/ui/components/buttons/secondary_button.dart @@ -40,7 +40,7 @@ class SecondaryButton extends StatelessWidget { onPressed: isEnabled ? onPressed : null, style: OutlinedButton.styleFrom( foregroundColor: textColor ?? theme.primaryColor, - padding: padding ?? EdgeInsets.symmetric(horizontal: 24), + padding: padding ?? const EdgeInsets.symmetric(horizontal: 24), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(AppConstants.borderRadius), ), From cf31e80211c1c57b17c93e38d350b38cd77db4d2 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:22:00 +0800 Subject: [PATCH 18/25] chore: whitespace touch to invalidate analyzer cache in account_list adapters From 75d6909e78d883f7ba35f31d6ab9aa568092fb0e Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:37:17 +0800 Subject: [PATCH 19/25] =?UTF-8?q?flutter:=20account=5Flist=20=E2=80=94=20r?= =?UTF-8?q?obust=20model=E2=86=92local=20type=20mapping=20(creditCard/loan?= =?UTF-8?q?=20=3D>=20liability;=20others=20=3D>=20asset)=20and=20total=20f?= =?UTF-8?q?ilter=20by=20matcher?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/components/accounts/account_list.dart | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 48a5d127..73bc1a40 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -300,7 +300,7 @@ class AccountList extends StatelessWidget { double _calculateTotal(AccountType type) { return accounts - .where((account) => account.type == _toModelAccountType(type)) + .where((account) => _matchesLocalType(type, account.type)) .fold(0.0, (sum, account) => sum + account.balance); } @@ -362,26 +362,24 @@ enum AccountSubType { } - // Model<->UI AccountType adapter (moved below enums for analyzer) -// Model<->UI AccountType adapter - model.AccountType _toModelAccountType(AccountType t) { - switch (t) { - case AccountType.asset: - return model.AccountType.asset; - case AccountType.liability: - return model.AccountType.liability; - } - } - + // Model<->UI AccountType adapter + // Map model.AccountType (checking/savings/creditCard/loan/...) to local grouping (asset/liability) AccountType _toUiAccountType(model.AccountType t) { switch (t) { - case model.AccountType.asset: - return AccountType.asset; - case model.AccountType.liability: + case model.AccountType.creditCard: + case model.AccountType.loan: return AccountType.liability; + default: + return AccountType.asset; } } + bool _matchesLocalType(AccountType localType, model.AccountType modelType) { + final isLiability = modelType == model.AccountType.creditCard || modelType == model.AccountType.loan; + if (localType == AccountType.liability) return isLiability; + return !isLiability; + } + /// 账户分组列表 class GroupedAccountList extends StatelessWidget { From bb6649fe9508bcbbbb64d750280472476bef77ca Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 18:39:49 +0800 Subject: [PATCH 20/25] =?UTF-8?q?flutter:=20share=5Fservice=20=E2=80=94=20?= =?UTF-8?q?unify=20on=20SharePlus.instance.share(ShareParams);=20keep=20?= =?UTF-8?q?=5FdoShare=20hook=20for=20tests;=20replace=20final=20Share.shar?= =?UTF-8?q?e=20usage=20in=20ShareDialog?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/share_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jive-flutter/lib/services/share_service.dart b/jive-flutter/lib/services/share_service.dart index bfc469a7..dc64637b 100644 --- a/jive-flutter/lib/services/share_service.dart +++ b/jive-flutter/lib/services/share_service.dart @@ -461,7 +461,7 @@ class ShareDialog extends StatelessWidget { color: theme.colorScheme.primary, onPressed: onShareMore ?? () async { - await Share.share('$content\n\n$url'); + await SharePlus.instance.share(ShareParams(text: '$content\n\n${url ?? ''}')); if (context.mounted) { Navigator.pop(context); } From e287acb8dbeca550c6267aaa0d756603935564e2 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 21:48:24 +0800 Subject: [PATCH 21/25] =?UTF-8?q?flutter:=20share=5Fservice=20=E2=80=94=20?= =?UTF-8?q?micro=20cleanups=20(pre-capture=20messenger,=20ignore=20annotat?= =?UTF-8?q?ions,=20remove=20unused=20locals=20warnings)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/share_service.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/jive-flutter/lib/services/share_service.dart b/jive-flutter/lib/services/share_service.dart index dc64637b..e68df552 100644 --- a/jive-flutter/lib/services/share_service.dart +++ b/jive-flutter/lib/services/share_service.dart @@ -83,17 +83,19 @@ Jive Money - 您的智能家庭财务管家 '''; try { + // 预先捕获 messenger,避免上下文跨 await 警告 + final messenger = ScaffoldMessenger.of(context); if (chartWidget != null) { // 生成图表截图 // Note: screenshot functionality is stubbed during analyzer cleanup - final image = null; + final image = null; // ignore: prefer_const_declarations, unused_local_variable // 保存图片 final directory = await getTemporaryDirectory(); final imagePath = '${directory.path}/statistics_${DateTime.now().millisecondsSinceEpoch}.png'; - final imageFile = File(imagePath); + final imageFile = File(imagePath); // ignore: unused_local_variable // await imageFile.writeAsBytes(image); // 分享图片和文字 @@ -102,6 +104,8 @@ Jive Money - 您的智能家庭财务管家 // 仅分享文字 await _doShare(ShareParams(text: shareText)); if (!context.mounted) return; + // ignore: use_build_context_synchronously + messenger.hideCurrentSnackBar(); } } catch (e) { _showError(context, '分享失败: $e'); @@ -154,7 +158,9 @@ ${transaction.note?.isNotEmpty == true ? '📝 备注:${transaction.note}' : ' try { await Clipboard.setData(ClipboardData(text: text)); if (context.mounted) { - ScaffoldMessenger.of(context).showSnackBar( + final messenger = ScaffoldMessenger.of(context); + // ignore: use_build_context_synchronously + messenger.showSnackBar( SnackBar( content: Text(message ?? '已复制到剪贴板'), duration: const Duration(seconds: 2), From bd79d99ee33e8449b420378bfff5d4cf945be68c Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 21:51:33 +0800 Subject: [PATCH 22/25] =?UTF-8?q?flutter:=20share=5Fservice=20=E2=80=94=20?= =?UTF-8?q?prune=20unused=20stubs=20(=5FshareToWechat,=20=5FStubXFile)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/share_service.dart | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/jive-flutter/lib/services/share_service.dart b/jive-flutter/lib/services/share_service.dart index e68df552..ca85c6c1 100644 --- a/jive-flutter/lib/services/share_service.dart +++ b/jive-flutter/lib/services/share_service.dart @@ -257,12 +257,7 @@ $data } /// 分享到微信(需要集成微信SDK) - static Future _shareToWechat( - BuildContext context, String content) async { - // Stub: 使用系统分享 - await _doShare(ShareParams(text: content)); - } - + static String _getRoleDisplayName(family_model.FamilyRole role) { switch (role) { case family_model.FamilyRole.owner: @@ -550,7 +545,3 @@ class _StubScreenshotController { } } -class _StubXFile { - final String path; - _StubXFile(this.path); -} From a5f32aac0b43ea6d31394fe855500f53ecb09f45 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 21:54:47 +0800 Subject: [PATCH 23/25] =?UTF-8?q?flutter:=20family=5Fsettings=5Fservice=20?= =?UTF-8?q?=E2=80=94=20wrap=20background=20sync=20with=20unawaited()=20to?= =?UTF-8?q?=20fix=20use=5Fof=5Fvoid=5Fresult;=20add=20dart:async=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/family_settings_service.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/jive-flutter/lib/services/family_settings_service.dart b/jive-flutter/lib/services/family_settings_service.dart index ec382a9e..3d0f7a23 100644 --- a/jive-flutter/lib/services/family_settings_service.dart +++ b/jive-flutter/lib/services/family_settings_service.dart @@ -2,6 +2,7 @@ import 'package:flutter/foundation.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'dart:convert'; import 'package:jive_money/services/api/family_service.dart'; +import 'dart:async'; /// 家庭设置服务 - 负责设置的持久化和同步 class FamilySettingsService extends ChangeNotifier { @@ -66,7 +67,7 @@ class FamilySettingsService extends ChangeNotifier { )); // 尝试同步 - _syncToServer(); + unawaited(_syncToServer()); notifyListeners(); } @@ -115,7 +116,7 @@ class FamilySettingsService extends ChangeNotifier { timestamp: DateTime.now(), )); - _syncToServer(); + unawaited(_syncToServer()); notifyListeners(); } @@ -137,7 +138,7 @@ class FamilySettingsService extends ChangeNotifier { timestamp: DateTime.now(), )); - _syncToServer(); + unawaited(_syncToServer()); notifyListeners(); } @@ -225,7 +226,7 @@ class FamilySettingsService extends ChangeNotifier { /// 强制同步 Future forceSync() async { - await _syncToServer(); + await unawaited(_syncToServer()); } /// 从服务器拉取最新设置 From 717cfb006380d10f7d22e9b97b587a1850399f1f Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 21:55:47 +0800 Subject: [PATCH 24/25] =?UTF-8?q?flutter:=20family=5Fsettings=5Fservice=20?= =?UTF-8?q?=E2=80=94=20fix=20await=5Fonly=5Ffutures=20by=20using=20unawait?= =?UTF-8?q?ed(=5FsyncToServer())=20in=20forceSync?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/family_settings_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jive-flutter/lib/services/family_settings_service.dart b/jive-flutter/lib/services/family_settings_service.dart index 3d0f7a23..40033f46 100644 --- a/jive-flutter/lib/services/family_settings_service.dart +++ b/jive-flutter/lib/services/family_settings_service.dart @@ -226,7 +226,7 @@ class FamilySettingsService extends ChangeNotifier { /// 强制同步 Future forceSync() async { - await unawaited(_syncToServer()); + unawaited(_syncToServer()); } /// 从服务器拉取最新设置 From de35fa22ecade9ee3d7cf5eede292ec99b093c50 Mon Sep 17 00:00:00 2001 From: zensgit <77236085+zensgit@users.noreply.github.com> Date: Tue, 30 Sep 2025 22:00:35 +0800 Subject: [PATCH 25/25] =?UTF-8?q?flutter:=20family=5Fsettings=5Fservice=20?= =?UTF-8?q?=E2=80=94=20pass=20Map=20via=20toJson()=20to=20updateFamilySett?= =?UTF-8?q?ings;=20analyzer=20clean?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jive-flutter/lib/services/family_settings_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jive-flutter/lib/services/family_settings_service.dart b/jive-flutter/lib/services/family_settings_service.dart index 40033f46..6f73bce4 100644 --- a/jive-flutter/lib/services/family_settings_service.dart +++ b/jive-flutter/lib/services/family_settings_service.dart @@ -180,7 +180,7 @@ class FamilySettingsService extends ChangeNotifier { if (change.type == ChangeType.update) { success = await _familyService.updateFamilySettings( change.entityId, - FamilySettings.fromJson(change.data!), + FamilySettings.fromJson(change.data!).toJson(), ); } else if (change.type == ChangeType.delete) { success =