diff --git a/jive-flutter/lib/services/share_service.dart b/jive-flutter/lib/services/share_service.dart index bfc469a7..ca85c6c1 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), @@ -251,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: @@ -461,7 +462,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); } @@ -544,7 +545,3 @@ class _StubScreenshotController { } } -class _StubXFile { - final String path; - _StubXFile(this.path); -} diff --git a/jive-flutter/lib/ui/components/accounts/account_list.dart b/jive-flutter/lib/ui/components/accounts/account_list.dart index 74fc8e06..73bc1a40 100644 --- a/jive-flutter/lib/ui/components/accounts/account_list.dart +++ b/jive-flutter/lib/ui/components/accounts/account_list.dart @@ -3,10 +3,10 @@ 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; class AccountList extends StatelessWidget { final List accounts; @@ -102,7 +102,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), @@ -138,7 +138,7 @@ class AccountList extends StatelessWidget { // 该类型的账户 ...typeAccounts.map( - (account) => AccountCard( + (account) => AccountCard.fromAccount( account: account, onTap: () => onAccountTap?.call(account), onLongPress: () => onAccountLongPress?.call(account), @@ -284,10 +284,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 +300,7 @@ class AccountList extends StatelessWidget { double _calculateTotal(AccountType type) { return accounts - .where((account) => account.type == type) + .where((account) => _matchesLocalType(type, account.type)) .fold(0.0, (sum, account) => sum + account.balance); } @@ -360,6 +361,26 @@ enum AccountSubType { mortgage, // 房贷 } + + // 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.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 { final Map> groupedAccounts; 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), ), 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,