From 964f77ca8be89c9627dd692980cab2b32263e919 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Wed, 19 Mar 2025 23:36:47 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E5=A4=B4=E5=83=8F=E5=92=8C=E7=94=A8=E6=88=B7=E5=90=8D=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/models/user_model.dart | 39 +++++ .../controllers/profile_controller.dart | 133 ++++++++++++------ lib/modules/profile/views/profile_view.dart | 104 +++++++++++++- .../controllers/settings_controller.dart | 62 ++++++++ lib/modules/settings/views/settings_view.dart | 57 +++++--- lib/routes/app_pages.dart | 5 + lib/routes/app_routes.dart | 1 + 7 files changed, 335 insertions(+), 66 deletions(-) create mode 100644 lib/data/models/user_model.dart diff --git a/lib/data/models/user_model.dart b/lib/data/models/user_model.dart new file mode 100644 index 000000000..4334df54e --- /dev/null +++ b/lib/data/models/user_model.dart @@ -0,0 +1,39 @@ +class UserModel { + String name; // 用户名 + String avatar; // 头像 + String id; + //final String deviceName; + String membershipLevel; // 会员等级 + + UserModel({ + required this.name, + required this.avatar, + required this.id, + //required this.deviceName, + required this.membershipLevel, + }); + + Map toJson() => { + 'name': name, + 'avatar': avatar, + 'id': id, + //'deviceName': deviceName, + 'membershipLevel': membershipLevel, + }; + + factory UserModel.fromJson(Map json) => UserModel( + name: json['name'] ?? '未设置昵称', + avatar: json['avatar'] ?? '', + id: json['id'] ?? '', + //deviceName: json['deviceName'] ?? '', + membershipLevel: json['membershipLevel'] ?? '普通会员', + ); + + factory UserModel.defaultUser() => UserModel( + name: '未设置昵称', + avatar: '', + id: 'deepvoice_${DateTime.now().millisecondsSinceEpoch.toString()}', + //deviceName: '', + membershipLevel: '普通会员', + ); +} \ No newline at end of file diff --git a/lib/modules/profile/controllers/profile_controller.dart b/lib/modules/profile/controllers/profile_controller.dart index f3d7a94eb..837a59b64 100644 --- a/lib/modules/profile/controllers/profile_controller.dart +++ b/lib/modules/profile/controllers/profile_controller.dart @@ -1,40 +1,47 @@ import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; +import '../../../data/models/user_model.dart'; class ProfileController extends GetxController { static ProfileController get to => Get.find(); - final _userName = ''.obs; - final _email = ''.obs; - final _avatar = ''.obs; - final _isEditing = false.obs; - final _storage = GetStorage(); + // final _userName = ''.obs; + // final _email = ''.obs; + // final _avatar = ''.obs; + // final _isEditing = false.obs; + // final _storage = GetStorage(); + //用户信息 + static const String userKey='user_info'; + final _storage=GetStorage(); + final ImagePicker _picker=ImagePicker(); + final Rx userInfo=UserModel.defaultUser().obs; // 使用响应式变量 final currentLanguage = 'zh'.obs; - String get userName => _userName.value; - String get email => _email.value; - String get avatar => _avatar.value; - bool get isEditing => _isEditing.value; + // String get userName => _userName.value; + // String get email => _email.value; + // String get avatar => _avatar.value; + // bool get isEditing => _isEditing.value; @override void onInit() { super.onInit(); - loadUserData(); + loadUserInfo(); loadLanguagePreference(); } - void loadUserData() { - try { - _userName.value = _storage.read('userName') ?? 'User Name'; - _email.value = _storage.read('userEmail') ?? 'user@example.com'; - _avatar.value = _storage.read('userAvatar') ?? ''; - } catch (e) { - Get.snackbar('Error', 'Failed to load user data'); - } - } + // void loadUserData() { + // try { + // _userName.value = _storage.read('userName') ?? 'User Name'; + // _email.value = _storage.read('userEmail') ?? 'user@example.com'; + // _avatar.value = _storage.read('userAvatar') ?? ''; + // } catch (e) { + // Get.snackbar('Error', 'Failed to load user data'); + // } + // } // 加载用户语言偏好设置 void loadLanguagePreference() { @@ -72,31 +79,71 @@ class ProfileController extends GetxController { }); } - Future updateUserData({ - String? userName, - String? email, - String? avatar, - }) async { - try { - if (userName != null) { - await _storage.write('userName', userName); - _userName.value = userName; - } - if (email != null) { - await _storage.write('userEmail', email); - _email.value = email; - } - if (avatar != null) { - await _storage.write('userAvatar', avatar); - _avatar.value = avatar; - } - Get.snackbar('Success', 'Profile updated successfully'); - } catch (e) { - Get.snackbar('Error', 'Failed to update profile'); + // Future updateUserData({ + // String? userName, + // String? email, + // String? avatar, + // }) async { + // try { + // if (userName != null) { + // await _storage.write('userName', userName); + // _userName.value = userName; + // } + // if (email != null) { + // await _storage.write('userEmail', email); + // _email.value = email; + // } + // if (avatar != null) { + // await _storage.write('userAvatar', avatar); + // _avatar.value = avatar; + // } + // Get.snackbar('Success', 'Profile updated successfully'); + // } catch (e) { + // Get.snackbar('Error', 'Failed to update profile'); + // } + // } + + // void toggleEditing() { + // _isEditing.value = !_isEditing.value; + // } + + void loadUserInfo() { + final userJson = _storage.read(userKey); + if (userJson != null) { + userInfo.value = UserModel.fromJson(userJson); } } - - void toggleEditing() { - _isEditing.value = !_isEditing.value; + + Future saveUserInfo() async { + await _storage.write(userKey, userInfo.value.toJson()); + } + + Future updateUserAvatar() async { + final XFile? image = await _picker.pickImage( + source: ImageSource.gallery, + maxWidth: 800, + maxHeight: 800, + imageQuality: 85, + ); + + if (image != null) { + userInfo.update((user) { + if (user != null) { + user.avatar = image.path; + } + }); + await saveUserInfo(); + } + } + + Future updateUserName(String name) async { + if (name.trim().isNotEmpty) { + userInfo.update((user) { + if (user != null) { + user.name = name.trim(); + } + }); + await saveUserInfo(); + } } } \ No newline at end of file diff --git a/lib/modules/profile/views/profile_view.dart b/lib/modules/profile/views/profile_view.dart index 84e8a25fa..c23bf2685 100644 --- a/lib/modules/profile/views/profile_view.dart +++ b/lib/modules/profile/views/profile_view.dart @@ -4,7 +4,9 @@ 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'; +// ProfileView: 用户设置页面 class ProfileView extends GetView { const ProfileView({Key? key}) : super(key: key); @@ -132,4 +134,104 @@ class ProfileView extends GetView { bottomNavigationBar: const CommonBottomNav(currentIndex: 2), ); } -} \ No newline at end of file +} + + +// 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( + appBar: AppBar( + title: const Text('个人资料'), + actions: [ + TextButton( + onPressed: () { + // 保存用户名 + controller.updateUserName(nameController.text); + // 返回上一级页面 + Get.back(); + }, + child: Text( + '保存', + style: TextStyle( + fontSize: 16.sp, + color: isDarkMode ? Colors.blue[300] : Colors.blue, + fontWeight: FontWeight.w500, + ), + ), + ), + ], + ), + body: Padding( + padding: EdgeInsets.all(16.w), + child: Column( + children: [ + // 头像编辑 + Center( + child: GestureDetector( + onTap: () => controller.updateUserAvatar(), + child: Obx(() => CircleAvatar( + radius: 50.r, + backgroundImage: controller.userInfo.value.avatar.isNotEmpty + ? FileImage(File(controller.userInfo.value.avatar)) + : null, + child: controller.userInfo.value.avatar.isEmpty + ? Icon(Icons.person, size: 50.r) + : null, + // onBackgroundImageError: hasAvatar + // ? (_, __) {} + // : null, + )), + ), + ), + SizedBox(height: 20.h), + // 昵称编辑 - 使用外部定义的controller而不是每次重建 + TextField( + controller: nameController, + decoration: const InputDecoration( + labelText: '昵称', + border: OutlineInputBorder(), + ), + ), + // ... 其他编辑项 ... + + SizedBox(height: 30.h), + // 添加一个大的保存按钮 + SizedBox( + width: double.infinity, + height: 50.h, + child: ElevatedButton( + onPressed: () { + // 保存用户名 + controller.updateUserName(nameController.text); + // 返回上一级页面 + Get.back(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: isDarkMode ? Colors.blue[700] : Colors.blue, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10.r), + ), + ), + child: Text( + '保存', + style: TextStyle( + fontSize: 16.sp, + color: Colors.white, + fontWeight: FontWeight.w500, + ), + ), + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/modules/settings/controllers/settings_controller.dart b/lib/modules/settings/controllers/settings_controller.dart index 1ab68e829..5275b0009 100644 --- a/lib/modules/settings/controllers/settings_controller.dart +++ b/lib/modules/settings/controllers/settings_controller.dart @@ -1,7 +1,10 @@ import 'package:get/get.dart'; import 'package:flutter/material.dart'; +import 'package:image_picker/image_picker.dart'; import '../../../core/themes/theme_service.dart'; import '../../../data/services/speech_factory.dart'; +import 'package:get_storage/get_storage.dart'; +import '../../../data/models/user_model.dart'; class SettingsController extends GetxController { // 主题服务 @@ -21,6 +24,12 @@ class SettingsController extends GetxController { {'type': SpeechServiceType.azure, 'name': 'Azure 语音服务', 'description': '微软云端语音服务,支持高质量语音合成和识别'}, {'type': SpeechServiceType.flutter, 'name': 'Flutter 本地语音服务', 'description': '设备本地语音服务,无需联网即可使用'}, ]; + + //用户信息 + static const String userKey='user_info'; + final _storage=GetStorage(); + final ImagePicker _picker=ImagePicker(); + final Rx userInfo=UserModel.defaultUser().obs; @override void onInit() { @@ -34,7 +43,60 @@ class SettingsController extends GetxController { // 获取当前语音服务类型 _loadCurrentSpeechServiceType(); + + //获取用户信息 + loadUserInfo(); + } + + void loadUserInfo() { + final userJson = _storage.read(userKey); + if (userJson != null) { + userInfo.value = UserModel.fromJson(userJson); + } + } + + Future saveUserInfo() async { + await _storage.write(userKey, userInfo.value.toJson()); } + + Future updateUserAvatar() async { + final XFile? image = await _picker.pickImage( + source: ImageSource.gallery, + maxWidth: 800, + maxHeight: 800, + imageQuality: 85, + ); + + if (image != null) { + userInfo.update((user) { + if (user != null) { + user.avatar = image.path; + } + }); + await saveUserInfo(); + } + } + + Future updateUserName(String name) async { + if (name.trim().isNotEmpty) { + userInfo.update((user) { + if (user != null) { + user.name = name.trim(); + } + }); + await saveUserInfo(); + } + } + +// Future updateDeviceName(String deviceName) async { +// userInfo.update((user) { +// if (user != null) { +// user.deviceName = deviceName; +// } +// }); +// await saveUserInfo(); +// } +// } // 加载当前语音服务类型 void _loadCurrentSpeechServiceType() { diff --git a/lib/modules/settings/views/settings_view.dart b/lib/modules/settings/views/settings_view.dart index d66e6e9c9..126ab3ab5 100644 --- a/lib/modules/settings/views/settings_view.dart +++ b/lib/modules/settings/views/settings_view.dart @@ -5,6 +5,7 @@ import 'dart:ui'; import '../controllers/settings_controller.dart'; import '../../../core/widgets/common_bottom_nav.dart'; import '../../../routes/app_routes.dart'; +import 'dart:io'; class SettingsView extends GetView { const SettingsView({Key? key}) : super(key: key); @@ -74,13 +75,15 @@ class SettingsView extends GetView { ), ], ), - child: ClipRRect( + child: ClipRRect(//裁剪圆角矩形 borderRadius: BorderRadius.circular(16.r), - child: BackdropFilter( + child: BackdropFilter(// 背景滤镜(实现毛玻璃效果) filter: isDarkMode ? ImageFilter.blur(sigmaX: 10, sigmaY: 10) : ImageFilter.blur(sigmaX: 0, sigmaY: 0), child: Row( children: [ - Container( + Obx(()=>GestureDetector( + onTap: ()=>controller.updateUserAvatar(), + child:Container(//用户头像部分 width: 60.w, height: 60.w, decoration: BoxDecoration( @@ -93,21 +96,27 @@ class SettingsView extends GetView { ), ], ), - child: ClipRRect( + child: ClipRRect(// 裁剪圆形头像 borderRadius: BorderRadius.circular(30.r), - child: Image.network( + child: controller.userInfo.value.avatar.isEmpty + ? Image.network( 'https://images.unsplash.com/photo-1534528741775-53994a69daeb?ixlib=rb-1.2.1&auto=format&fit=crop&w=200&q=80', - fit: BoxFit.cover, - ), + fit: BoxFit.cover,// 图片填充方式 + ) + :Image.file( + File(controller.userInfo.value.avatar), + fit: BoxFit.cover,// 图片填充方式 + ) ), ), + )), SizedBox(width: 16.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + Expanded(// 占据剩余空间 + child: Obx(()=>Column( + crossAxisAlignment: CrossAxisAlignment.start,// 左对齐 children: [ - Text( - '林美珍', + Text(//用户名 + controller.userInfo.value.name, style: TextStyle( fontSize: 18.sp, fontWeight: FontWeight.w600, @@ -118,14 +127,14 @@ class SettingsView extends GetView { SizedBox(height: 4.h), Row( children: [ - Container( + Container(// 会员等级 padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 2.h), decoration: BoxDecoration( color: Colors.blue[600], borderRadius: BorderRadius.circular(10.r), ), child: Text( - '高级会员', + controller.userInfo.value.membershipLevel, style: TextStyle( fontSize: 10.sp, color: Colors.white, @@ -147,7 +156,7 @@ class SettingsView extends GetView { ), SizedBox(height: 4.h), Text( - '账号ID: deepvoice_834291', + controller.userInfo.value.id, style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.white70 : Colors.black54, @@ -155,8 +164,8 @@ class SettingsView extends GetView { ), ], ), - ), - Container( + ),), + Container(// 编辑按钮 width: 32.w, height: 32.w, decoration: BoxDecoration( @@ -172,11 +181,15 @@ class SettingsView extends GetView { ), ], ), - child: Icon( - Icons.edit, - size: 16.w, - color: isDarkMode ? Colors.white70 : Colors.grey[600], - ), + child: InkWell( + onTap: () => Get.toNamed(Routes.editProfile), + child: Icon( + Icons.edit, + size: 16.w, + color: isDarkMode ? Colors.white70 : Colors.grey[600], + ), + ) + ), ], ), diff --git a/lib/routes/app_pages.dart b/lib/routes/app_pages.dart index 7c3388e5e..034cc859f 100644 --- a/lib/routes/app_pages.dart +++ b/lib/routes/app_pages.dart @@ -64,6 +64,11 @@ abstract class AppPages { page: () => const ProfileView(), binding: ProfileBinding(), ), + GetPage( + name: Routes.editProfile, + page: () => const EditProfileView(), + binding: ProfileBinding(), + ), GetPage( name: Routes.translation, diff --git a/lib/routes/app_routes.dart b/lib/routes/app_routes.dart index 1d6c8a1ea..b5e34e078 100644 --- a/lib/routes/app_routes.dart +++ b/lib/routes/app_routes.dart @@ -18,4 +18,5 @@ abstract class Routes { static const translationHistory = '/translation_history'; static const FLUTTER_TTS_TEST = '/flutter_tts_test'; static const FLUTTER_ASR_TEST = '/flutter_asr_test'; + static const editProfile='/edit_profile'; } \ No newline at end of file From 52e35241df3e84885578a23ad4f7ece4b707d1fe Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Thu, 20 Mar 2025 11:51:05 +0800 Subject: [PATCH 2/7] =?UTF-8?q?editProfile=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/profile_controller.dart | 12 ++ lib/modules/profile/views/profile_view.dart | 113 +++++++++++------- lib/modules/settings/views/settings_view.dart | 2 +- 3 files changed, 84 insertions(+), 43 deletions(-) diff --git a/lib/modules/profile/controllers/profile_controller.dart b/lib/modules/profile/controllers/profile_controller.dart index 837a59b64..a75f87ee9 100644 --- a/lib/modules/profile/controllers/profile_controller.dart +++ b/lib/modules/profile/controllers/profile_controller.dart @@ -3,6 +3,7 @@ import 'package:get_storage/get_storage.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import '../../../data/models/user_model.dart'; +import '../../settings/controllers/settings_controller.dart'; class ProfileController extends GetxController { static ProfileController get to => Get.find(); @@ -133,6 +134,11 @@ class ProfileController extends GetxController { } }); await saveUserInfo(); + + // 通知 SettingsController 更新 + if (Get.isRegistered()) { + Get.find().loadUserInfo(); + } } } @@ -144,6 +150,12 @@ class ProfileController extends GetxController { } }); await saveUserInfo(); + + // 同步更新 SettingsController + if (Get.isRegistered()) { + final settingsController = Get.find(); + settingsController.loadUserInfo(); + } } } } \ No newline at end of file diff --git a/lib/modules/profile/views/profile_view.dart b/lib/modules/profile/views/profile_view.dart index c23bf2685..dd21ed8bc 100644 --- a/lib/modules/profile/views/profile_view.dart +++ b/lib/modules/profile/views/profile_view.dart @@ -63,7 +63,6 @@ class ProfileView extends GetView { body: ListView( children: [ SizedBox(height: 12.h), - const Divider(), _buildMenuItem( title: '关于'.tr, @@ -72,7 +71,6 @@ class ProfileView extends GetView { // TODO: 实现关于页面 }, ), - const Divider(), _buildMenuItem( title: '火山语音合成测试'.tr, @@ -82,8 +80,6 @@ class ProfileView extends GetView { Get.toNamed(Routes.TTS_TEST); }, ), - - const Divider(), _buildMenuItem( title: '火山语音识别测试'.tr, @@ -102,7 +98,7 @@ class ProfileView extends GetView { Get.toNamed(Routes.AZURE_ASR_TEST); }, ), - const Divider(), + const Divider(), _buildMenuItem( title: 'Azure语音合成测试'.tr, icon: Icons.record_voice_over, @@ -134,8 +130,7 @@ class ProfileView extends GetView { bottomNavigationBar: const CommonBottomNav(currentIndex: 2), ); } -} - +} // EditProfileView: 编辑个人资料页面 class EditProfileView extends GetView { @@ -144,29 +139,45 @@ class EditProfileView extends GetView { @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; - final nameController = TextEditingController(text: controller.userInfo.value.name); - + final nameController = + TextEditingController(text: controller.userInfo.value.name); + return Scaffold( appBar: AppBar( - title: const Text('个人资料'), - actions: [ - TextButton( - onPressed: () { - // 保存用户名 - controller.updateUserName(nameController.text); - // 返回上一级页面 - Get.back(); - }, - child: Text( - '保存', - style: TextStyle( - fontSize: 16.sp, - color: isDarkMode ? Colors.blue[300] : Colors.blue, - fontWeight: FontWeight.w500, - ), - ), + automaticallyImplyLeading: false, + centerTitle: true, + elevation: 0, + backgroundColor: isDarkMode ? Colors.black : Colors.white, + title: Text( + '编辑个人资料', + style: TextStyle( + fontSize: 17.sp, + fontWeight: FontWeight.w600, + color: isDarkMode ? Colors.white : Colors.black, ), - ], + ), + // actions: [ + // TextButton( + // onPressed: () { + // // 保存用户名 + // controller.updateUserName(nameController.text); + // // 返回上一级页面 + // Get.back(); + // }, + // style: TextButton.styleFrom( + // foregroundColor: Colors.blue, // 确保按钮文字颜色 + // padding: EdgeInsets.symmetric(horizontal: 16.w), + // ), + // child: Text( + // '保 存', + // style: TextStyle( + // fontSize: 16.sp, + // color: isDarkMode ? Colors.blue[300] : Colors.blue, + // fontWeight: FontWeight.w500, + // ), + // ), + // ), + // ], ), body: Padding( padding: EdgeInsets.all(16.w), @@ -175,22 +186,40 @@ class EditProfileView extends GetView { // 头像编辑 Center( child: GestureDetector( - onTap: () => controller.updateUserAvatar(), - child: Obx(() => CircleAvatar( - radius: 50.r, - backgroundImage: controller.userInfo.value.avatar.isNotEmpty - ? FileImage(File(controller.userInfo.value.avatar)) - : null, - child: controller.userInfo.value.avatar.isEmpty - ? Icon(Icons.person, size: 50.r) - : null, - // onBackgroundImageError: hasAvatar - // ? (_, __) {} - // : null, - )), - ), + onTap: () => controller.updateUserAvatar(), + child: Stack( + children: [ + Obx(() => CircleAvatar( + radius: 50.r, + backgroundImage: + controller.userInfo.value.avatar.isNotEmpty + ? FileImage( + File(controller.userInfo.value.avatar)) + : null, + 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而不是每次重建 TextField( controller: nameController, @@ -200,7 +229,7 @@ class EditProfileView extends GetView { ), ), // ... 其他编辑项 ... - + SizedBox(height: 30.h), // 添加一个大的保存按钮 SizedBox( diff --git a/lib/modules/settings/views/settings_view.dart b/lib/modules/settings/views/settings_view.dart index 126ab3ab5..d60967e6d 100644 --- a/lib/modules/settings/views/settings_view.dart +++ b/lib/modules/settings/views/settings_view.dart @@ -82,7 +82,7 @@ class SettingsView extends GetView { child: Row( children: [ Obx(()=>GestureDetector( - onTap: ()=>controller.updateUserAvatar(), + //onTap: ()=>controller.updateUserAvatar(), child:Container(//用户头像部分 width: 60.w, height: 60.w, From 8c8c5e16a9a56b67793e4e90c3b5b3da7b03088a Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Thu, 20 Mar 2025 15:51:21 +0800 Subject: [PATCH 3/7] =?UTF-8?q?editProfile=E9=A1=B5=E9=9D=A2=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E5=A4=9A=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/translations/language/en_us.dart | 5 ++ lib/core/translations/language/zh_cn.dart | 5 ++ lib/modules/profile/views/profile_view.dart | 52 +++++++++------------ 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index 1df8d03eb..72a8c0c35 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -152,4 +152,9 @@ const Map enUS = { // 翻译页 "selectSourceLanguage": "Select Source Language", "selectTargetLanguage": "Select Target Language", + + //编辑个人信息页 + "editProfile": "Edit Profile", + "nickname": "Nickname", + "save": "Save", }; diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index 657a6880c..c1828d06c 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -147,4 +147,9 @@ const Map zhCN = { // 翻译页 "selectSourceLanguage": "选择源语言", "selectTargetLanguage": "选择目标语言", + + //编辑个人信息页 + "editProfile": "编辑个人信息", + "nickname": "昵称", + "save": "保存", }; diff --git a/lib/modules/profile/views/profile_view.dart b/lib/modules/profile/views/profile_view.dart index dd21ed8bc..c2947f532 100644 --- a/lib/modules/profile/views/profile_view.dart +++ b/lib/modules/profile/views/profile_view.dart @@ -149,35 +149,13 @@ class EditProfileView extends GetView { elevation: 0, backgroundColor: isDarkMode ? Colors.black : Colors.white, title: Text( - '编辑个人资料', + 'editProfile'.tr, style: TextStyle( fontSize: 17.sp, fontWeight: FontWeight.w600, color: isDarkMode ? Colors.white : Colors.black, ), ), - // actions: [ - // TextButton( - // onPressed: () { - // // 保存用户名 - // controller.updateUserName(nameController.text); - // // 返回上一级页面 - // Get.back(); - // }, - // style: TextButton.styleFrom( - // foregroundColor: Colors.blue, // 确保按钮文字颜色 - // padding: EdgeInsets.symmetric(horizontal: 16.w), - // ), - // child: Text( - // '保 存', - // style: TextStyle( - // fontSize: 16.sp, - // color: isDarkMode ? Colors.blue[300] : Colors.blue, - // fontWeight: FontWeight.w500, - // ), - // ), - // ), - // ], ), body: Padding( padding: EdgeInsets.all(16.w), @@ -221,12 +199,26 @@ class EditProfileView extends GetView { SizedBox(height: 20.h), // 昵称编辑 - 使用外部定义的controller而不是每次重建 - TextField( - controller: nameController, - decoration: const InputDecoration( - labelText: '昵称', - border: OutlineInputBorder(), - ), + Row( + children: [ + Expanded( + child: TextField( + controller: nameController, + decoration: InputDecoration( + labelText: 'nickname'.tr, + border: OutlineInputBorder(), + suffixIcon: nameController.text.isNotEmpty + ? IconButton( + icon: Icon(Icons.clear), + onPressed: () { + nameController.clear(); + }, + ) + : null, + ), + ), + ), + ], ), // ... 其他编辑项 ... @@ -249,7 +241,7 @@ class EditProfileView extends GetView { ), ), child: Text( - '保存', + 'save'.tr, style: TextStyle( fontSize: 16.sp, color: Colors.white, From 6711d9b0dc87a9da4f5c2210b136d8c236e94c42 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Thu, 20 Mar 2025 18:27:17 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AF=B9=E8=93=9D?= =?UTF-8?q?=E7=89=99=E5=BC=80=E5=85=B3=E7=8A=B6=E6=80=81=E7=9A=84=E7=9B=91?= =?UTF-8?q?=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/data/services/classic_bluetooth_service.dart | 4 ++-- lib/modules/home/controllers/home_controller.dart | 1 + lib/modules/home/views/home_view.dart | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/data/services/classic_bluetooth_service.dart b/lib/data/services/classic_bluetooth_service.dart index bc4c3a25e..3ed682e6b 100644 --- a/lib/data/services/classic_bluetooth_service.dart +++ b/lib/data/services/classic_bluetooth_service.dart @@ -316,7 +316,7 @@ class ClassicBluetoothService extends GetxService { if (event is Map) { final type = event['type'] as String?; - if (type == 'stateChanged') { + if (type == 'bluetoothStateChanged') { final state = event['state'] as String?; if (state != null) { _handleBluetoothStateChange(state); @@ -353,7 +353,7 @@ class ClassicBluetoothService extends GetxService { /// 处理蓝牙状态变化 void _handleBluetoothStateChange(String state) { - Logger.info('蓝牙状态变化: $state'); + Logger.info('----蓝牙状态变化: $state'); // 如果蓝牙关闭,清除设备信息 if (state == 'off') { diff --git a/lib/modules/home/controllers/home_controller.dart b/lib/modules/home/controllers/home_controller.dart index 8b6bc7716..4cd0fdfa8 100644 --- a/lib/modules/home/controllers/home_controller.dart +++ b/lib/modules/home/controllers/home_controller.dart @@ -111,6 +111,7 @@ class HomeController extends GetxController { // 设置蓝牙监听器 void _setupBluetoothListeners() { + // 监听设备连接 _bluetoothService.onDeviceConnected((device) { Logger.info('监听到蓝牙设备连接: ${device.name}'); diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index da2a1aa3c..c3b646fae 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -69,6 +69,7 @@ class _AnimatedPulsingState extends State } } +//首页视图 class HomeView extends GetView { const HomeView({Key? key}) : super(key: key); From 8f88a634b38908906aba49e39ed115c92e6143b3 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Thu, 20 Mar 2025 20:40:24 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dhome=E9=A1=B5AI=E5=A5=B3?= =?UTF-8?q?=E5=8F=8B=E8=B7=B3=E8=BD=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/modules/home/bindings/home_binding.dart | 2 ++ lib/modules/home/controllers/home_controller.dart | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/modules/home/bindings/home_binding.dart b/lib/modules/home/bindings/home_binding.dart index d503413c7..9a67dfcc4 100644 --- a/lib/modules/home/bindings/home_binding.dart +++ b/lib/modules/home/bindings/home_binding.dart @@ -1,3 +1,4 @@ +import 'package:deep_voice/modules/explore/controllers/explore_controller.dart'; import 'package:get/get.dart'; import '../controllers/home_controller.dart'; @@ -5,5 +6,6 @@ class HomeBinding extends Bindings { @override void dependencies() { Get.lazyPut(() => HomeController()); + Get.lazyPut(()=>ExploreController());// 注册ExploreController } } \ No newline at end of file diff --git a/lib/modules/home/controllers/home_controller.dart b/lib/modules/home/controllers/home_controller.dart index 4cd0fdfa8..5e5ea4223 100644 --- a/lib/modules/home/controllers/home_controller.dart +++ b/lib/modules/home/controllers/home_controller.dart @@ -6,6 +6,7 @@ import 'package:flutter_blue_plus/flutter_blue_plus.dart' hide BluetoothDevice; import 'package:flutter/material.dart'; import '../../../data/services/voice_interaction_service.dart'; import 'package:permission_handler/permission_handler.dart'; +import '../../explore/controllers/explore_controller.dart'; // 连接状态枚举 enum ConnectionStatus { @@ -17,6 +18,7 @@ enum ConnectionStatus { class HomeController extends GetxController { static HomeController get to => Get.find(); + final ExploreController exploreController = Get.find(); // 经典蓝牙服务 late classic.ClassicBluetoothService _bluetoothService; @@ -186,13 +188,13 @@ class HomeController extends GetxController { // 打开AI伴侣功能 void openAIGirlfriend() { - Get.toNamed(Routes.chat); + exploreController.onAIFeatureTap(2);//进入AI女友页面 } // 展示AI功能 void exploreAIFeatures() { // 简单实现,直接跳转到AI聊天页面 - openAIGirlfriend(); + Get.toNamed(Routes.chat); } // 获取连接状态对应的颜色 From 3b9d28e676b6cc94a6a5768b78a8dbcee9767aef Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Fri, 21 Mar 2025 11:14:08 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=9B=B4=E6=8D=A2?= =?UTF-8?q?=E5=A4=B4=E5=83=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controllers/profile_controller.dart | 77 ++++++++++++++----- pubspec.yaml | 2 + 2 files changed, 60 insertions(+), 19 deletions(-) diff --git a/lib/modules/profile/controllers/profile_controller.dart b/lib/modules/profile/controllers/profile_controller.dart index a75f87ee9..083d9b9e4 100644 --- a/lib/modules/profile/controllers/profile_controller.dart +++ b/lib/modules/profile/controllers/profile_controller.dart @@ -2,38 +2,41 @@ import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; +import 'package:logger/logger.dart'; import '../../../data/models/user_model.dart'; import '../../settings/controllers/settings_controller.dart'; +import 'dart:io'; +import 'package:flutter_image_compress/flutter_image_compress.dart'; class ProfileController extends GetxController { static ProfileController get to => Get.find(); - + // final _userName = ''.obs; // final _email = ''.obs; // final _avatar = ''.obs; // final _isEditing = false.obs; // final _storage = GetStorage(); //用户信息 - static const String userKey='user_info'; - final _storage=GetStorage(); - final ImagePicker _picker=ImagePicker(); - final Rx userInfo=UserModel.defaultUser().obs; - + static const String userKey = 'user_info'; + final _storage = GetStorage(); + final ImagePicker _picker = ImagePicker(); + final Rx userInfo = UserModel.defaultUser().obs; + // 使用响应式变量 final currentLanguage = 'zh'.obs; - + // String get userName => _userName.value; // String get email => _email.value; // String get avatar => _avatar.value; // bool get isEditing => _isEditing.value; - + @override void onInit() { super.onInit(); loadUserInfo(); loadLanguagePreference(); } - + // void loadUserData() { // try { // _userName.value = _storage.read('userName') ?? 'User Name'; @@ -43,13 +46,13 @@ class ProfileController extends GetxController { // Get.snackbar('Error', 'Failed to load user data'); // } // } - + // 加载用户语言偏好设置 void loadLanguagePreference() { try { final String? languageCode = _storage.read('languageCode'); final String? countryCode = _storage.read('countryCode'); - + if (languageCode != null && countryCode != null) { Get.updateLocale(Locale(languageCode, countryCode)); currentLanguage.value = languageCode; @@ -58,7 +61,7 @@ class ProfileController extends GetxController { print('Failed to load language preference: $e'); } } - + // 保存用户语言偏好设置 Future saveLanguagePreference(Locale locale) async { try { @@ -68,7 +71,7 @@ class ProfileController extends GetxController { print('Failed to save language preference: $e'); } } - + // 切换应用语言 void changeLanguage(String languageCode, String countryCode) { // 使用Future.delayed来避免在构建过程中更新UI @@ -79,7 +82,7 @@ class ProfileController extends GetxController { currentLanguage.value = languageCode; }); } - + // Future updateUserData({ // String? userName, // String? email, @@ -103,12 +106,12 @@ class ProfileController extends GetxController { // Get.snackbar('Error', 'Failed to update profile'); // } // } - + // void toggleEditing() { // _isEditing.value = !_isEditing.value; // } - void loadUserInfo() { + void loadUserInfo() { final userJson = _storage.read(userKey); if (userJson != null) { userInfo.value = UserModel.fromJson(userJson); @@ -126,8 +129,34 @@ class ProfileController extends GetxController { maxHeight: 800, imageQuality: 85, ); - + if (image != null) { + // 检查文件大小 + final file = File(image.path); + var fileSize = await file.length(); + var quality = 85; + + // 如果文件大于1MB,进行压缩 + while (fileSize > 1024 * 1024 && quality > 30) { + final compressedImage = await FlutterImageCompress.compressAndGetFile( + file.absolute.path, + file.absolute.path, // 覆盖原文件 + quality: quality, + minWidth: 800, + minHeight: 800, + ); + + if (compressedImage == null) { + Get.snackbar('错误', '图片压缩失败'); + return; + } + + //更新文件大小和质量 + fileSize = await compressedImage.length(); + quality -= 5; + Logger().d('压缩后文件大小:$fileSize'); + } + userInfo.update((user) { if (user != null) { user.avatar = image.path; @@ -143,12 +172,19 @@ class ProfileController extends GetxController { } Future updateUserName(String name) async { - if (name.trim().isNotEmpty) { + if (name.trim().isEmpty) { + Logger().e('Invalid name: $name'); + return; + } + + try { userInfo.update((user) { if (user != null) { user.name = name.trim(); + Logger().d('Name updated to: ${user.name}'); } }); + await saveUserInfo(); // 同步更新 SettingsController @@ -156,6 +192,9 @@ class ProfileController extends GetxController { final settingsController = Get.find(); settingsController.loadUserInfo(); } + } catch (e) { + Logger().e('Error updating name: $e'); + Get.snackbar('Error', 'Failed to update user name'); } } -} \ No newline at end of file +} diff --git a/pubspec.yaml b/pubspec.yaml index ba0a93491..b91f3a678 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,6 +50,8 @@ dependencies: lottie: ^3.3.1 app_settings: 5.2.0 speech_to_text: ^7.0.0 + flutter_image_compress: ^2.4.0 + # image_cropper: ^9.0.0 dev_dependencies: flutter_test: From 3e5e625ee10aa8c0647e95b65935e3215fc04075 Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Fri, 21 Mar 2025 11:38:59 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E5=90=8D=E7=A7=B0=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/core/translations/language/en_us.dart | 2 +- lib/core/translations/language/zh_cn.dart | 2 +- lib/data/models/user_model.dart | 2 +- lib/modules/explore/views/explore_view.dart | 2 +- lib/modules/home/views/home_view.dart | 2 +- lib/modules/login/views/login_view.dart | 2 +- lib/modules/pairing/views/pairing_view.dart | 2 +- lib/modules/settings/views/settings_view.dart | 6 +++--- lib/modules/splash/views/splash_view.dart | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/core/translations/language/en_us.dart b/lib/core/translations/language/en_us.dart index 72a8c0c35..848034b24 100644 --- a/lib/core/translations/language/en_us.dart +++ b/lib/core/translations/language/en_us.dart @@ -84,7 +84,7 @@ const Map enUS = { // 发现页 "searchAi": "Search AI features...", "exploreSlogan": "Smart Earbuds, Infinite Possibilities", - "exploreAi": "Explore AI features provided by DeepVoice", + "exploreAi": "Explore AI features provided by DeepSound", "aiFunction": "AI Features", "allRoundAssistant": "All-round Assistant", "allRoundAssistantInfo": "Helps solve various problems", diff --git a/lib/core/translations/language/zh_cn.dart b/lib/core/translations/language/zh_cn.dart index c1828d06c..6f46f6276 100644 --- a/lib/core/translations/language/zh_cn.dart +++ b/lib/core/translations/language/zh_cn.dart @@ -83,7 +83,7 @@ const Map zhCN = { // 发现页 "searchAi": "搜索AI功能...", "exploreSlogan": "智能耳机,无限可能", - "exploreAi": "探索DeepVoice提供的AI功能", + "exploreAi": "探索DeepSound提供的AI功能", "aiFunction": "AI功能", "allRoundAssistant": "全能助理", "allRoundAssistantInfo": "帮你解决各类问题", diff --git a/lib/data/models/user_model.dart b/lib/data/models/user_model.dart index 4334df54e..ff3c07de4 100644 --- a/lib/data/models/user_model.dart +++ b/lib/data/models/user_model.dart @@ -32,7 +32,7 @@ class UserModel { factory UserModel.defaultUser() => UserModel( name: '未设置昵称', avatar: '', - id: 'deepvoice_${DateTime.now().millisecondsSinceEpoch.toString()}', + id: 'DeepSound_${DateTime.now().millisecondsSinceEpoch.toString()}', //deviceName: '', membershipLevel: '普通会员', ); diff --git a/lib/modules/explore/views/explore_view.dart b/lib/modules/explore/views/explore_view.dart index 997f6f1f7..25101b6d3 100644 --- a/lib/modules/explore/views/explore_view.dart +++ b/lib/modules/explore/views/explore_view.dart @@ -205,7 +205,7 @@ class ExploreView extends GetView { ), SizedBox(height: 4.h), Text( - 'exploreAi'.tr, // 探索DeepVoice提供的AI功能 + 'exploreAi'.tr, // 探索DeepSound提供的AI功能 style: TextStyle( fontSize: 14.sp, color: Colors.white.withOpacity(0.8), diff --git a/lib/modules/home/views/home_view.dart b/lib/modules/home/views/home_view.dart index c3b646fae..93e4d5b9f 100644 --- a/lib/modules/home/views/home_view.dart +++ b/lib/modules/home/views/home_view.dart @@ -116,7 +116,7 @@ class HomeView extends GetView { mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( - 'DeepVoice', + 'DeepSound', style: TextStyle( fontSize: 20.sp, fontWeight: FontWeight.bold, diff --git a/lib/modules/login/views/login_view.dart b/lib/modules/login/views/login_view.dart index c827a1715..84ceff40b 100644 --- a/lib/modules/login/views/login_view.dart +++ b/lib/modules/login/views/login_view.dart @@ -131,7 +131,7 @@ class LoginView extends GetView { ), SizedBox(height: 16.h), Text( - 'DeepVoice', + 'DeepSound', style: TextStyle( fontSize: 24.sp, fontWeight: FontWeight.bold, diff --git a/lib/modules/pairing/views/pairing_view.dart b/lib/modules/pairing/views/pairing_view.dart index 97638299b..5775f379f 100644 --- a/lib/modules/pairing/views/pairing_view.dart +++ b/lib/modules/pairing/views/pairing_view.dart @@ -75,7 +75,7 @@ class PairingView extends GetView { return Column( children: [ Text( - 'DeepVoice', + 'DeepSound', style: TextStyle( fontSize: 30.sp, fontWeight: FontWeight.bold, diff --git a/lib/modules/settings/views/settings_view.dart b/lib/modules/settings/views/settings_view.dart index 1d5baf0b1..9b8a498e0 100644 --- a/lib/modules/settings/views/settings_view.dart +++ b/lib/modules/settings/views/settings_view.dart @@ -145,7 +145,7 @@ class SettingsView extends GetView { SizedBox(width: 8.w), Flexible( child: Text( - '${'joinDevice'.tr} DeepVoice Pro', // 已连接设备: + '${'joinDevice'.tr} DeepSound Pro', // 已连接设备: style: TextStyle( fontSize: 12.sp, color: @@ -485,7 +485,7 @@ class SettingsView extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - 'DeepVoice', + 'DeepSound', style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w500, @@ -532,7 +532,7 @@ class SettingsView extends GetView { child: Column( children: [ Text( - '© 2023 DeepVoice Technologies', + '© 2025 DeepSound Technologies', style: TextStyle( fontSize: 12.sp, color: isDarkMode ? Colors.grey[400] : Colors.grey[500], diff --git a/lib/modules/splash/views/splash_view.dart b/lib/modules/splash/views/splash_view.dart index fba98eedb..900c5af3e 100644 --- a/lib/modules/splash/views/splash_view.dart +++ b/lib/modules/splash/views/splash_view.dart @@ -105,7 +105,7 @@ class SplashView extends GetView { child: Padding( padding: EdgeInsets.only(top: 24.h), child: Text( - 'DeepVoice', + 'DeepSound', style: TextStyle( fontSize: 28.sp, fontWeight: FontWeight.bold,