import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../../../core/localization/app_localizations.dart'; import '../../../core/localization/locale_provider.dart'; import '../../../core/theme/app_theme.dart'; import '../../../shared/widgets/common_button.dart'; import '../services/settings_service.dart'; /// 系统设置页面 class SettingsPage extends ConsumerStatefulWidget { const SettingsPage({super.key}); @override ConsumerState createState() => _SettingsPageState(); } class _SettingsPageState extends ConsumerState { String _currentVersion = 'V1.0.0'; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context); // locale 用于语言切换,通过 ref.watch 保持监听 return Scaffold( body: Container( color: AppTheme.backgroundColor, child: Row( children: [ // 左侧导航菜单 SizedBox( width: 280, child: Container( color: Colors.white, child: Column( children: [ // 返回按钮 Container( height: 50, padding: const EdgeInsets.symmetric(horizontal: 16), child: Row( children: [ IconButton( icon: const Icon(Icons.arrow_back), color: AppTheme.textPrimary, onPressed: () => context.go('/'), ), Text( '返回首页', style: TextStyle( color: AppTheme.textSecondary, fontSize: 14, ), ), ], ), ), // 设置标题 Container( height: 60, padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppTheme.primaryColor.withValues(alpha: 0.1), ), child: Row( children: [ Icon(Icons.settings, color: AppTheme.primaryColor, size: 24), const SizedBox(width: 12), Text( l10n?.settings ?? '系统设置', style: TextStyle( color: AppTheme.primaryColor, fontSize: 18, fontWeight: FontWeight.w600, ), ), ], ), ), // 软件升级 _buildMenuItem( icon: Icons.system_update, title: l10n?.upgrade ?? '软件升级', onTap: () {}, ), // 语言设置 _buildMenuItem( icon: Icons.language, title: l10n?.language ?? '语言设置', onTap: () => _showLanguageDialog(), ), // 安全设置 _buildMenuItem( icon: Icons.lock, title: l10n?.password ?? '密码修改', onTap: () => _showPasswordDialog(), ), // U盘导入 _buildMenuItem( icon: Icons.usb, title: l10n?.usbImport ?? 'U盘导入', onTap: () => _showUsbImportDialog(), ), ], ), ), ), // 右侧内容区域 Expanded( child: Container( margin: const EdgeInsets.all(16), padding: const EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( l10n?.upgrade ?? '软件升级', style: TextStyle( color: AppTheme.textPrimary, fontSize: 18, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 24), // 版本信息 Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: AppTheme.backgroundColor, borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Icon(Icons.info_outline, color: AppTheme.primaryColor), const SizedBox(width: 12), Text( '当前版本: $_currentVersion', style: TextStyle(color: AppTheme.textPrimary), ), ], ), ), const SizedBox(height: 24), // 检查更新按钮 CommonButton( text: '检查更新', icon: Icons.refresh, type: ButtonType.primary, onPressed: () { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('已是最新版本'), backgroundColor: AppTheme.successColor, ), ); }, ), ], ), ), ), ], ), ), ); } /// 导航菜单项 Widget _buildMenuItem({ required IconData icon, required String title, required VoidCallback onTap, }) { return ListTile( leading: Icon(icon, color: AppTheme.textSecondary), title: Text(title, style: TextStyle(color: AppTheme.textPrimary)), trailing: Icon(Icons.chevron_right, color: AppTheme.idleColor), onTap: onTap, ); } /// 显示语言选择对话框 void _showLanguageDialog() { final locale = ref.read(localeProvider); final currentLang = locale.languageCode; showDialog( context: context, builder: (ctx) => AlertDialog( title: Text('语言设置'), content: Column( mainAxisSize: MainAxisSize.min, children: [ RadioListTile( title: Text('简体中文'), value: 'zh', groupValue: currentLang, onChanged: (value) { ref.read(localeProvider.notifier).setChinese(); Navigator.of(ctx).pop(); }, ), RadioListTile( title: Text('English'), value: 'en', groupValue: currentLang, onChanged: (value) { ref.read(localeProvider.notifier).setEnglish(); Navigator.of(ctx).pop(); }, ), ], ), ), ); } /// 显示密码修改对话框 void _showPasswordDialog() { final oldPasswordController = TextEditingController(); final newPasswordController = TextEditingController(); final confirmPasswordController = TextEditingController(); String? errorMessage; showDialog( context: context, builder: (ctx) => StatefulBuilder( builder: (context, setState) => AlertDialog( title: Text('密码修改'), content: SizedBox( width: 300, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( controller: oldPasswordController, decoration: InputDecoration( labelText: '原密码', errorText: null, ), obscureText: true, ), const SizedBox(height: 12), TextField( controller: newPasswordController, decoration: InputDecoration( labelText: '新密码', helperText: '至少6位字符', ), obscureText: true, ), const SizedBox(height: 12), TextField( controller: confirmPasswordController, decoration: InputDecoration(labelText: '确认新密码'), obscureText: true, ), if (errorMessage != null) Padding( padding: const EdgeInsets.only(top: 12), child: Text( errorMessage!, style: TextStyle(color: AppTheme.errorColor, fontSize: 12), ), ), ], ), ), actions: [ TextButton( onPressed: () => Navigator.of(ctx).pop(), child: Text('取消'), ), ElevatedButton( onPressed: () async { // 验证逻辑 final oldPassword = oldPasswordController.text.trim(); final newPassword = newPasswordController.text.trim(); final confirmPassword = confirmPasswordController.text.trim(); // 检查空值 if (oldPassword.isEmpty || newPassword.isEmpty || confirmPassword.isEmpty) { setState(() => errorMessage = '请填写所有字段'); return; } // 检查新密码长度 if (newPassword.length < 6) { setState(() => errorMessage = '新密码至少6位字符'); return; } // 检查新密码一致性 if (newPassword != confirmPassword) { setState(() => errorMessage = '两次输入的新密码不一致'); return; } // 验证原密码 final isValid = await SettingsService.instance.verifyPassword(oldPassword); if (!isValid) { setState(() => errorMessage = '原密码错误'); return; } // 保存新密码 final success = await SettingsService.instance.setPassword(newPassword); Navigator.of(ctx).pop(); if (success) { ScaffoldMessenger.of(this.context).showSnackBar( SnackBar( content: Text('密码已修改'), backgroundColor: AppTheme.successColor, ), ); } else { ScaffoldMessenger.of(this.context).showSnackBar( SnackBar( content: Text('密码修改失败'), backgroundColor: AppTheme.errorColor, ), ); } }, child: Text('确认'), ), ], ), ), ); } /// 显示U盘导入对话框 void _showUsbImportDialog() { showDialog( context: context, builder: (context) => AlertDialog( title: Text('U盘导入'), content: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.usb, size: 48, color: AppTheme.warningColor), const SizedBox(height: 16), Text('未检测到U盘'), const SizedBox(height: 8), Text( '请插入U盘后重试', style: TextStyle(color: AppTheme.textSecondary, fontSize: 12), ), ], ), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text('关闭'), ), ElevatedButton( onPressed: () { Navigator.of(context).pop(); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('正在检测U盘...'), backgroundColor: AppTheme.primaryColor, ), ); }, child: Text('重新检测'), ), ], ), ); } }