import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:get_it/get_it.dart'; import 'package:go_router/go_router.dart'; import 'package:maibu_satabot_v2/core/localization/app_localizations.dart'; import 'package:maibu_satabot_v2/core/localization/locale_cubit.dart'; import 'package:maibu_satabot_v2/core/router/route_paths.dart'; import 'package:maibu_satabot_v2/core/theme/AppTheme.dart'; import 'package:maibu_satabot_v2/core/storage/user_storage.dart'; import 'package:maibu_satabot_v2/features/auth/presentation/bloc/auth_cubit.dart'; import 'package:maibu_satabot_v2/features/main_container/presentation/cubit/tab_config_cubit.dart'; import 'package:maibu_satabot_v2/features/main_container/domain/tab_config.dart'; import 'package:maibu_satabot_v2/core/app/app_user_cubit.dart'; import 'package:maibu_satabot_v2/features/v2/device_list/presentation/float_bar/cubit/float_bar_setting_cubit.dart'; import 'package:maibu_satabot_v2/core/update/update_cubit.dart'; import 'package:maibu_satabot_v2/core/update/update_state.dart'; /// 系统设置综合页面 class SystemSettingsPage extends StatefulWidget { const SystemSettingsPage({super.key}); @override State createState() => _SystemSettingsPageState(); } class _SystemSettingsPageState extends State { String _currentVersion = ''; int _currentVersionCode = 0; @override void initState() { super.initState(); _loadVersion(); } Future _loadVersion() async { try { final String versionString = await rootBundle.loadString('pubspec.yaml'); final versionMatch = RegExp(r'version:\s*(\d+\.\d+\.\d+)\+(\d+)').firstMatch(versionString); setState(() { _currentVersion = versionMatch?.group(1) ?? '1.0.0'; _currentVersionCode = int.tryParse(versionMatch?.group(2) ?? '1') ?? 1; }); } catch (_) {} } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: context.appColors.pageBackground, appBar: AppBar( elevation: 0, leading: IconButton( icon: Icon(Icons.arrow_back, color: context.appColors.textPrimary), onPressed: () => Navigator.pop(context), ), title: Text( AppLocalizations.of(context).translate('my.settings'), style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: context.appColors.textPrimary, ), ), centerTitle: true, ), body: ListView( padding: const EdgeInsets.all(16), children: [ // Tab 设置 _buildTabSettingsSection(), const SizedBox(height: 12), // 悬浮条设置 _buildFloatBarSection(), const SizedBox(height: 12), // 语言设置 _buildLanguageSection(), const SizedBox(height: 12), // 版本更新 _buildUpdateSection(), const SizedBox(height: 12), // 退出登录(已挪至“我的”页面最下边,此处注释掉) // _buildLogoutButton(context), // const SizedBox(height: 20), ], ), ); } /// 悬浮条设置 Widget _buildFloatBarSection() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: context.appColors.cardBackground, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: context.appColors.cardShadow, blurRadius: 8, offset: Offset(0, 2), ), ], ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppLocalizations.of(context).translate('my_v2.suspend_bar'), style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: context.appColors.textPrimary, ), ), const SizedBox(height: 4), Text( AppLocalizations.of( context, ).translate('my_v2.suspend_bar_desc'), style: TextStyle( fontSize: 13, color: context.appColors.textTertiary, ), ), ], ), ), ValueListenableBuilder( valueListenable: FloatBarSettingService.settingNotifier, builder: (context, isEnabled, child) { return Switch( value: isEnabled, onChanged: (value) { FloatBarSettingService.setEnabled(value); }, activeColor: const Color(0xFF165DFF), ); }, ), ], ), ); } /// Tab 设置 Widget _buildTabSettingsSection() { // 🔥 个人角色(roleKey == 'personal'):Tab 设置只列出「设备 + 我的」,且开关常开锁定 final roleKey = context.watch().state.user?.roleKey; final isPersonal = roleKey == TabConfig.personalRoleKey; return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: context.appColors.cardBackground, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: context.appColors.cardShadow, blurRadius: 8, offset: Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppLocalizations.of(context).translate('my_v2.tab_settings'), style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: context.appColors.textPrimary, ), ), const SizedBox(height: 16), BlocBuilder( builder: (context, state) { if (state.runtimeType.toString() != 'TabConfigLoaded') { return const Center(child: CircularProgressIndicator()); } final tabs = state.config.settingItemsForRole(roleKey); return ListView.builder( shrinkWrap: true, physics: const NeverScrollableScrollPhysics(), itemCount: tabs.length, itemBuilder: (context, index) { final tab = tabs[index]; return Padding( padding: const EdgeInsets.only(bottom: 12), child: Row( children: [ Expanded( child: Text( tab.name, style: TextStyle( fontSize: 14, color: context.appColors.textPrimary, ), ), ), Switch( // 个人角色:设备/我的 强制常开且不可关闭 value: isPersonal ? true : tab.isEnabled, onChanged: isPersonal ? null : (value) { context.read().toggleTab(tab.id); }, activeColor: const Color(0xFF165DFF), ), ], ), ); }, ); }, ), ], ), ); } /// 语言设置 Widget _buildLanguageSection() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: context.appColors.cardBackground, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: context.appColors.cardShadow, blurRadius: 8, offset: Offset(0, 2), ), ], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( AppLocalizations.of(context).translate('my.language'), style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: context.appColors.textPrimary, ), ), const SizedBox(height: 16), BlocBuilder( builder: (context, locale) { return Column( children: [ _buildLanguageOption( AppLocalizations.of(context).translate('my.chinese'), 'zh', locale.languageCode == 'zh', () => context.read().setLocale( const Locale('zh', 'CN'), ), ), const SizedBox(height: 12), _buildLanguageOption( AppLocalizations.of(context).translate('my.english'), 'en', locale.languageCode == 'en', () => context.read().setLocale( const Locale('en', 'US'), ), ), ], ); }, ), ], ), ); } Widget _buildLanguageOption( String label, String code, bool isSelected, VoidCallback onTap, ) { return GestureDetector( onTap: onTap, child: Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: isSelected ? const Color(0xFF165DFF).withOpacity(0.1) : Colors.transparent, borderRadius: BorderRadius.circular(8), border: Border.all( color: isSelected ? const Color(0xFF165DFF) : context.appColors.divider, width: 1, ), ), child: Row( children: [ Expanded( child: Text( label, style: TextStyle( fontSize: 14, color: isSelected ? const Color(0xFF165DFF) : context.appColors.textPrimary, fontWeight: isSelected ? FontWeight.w600 : FontWeight.normal, ), ), ), if (isSelected) const Icon( Icons.check_circle, color: Color(0xFF165DFF), size: 20, ), ], ), ), ); } /// 版本更新 Widget _buildUpdateSection() { return Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: context.appColors.cardBackground, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: context.appColors.cardShadow, blurRadius: 8, offset: Offset(0, 2), ), ], ), child: BlocConsumer( listener: (context, state) { if (state is UpdateUpToDate) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('当前已是最新版本'), backgroundColor: context.appColors.success, duration: const Duration(seconds: 2), ), ); } }, builder: (context, state) { final isChecking = state is UpdateChecking; return Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( '版本更新', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: context.appColors.textPrimary, ), ), const SizedBox(height: 4), Text( '当前版本: $_currentVersion ($_currentVersionCode)', style: TextStyle( fontSize: 13, color: context.appColors.textTertiary, ), ), const SizedBox(height: 2), Text( isChecking ? '正在检查更新...' : '点击检查是否有新版本', style: TextStyle( fontSize: 13, color: context.appColors.textTertiary, ), ), ], ), ), if (isChecking) const SizedBox( width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2), ) else GestureDetector( onTap: () { context.read().checkUpdate(); }, child: Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 8, ), decoration: BoxDecoration( color: const Color(0xFF165DFF), borderRadius: BorderRadius.circular(8), ), child: const Text( '检查更新', style: TextStyle( fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500, ), ), ), ), ], ); }, ), ); } /// 退出登录按钮(已挪至“我的”页面最下边,此处注释掉) // Widget _buildLogoutButton(BuildContext context) { // return GestureDetector( // onTap: () { // _showLogoutDialog(context); // }, // child: Container( // padding: const EdgeInsets.symmetric(vertical: 16), // decoration: BoxDecoration( // color: context.appColors.cardBackground, // borderRadius: BorderRadius.circular(12), // boxShadow: [ // BoxShadow( // color: context.appColors.cardShadow, // blurRadius: 8, // offset: Offset(0, 2), // ), // ], // ), // child: Center( // child: Text( // AppLocalizations.of(context).translate('login.logout'), // style: const TextStyle( // fontSize: 16, // fontWeight: FontWeight.w500, // color: Color(0xFFF53F3F), // ), // ), // ), // ), // ); // } /// 显示退出登录确认对话框(已挪至“我的”页面最下边,此处注释掉) // void _showLogoutDialog(BuildContext context) { // showDialog( // context: context, // builder: (context) => AlertDialog( // title: Text(AppLocalizations.of(context).translate('login.logout')), // content: Text( // AppLocalizations.of(context).translate('login.confirm_logout'), // ), // actions: [ // TextButton( // onPressed: () => Navigator.pop(context), // child: Text(AppLocalizations.of(context).translate('my_v2.cancel')), // ), // TextButton( // onPressed: () async { // Navigator.pop(context); // // 执行退出登录逻辑 // await GetIt.I().deleteUser(); // GetIt.I().logout(); // context.go(RoutePaths.login); // }, // style: TextButton.styleFrom( // foregroundColor: const Color(0xFFF53F3F), // ), // child: Text( // AppLocalizations.of(context).translate('my_v2.confirm'), // ), // ), // ], // ), // ); // } }