import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/profile_controller.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import '../../../core/widgets/common_bottom_nav.dart'; import '../../../routes/app_routes.dart'; import 'dart:io'; import 'dart:ui'; import '../../common/webview_page.dart'; // ProfileView: 用户设置页面 // class ProfileView extends GetView { // const ProfileView({Key? key}) : super(key: key); // Widget _buildMenuItem({ // required String title, // required IconData icon, // String? subtitle, // required VoidCallback onTap, // }) { // return ListTile( // leading: Icon(icon, size: 24.sp, color: Colors.grey[700]), // title: Text( // title, // style: TextStyle( // fontSize: 16.sp, // fontWeight: FontWeight.w500, // ), // ), // subtitle: subtitle != null // ? Text( // subtitle, // style: TextStyle( // fontSize: 14.sp, // color: Colors.grey[600], // ), // ) // : null, // trailing: Icon( // Icons.chevron_right, // size: 24.sp, // color: Colors.grey[400], // ), // onTap: onTap, // ); // } // @override // Widget build(BuildContext context) { // return Scaffold( // backgroundColor: Colors.white, // appBar: AppBar( // backgroundColor: Colors.white, // elevation: 0, // title: Text( // '设置'.tr, // style: TextStyle( // fontSize: 17.sp, // fontWeight: FontWeight.w600, // color: Colors.black, // ), // ), // centerTitle: true, // ), // body: ListView( // children: [ // SizedBox(height: 12.h), // const Divider(), // _buildMenuItem( // title: '关于'.tr, // icon: Icons.info_outline, // onTap: () { // // TODO: 实现关于页面 // }, // ), // const Divider(), // _buildMenuItem( // title: '火山语音合成测试'.tr, // icon: Icons.record_voice_over, // subtitle: '测试火山语音TTS功能', // onTap: () { // Get.toNamed(Routes.TTS_TEST); // }, // ), // const Divider(), // _buildMenuItem( // title: '火山语音识别测试'.tr, // icon: Icons.mic_external_on, // subtitle: '测试火山语音ASR功能', // onTap: () { // Get.toNamed(Routes.VOLCANO_ASR_TEST); // }, // ), // const Divider(), // _buildMenuItem( // title: 'Azure语音识别测试'.tr, // icon: Icons.mic, // subtitle: '测试Azure语音ASR功能', // onTap: () { // Get.toNamed(Routes.AZURE_ASR_TEST); // }, // ), // const Divider(), // _buildMenuItem( // title: 'Azure语音合成测试'.tr, // icon: Icons.record_voice_over, // subtitle: '测试Azure语音TTS功能', // onTap: () { // Get.toNamed(Routes.AZURE_TTS_TEST); // }, // ), // const Divider(), // _buildMenuItem( // title: '本地语音合成测试'.tr, // icon: Icons.speaker_phone, // subtitle: '测试Flutter TTS本地语音合成功能', // onTap: () { // Get.toNamed(Routes.FLUTTER_TTS_TEST); // }, // ), // const Divider(), // _buildMenuItem( // title: '本地语音识别测试'.tr, // icon: Icons.mic_none, // subtitle: '测试Flutter本地语音识别功能', // onTap: () { // Get.toNamed(Routes.FLUTTER_ASR_TEST); // }, // ), // ], // ), // bottomNavigationBar: const CommonBottomNav(currentIndex: 2), // ); // } // } // EditProfileView: 编辑个人资料页面 class EditProfileView extends GetView { const EditProfileView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; final nameController = TextEditingController(text: controller.userInfo.value.name); return Scaffold( resizeToAvoidBottomInset: false, // 添加这一行,防止键盘挤压内容 appBar: AppBar( automaticallyImplyLeading: false, centerTitle: true, elevation: 0, backgroundColor: isDarkMode ? Colors.black : Colors.white, leading: IconButton( icon: Icon( Icons.arrow_back_ios, size: 20.sp, color: isDarkMode ? Colors.white : Colors.black, ), onPressed: () => Get.back(), ), // title: Text( // 'editProfile'.tr, // style: TextStyle( // fontSize: 17.sp, // fontWeight: FontWeight.w600, // color: isDarkMode ? Colors.white : Colors.black, // ), // ), actions: [ Obx(() => Visibility( visible: controller.hasEdits.value, child: TextButton( onPressed: () { // 保存用户名 controller.updateUserNameAndAvatar(nameController.text); // 返回上一级页面 Get.back(); }, child: Text( 'save'.tr, style: TextStyle( fontSize: 16.sp, color: isDarkMode ? Colors.blue[300] : Colors.blue, fontWeight: FontWeight.w500, ), ), ), )) ], ), body: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildEditProfileSection(context, isDarkMode, nameController), SizedBox(height: 16.h), _buildAccountSettings(isDarkMode), SizedBox(height: 16.h), ]))); } // 新增:构建编辑资料区域的方法 Widget _buildEditProfileSection(BuildContext context, bool isDarkMode, TextEditingController nameController) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(left: 4.w, bottom: 8.h), child: Text( 'editProfile'.tr, // 编辑资料 style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.blue[400] : Colors.blue[600], letterSpacing: 1, ), ), ), Container( decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, borderRadius: BorderRadius.circular(16.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(16.r), child: BackdropFilter( // 保留毛玻璃效果(如果需要) filter: isDarkMode ? ImageFilter.blur(sigmaX: 5, sigmaY: 5) : ImageFilter.blur(sigmaX: 0, sigmaY: 0), child: Column( children: [ // 头像设置项 _buildAvatarSetting(isDarkMode), Divider( height: 1, color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[200]), // 昵称设置项 _buildNicknameSetting(context, isDarkMode, nameController), ], ), ), ), ), ], ); } // 新增:构建头像设置项 Widget _buildAvatarSetting(bool isDarkMode) { return InkWell( onTap: () => controller.updateUserAvatar(), child: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 4.h), // 调整垂直间距 child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // 移除,让内容自然排列 children: [ // --- 添加图标 --- Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: isDarkMode ? Colors.blue[900]!.withOpacity(0.3) // 使用示例颜色 : Colors.blue[50]!, // 使用示例颜色 borderRadius: BorderRadius.circular(16.r), // 图标背景圆角 ), child: Icon( Icons.account_circle_outlined, // 头像图标 size: 18.w, color: isDarkMode ? Colors.blue[300]! : Colors.blue[600]!, // 图标颜色 ), ), SizedBox(width: 12.w), // 图标和文字间距 // --- --- Expanded( // 让文字占据剩余空间 child: Text( 'avatar'.tr, // 头像 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.white : Colors.black87, ), ), ), // --- 右侧内容保持不变 --- Row( children: [ Obx(() => CircleAvatar( radius: 30.r, // 调整头像大小以适应行高 backgroundImage: controller.localAvatar.value.isNotEmpty ? FileImage(File(controller.localAvatar.value)) : (controller.userInfo.value.avatar.isNotEmpty ? NetworkImage(controller.userInfo.value.avatar) : null) as ImageProvider?, child: (controller.localAvatar.value.isEmpty && controller.userInfo.value.avatar.isEmpty) ? Icon(Icons.person, size: 20.r, color: Colors.grey) // 默认图标 : null, backgroundColor: Colors.grey[200], // 添加背景色防止透明图片问题 )), SizedBox(width: 8.w), Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.grey[100], borderRadius: BorderRadius.circular(16.r), ), child: Icon( Icons.chevron_right, size: 16.w, color: isDarkMode ? Colors.white70 : Colors.grey[500], ), ), ], ), // --- --- ], ), ), ); } // 新增:构建昵称设置项 Widget _buildNicknameSetting(BuildContext context, bool isDarkMode, TextEditingController nameController) { return InkWell( onTap: () => _showEditNicknameDialog(context, isDarkMode, nameController), child: Padding( padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), // 调整垂直间距 child: Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // 移除 children: [ // --- 添加图标 --- Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: isDarkMode ? Colors.green[900]!.withOpacity(0.3) // 使用示例颜色 : Colors.green[50]!, // 使用示例颜色 borderRadius: BorderRadius.circular(16.r), // 图标背景圆角 ), child: Icon( Icons.edit_outlined, // 编辑图标 size: 18.w, color: isDarkMode ? Colors.green[300]! : Colors.green[600]!, // 图标颜色 ), ), SizedBox(width: 12.w), // 图标和文字间距 // --- --- Expanded( // 让文字占据剩余空间 child: Text( 'nickname'.tr, // 名字 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.white : Colors.black87, ), ), ), // --- 右侧内容保持不变 --- Row( children: [ // 使用 Obx 监听 userInfo 的变化来显示昵称 Obx(() => Text( controller.userInfo.value.name.isNotEmpty ? controller.userInfo.value.name : 'notSet'.tr, // 未设置 style: TextStyle( fontSize: 14.sp, color: isDarkMode ? Colors.white70 : Colors.grey[600], ), overflow: TextOverflow.ellipsis, )), SizedBox(width: 8.w), Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.grey[100], borderRadius: BorderRadius.circular(16.r), ), child: Icon( Icons.chevron_right, size: 16.w, color: isDarkMode ? Colors.white70 : Colors.grey[500], ), ), ], ), // --- --- ], ), ), ); } // 新增:显示编辑昵称对话框的方法 void _showEditNicknameDialog(BuildContext context, bool isDarkMode, TextEditingController nameController) { // 创建一个临时的 Controller,用于对话框内的编辑,避免直接修改主 nameController final dialogNameController = TextEditingController(text: nameController.text); Get.dialog( AlertDialog( backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, title: Text( 'editNickname'.tr, // 编辑昵称 style: TextStyle(color: isDarkMode ? Colors.white : Colors.black87), ), content: TextField( controller: dialogNameController, // 使用对话框的 Controller autofocus: true, decoration: InputDecoration( hintText: 'enterNickname'.tr, // 请输入昵称 hintStyle: TextStyle(color: isDarkMode ? Colors.white54 : Colors.black38), // 可以添加其他样式,如边框 border: OutlineInputBorder( borderRadius: BorderRadius.circular(8.r), borderSide: BorderSide( color: isDarkMode ? Colors.white38 : Colors.grey[400]!), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.r), borderSide: BorderSide( color: isDarkMode ? Colors.white38 : Colors.grey[400]!), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8.r), borderSide: BorderSide( color: isDarkMode ? Colors.blue[300]! : Colors.blue), ), ), style: TextStyle(color: isDarkMode ? Colors.white : Colors.black87), ), actions: [ TextButton( onPressed: () => Get.back(), child: Text( 'cancel'.tr, style: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54), ), ), TextButton( onPressed: () { // 确认时,将对话框输入的值更新回主 nameController nameController.text = dialogNameController.text; controller.userInfo.update((user) { if (user != null) { user.name = dialogNameController.text; } }); controller.hasEdits.value = true; // 标记已编辑 Get.back(); // 关闭对话框 // 注意:实际的保存操作由 AppBar 中的保存按钮触发 }, child: Text( 'confirm'.tr, style: TextStyle(color: isDarkMode ? Colors.blue[300] : Colors.blue), ), ), ], ), ); } // _buildEditProfile(bool isDarkMode, TextEditingController nameController) { // return // //Padding( // //padding: EdgeInsets.all(16.w), // //child: // Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Padding( // padding: EdgeInsets.only(left: 4.w, bottom: 8.h), // child: Text( // 'editProfile'.tr, // 账号设置 // style: TextStyle( // fontSize: 12.sp, // fontWeight: FontWeight.w500, // color: isDarkMode ? Colors.blue[400] : Colors.blue[600], // letterSpacing: 1, // ), // ), // ), // // 头像编辑 // Center( // child: GestureDetector( // onTap: () => controller.updateUserAvatar(), // child: Stack( // children: [ // Obx(() => CircleAvatar( // radius: 50.r, // backgroundImage: controller.localAvatar.value.isNotEmpty // ? FileImage(File(controller.localAvatar.value)) // : (controller.userInfo.value.avatar.isNotEmpty // ? NetworkImage(controller.userInfo.value.avatar) // : null) as ImageProvider?, // child: controller.userInfo.value.avatar.isEmpty // ? Icon(Icons.person, size: 50.r) // : null, // )), // Positioned( // right: 0, // bottom: 0, // child: Container( // padding: EdgeInsets.all(4.w), // decoration: const BoxDecoration( // color: Colors.blue, // shape: BoxShape.circle, // ), // child: Icon( // Icons.camera_alt, // size: 20.w, // color: Colors.white, // )), // ) // ], // )), // ), // SizedBox(height: 20.h), // // 昵称编辑 - 使用外部定义的controller而不是每次重建 // Row( // children: [ // Expanded( // child: TextField( // controller: nameController, // decoration: InputDecoration( // labelText: 'nickname'.tr, // border: const OutlineInputBorder(), // suffixIcon: nameController.text.isNotEmpty // ? IconButton( // icon: const Icon(Icons.clear), // onPressed: () { // nameController.clear(); // }, // ) // : null, // ), // ), // ), // ], // ), // ], // //), // ); // } Widget _buildAccountSettings(bool isDarkMode) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: EdgeInsets.only(left: 4.w, bottom: 8.h), child: Text( 'AccountSetting'.tr, // 账号设置 style: TextStyle( fontSize: 12.sp, fontWeight: FontWeight.w500, color: isDarkMode ? Colors.blue[400] : Colors.blue[600], letterSpacing: 1, ), ), ), Container( decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, borderRadius: BorderRadius.circular(16.r), boxShadow: [ BoxShadow( color: isDarkMode ? Colors.black.withOpacity(0.2) : Colors.black.withOpacity(0.05), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(16.r), child: BackdropFilter( filter: isDarkMode ? ImageFilter.blur(sigmaX: 5, sigmaY: 5) : ImageFilter.blur(sigmaX: 0, sigmaY: 0), child: Column( children: [ // 用户协议 _buildSimpleNavigationSetting( title: 'userAgreement'.tr, // 用户协议 icon: Icons.description_outlined, iconBgColor: isDarkMode ? Colors.purple[900]!.withOpacity(0.3) : Colors.purple[50]!, iconColor: isDarkMode ? Colors.purple[300]! : Colors.purple[600]!, titleColor: isDarkMode ? Colors.white : Colors.black87, onTap: () { String url = 'https://www.deepsoud.com/yhxy.html'; if (Get.locale?.languageCode != 'zh' || Get.locale?.countryCode != 'CN') { url = 'https://www.deepsoud.com/yhxy_en.html'; } Get.to(() => WebViewPage( url: url, title: 'userAgreement'.tr, )); }, isDarkMode: isDarkMode, ), Divider( height: 1, color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[200]), // 隐私政策 _buildSimpleNavigationSetting( title: 'privacyPolicy'.tr, // 隐私政策 icon: Icons.privacy_tip_outlined, iconBgColor: isDarkMode ? Colors.purple[900]!.withOpacity(0.3) : Colors.purple[50]!, iconColor: isDarkMode ? Colors.purple[300]! : Colors.purple[600]!, titleColor: isDarkMode ? Colors.white : Colors.black87, onTap: () { String url = 'https://www.deepsoud.com/ysxy.html'; if (Get.locale?.languageCode != 'zh' || Get.locale?.countryCode != 'CN') { url = 'https://www.deepsoud.com/ysxy_en.html'; } Get.to(() => WebViewPage( url: url, title: 'privacyPolicy'.tr, )); }, isDarkMode: isDarkMode, ), Divider( height: 1, color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[200]), // 退出登录 _buildSimpleNavigationSetting( title: 'logout'.tr, // 退出登录 icon: Icons.logout, iconBgColor: isDarkMode ? Colors.red[900]!.withOpacity(0.3) : Colors.red[50]!, iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, titleColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, onTap: () { // 退出登录确认对话框 Get.dialog( AlertDialog( backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, title: Text( 'logout'.tr, // 退出登录 style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, ), ), content: Text( 'logoutTips'.tr, // 确定要退出当前账号吗? style: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, ), ), actions: [ TextButton( onPressed: () => Get.back(), child: Text( 'cancel'.tr, // 取消 style: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ), TextButton( onPressed: () { Get.back(); controller.signOut(); }, child: Text( 'confirm'.tr, // 确定 style: TextStyle( color: isDarkMode ? Colors.red[300] : Colors.red[600], ), ), ), ], ), ); }, isDarkMode: isDarkMode, ), Divider( height: 1, color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[200]), // 注销账号 _buildSimpleNavigationSetting( title: 'deleteAccount'.tr, // 注销账号 icon: Icons.delete_forever, iconBgColor: isDarkMode ? Colors.red[900]!.withOpacity(0.3) : Colors.red[50]!, iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, titleColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, onTap: () { // 注销账号确认对话框 Get.dialog( AlertDialog( backgroundColor: isDarkMode ? Colors.grey[900] : Colors.white, title: Text( 'deleteAccount'.tr, // 注销账号 style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, ), ), content: Text( 'deleteAccountTips'.tr, // 确定要永久删除您的账号吗?此操作不可撤销 style: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, ), ), actions: [ TextButton( onPressed: () => Get.back(), child: Text( 'cancel'.tr, // 取消 style: TextStyle( color: isDarkMode ? Colors.white70 : Colors.black54, ), ), ), TextButton( onPressed: () { Get.back(); controller.deleteAccount(); }, child: Text( 'confirm'.tr, // 确定 style: TextStyle( color: isDarkMode ? Colors.red[300] : Colors.red[600], ), ), ), ], ), ); }, isDarkMode: isDarkMode, ), ], ), ), ), ), ], ); } // 简单导航设置项 Widget _buildSimpleNavigationSetting({ required String title, String? subtitle, required IconData icon, required Color iconBgColor, required Color iconColor, Color? titleColor, Color? subtitleColor, required VoidCallback onTap, required bool isDarkMode, }) { return InkWell( onTap: onTap, child: Padding( padding: EdgeInsets.all(16.w), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Row( children: [ Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: iconBgColor, borderRadius: BorderRadius.circular(16.r), ), child: Icon( icon, size: 16.w, color: iconColor, ), ), SizedBox(width: 12.w), Flexible( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, color: titleColor ?? (isDarkMode ? Colors.white : Colors.black87), ), overflow: TextOverflow.ellipsis, ), if (subtitle != null) SizedBox(height: 2.h), if (subtitle != null) Text( subtitle, style: TextStyle( fontSize: 12.sp, color: subtitleColor ?? (isDarkMode ? Colors.white70 : Colors.black54), ), overflow: TextOverflow.ellipsis, ), ], ), ), ], ), ), Container( width: 32.w, height: 32.w, decoration: BoxDecoration( color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.grey[100], borderRadius: BorderRadius.circular(16.r), ), child: Icon( Icons.chevron_right, size: 16.w, color: isDarkMode ? Colors.white70 : Colors.grey[500], ), ), ], ), ), ); } }