Browse Source

将退出登录和注销账号功能从设置模块移至个人资料模块

newdev_shunjiawei
lxm 1 year ago
parent
commit
1df8e14445
  1. 79
      lib/modules/profile/controllers/profile_controller.dart
  2. 797
      lib/modules/profile/views/profile_view.dart
  3. 81
      lib/modules/settings/controllers/settings_controller.dart
  4. 293
      lib/modules/settings/views/settings_view.dart

79
lib/modules/profile/controllers/profile_controller.dart

@ -12,6 +12,9 @@ import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import '../../../data/services/network/api.dart'; import '../../../data/services/network/api.dart';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import '../../../routes/app_routes.dart';
import '../../../modules/login/controllers/googleLogin.dart';
import '../../../modules/login/controllers/facebookLogin.dart';
class ProfileController extends GetxController { class ProfileController extends GetxController {
static ProfileController get to => Get.find(); static ProfileController get to => Get.find();
@ -364,4 +367,80 @@ class ProfileController extends GetxController {
Get.snackbar('错误', '更新用户名和头像失败'); Get.snackbar('错误', '更新用户名和头像失败');
} }
} }
Future<void> signOut() async {
try {
//显示加载提示
// Get.dialog(
// const Center(child: CircularProgressIndicator()),
// barrierDismissible: false,
// );
// 清理所有存储
await _storage.erase();
// 或者逐个清理关键存储项
await _storage.write("logintoken", null);
await _storage.write("user_info", null);
await _storage.write("local_avatar", null);
print('清理存储成功');
// 第三方登录退出
try {
final google = Google();
final facebook = Facebook();
await Future.wait([
google.signOutGoogle(),
facebook.signOutFacebook(),
]);
} catch (e) {
print('第三方登录退出错误: $e');
// 继续执行,不中断退出流程
}
// 关闭加载提示
//Get.back();
// 确保导航到登录页面
if (Get.currentRoute != Routes.login) {
await Get.offAllNamed(Routes.login);
}
Get.snackbar('成功', '已退出登录');
print('退出登录成功');
} catch (e) {
//Get.back(); // 关闭加载提示
Get.snackbar('错误', '退出登录失败,请重试');
print('退出登录错误: $e');
}
}
// 注销账号
Future<void> deleteAccount() async {
try {
// 显示加载提示
Get.dialog(
const Center(child: CircularProgressIndicator()),
barrierDismissible: false,
);
// 删除后台用户数据
final responce = await Api.deleteUser();
if (responce == null) {
Get.back(); // 关闭加载提示
Get.snackbar('错误', '删除用户数据失败');
return;
}
// 关闭加载提示
Get.back();
signOut(); // 调用 signOut 方法
Get.snackbar('Success', 'Account has been permanently deleted');
Logger().d('账号删除成功');
} catch (e) {
Get.back(); // 关闭加载提示
Get.snackbar('错误', '删除账号失败,请重试');
Logger().d('账号删除失败: $e');
}
}
} }

797
lib/modules/profile/views/profile_view.dart

@ -5,6 +5,8 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../../core/widgets/common_bottom_nav.dart'; import '../../../core/widgets/common_bottom_nav.dart';
import '../../../routes/app_routes.dart'; import '../../../routes/app_routes.dart';
import 'dart:io'; import 'dart:io';
import 'dart:ui';
import '../../common/webview_page.dart';
// ProfileView: 用户设置页面 // ProfileView: 用户设置页面
class ProfileView extends GetView<ProfileController> { class ProfileView extends GetView<ProfileController> {
@ -143,6 +145,7 @@ class EditProfileView extends GetView<ProfileController> {
TextEditingController(text: controller.userInfo.value.name); TextEditingController(text: controller.userInfo.value.name);
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: false, // 添加这一行,防止键盘挤压内容
appBar: AppBar( appBar: AppBar(
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
centerTitle: true, centerTitle: true,
@ -156,107 +159,729 @@ class EditProfileView extends GetView<ProfileController> {
), ),
onPressed: () => Get.back(), onPressed: () => Get.back(),
), ),
title: Text( // title: Text(
'editProfile'.tr, // 'editProfile'.tr,
style: TextStyle( // style: TextStyle(
fontSize: 17.sp, // fontSize: 17.sp,
fontWeight: FontWeight.w600, // fontWeight: FontWeight.w600,
color: isDarkMode ? Colors.white : Colors.black, // color: isDarkMode ? Colors.white : Colors.black,
// ),
// ),
actions: [
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(
body: Padding( decoration: BoxDecoration(
padding: EdgeInsets.all(16.w), color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white,
child: Column( borderRadius: BorderRadius.circular(16.r),
children: [ boxShadow: [
// 头像编辑 BoxShadow(
Center( color: isDarkMode
child: GestureDetector( ? Colors.black.withOpacity(0.2)
onTap: () => controller.updateUserAvatar(), : Colors.black.withOpacity(0.05),
child: Stack( blurRadius: 10,
children: [ offset: const Offset(0, 2),
Obx(() => CircleAvatar( ),
radius: 50.r, ],
backgroundImage: controller.localAvatar.value.isNotEmpty ),
? FileImage(File(controller.localAvatar.value)) child: ClipRRect(
: (controller.userInfo.value.avatar.isNotEmpty borderRadius: BorderRadius.circular(16.r),
? NetworkImage( child: BackdropFilter(
controller.userInfo.value.avatar) // 保留毛玻璃效果(如果需要)
: null) as ImageProvider<Object>?, filter: isDarkMode
child: controller.userInfo.value.avatar.isEmpty ? ImageFilter.blur(sigmaX: 5, sigmaY: 5)
? Icon(Icons.person, size: 50.r) : ImageFilter.blur(sigmaX: 0, sigmaY: 0),
: null, child: Column(
)), children: [
Positioned( // 头像设置项
right: 0, _buildAvatarSetting(isDarkMode),
bottom: 0, Divider(
child: Container( height: 1,
padding: EdgeInsets.all(4.w), color: isDarkMode
decoration: const BoxDecoration( ? Colors.white.withOpacity(0.1)
color: Colors.blue, : Colors.grey[200]),
shape: BoxShape.circle, // 昵称设置项
), _buildNicknameSetting(context, isDarkMode, nameController),
child: Icon( ],
Icons.camera_alt, ),
size: 20.w,
color: Colors.white,
)),
)
],
)),
), ),
SizedBox(height: 20.h), ),
),
],
);
}
// 昵称编辑 - 使用外部定义的controller而不是每次重建 // 新增:构建头像设置项
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( Row(
children: [ children: [
Expanded( Obx(() => CircleAvatar(
child: TextField( radius: 30.r, // 调整头像大小以适应行高
controller: nameController, backgroundImage: controller.localAvatar.value.isNotEmpty
decoration: InputDecoration( ? FileImage(File(controller.localAvatar.value))
labelText: 'nickname'.tr, : (controller.userInfo.value.avatar.isNotEmpty
border: const OutlineInputBorder(), ? NetworkImage(controller.userInfo.value.avatar)
suffixIcon: nameController.text.isNotEmpty : null) as ImageProvider<Object>?,
? IconButton( child: (controller.localAvatar.value.isEmpty &&
icon: const Icon(Icons.clear), controller.userInfo.value.avatar.isEmpty)
onPressed: () { ? Icon(Icons.person,
nameController.clear(); size: 20.r, color: Colors.grey) // 默认图标
},
)
: null, : 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],
), ),
), ),
], ],
), ),
// ... 其他编辑项 ... // --- ---
],
),
),
);
}
SizedBox(height: 30.h), // 新增:构建昵称设置项
// 添加一个大的保存按钮 Widget _buildNicknameSetting(BuildContext context, bool isDarkMode,
SizedBox( TextEditingController nameController) {
width: double.infinity, return InkWell(
height: 50.h, onTap: () => _showEditNicknameDialog(context, isDarkMode, nameController),
child: ElevatedButton( child: Padding(
onPressed: () { padding:
// 保存用户名 EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), // 调整垂直间距
controller.updateUserNameAndAvatar(nameController.text); child: Row(
// 返回上一级页面 // mainAxisAlignment: MainAxisAlignment.spaceBetween, // 移除
Get.back(); children: [
}, // --- 添加图标 ---
style: ElevatedButton.styleFrom( Container(
backgroundColor: isDarkMode ? Colors.blue[700] : Colors.blue, width: 32.w,
shape: RoundedRectangleBorder( height: 32.w,
borderRadius: BorderRadius.circular(10.r), 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,
), ),
child: Text( ),
'save'.tr, ),
style: TextStyle( // --- 右侧内容保持不变 ---
fontSize: 16.sp, Row(
color: Colors.white, children: [
fontWeight: FontWeight.w500, // 使用 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;
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<Object>?,
// 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?.toString() != 'zh_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?.toString() != 'zh_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],
), ),
), ),
], ],

81
lib/modules/settings/controllers/settings_controller.dart

@ -8,13 +8,10 @@ import '../../../data/services/speech_factory.dart';
import '../models/language_model.dart'; import '../models/language_model.dart';
import 'package:logger/logger.dart'; import 'package:logger/logger.dart';
import '../../../data/models/user_Info.dart'; import '../../../data/models/user_Info.dart';
import '../../../modules/login/controllers/googleLogin.dart';
import '../../../modules/login/controllers/facebookLogin.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'dart:io'; import 'dart:io';
import '../../../routes/app_routes.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import '../../../data/services/network/api.dart';
class SettingsController extends GetxController { class SettingsController extends GetxController {
// 语言设置 // 语言设置
@ -327,80 +324,4 @@ class SettingsController extends GetxController {
sourceLanguage.value = targetLanguage.value; sourceLanguage.value = targetLanguage.value;
targetLanguage.value = temp; targetLanguage.value = temp;
} }
Future<void> signOut() async {
try {
//显示加载提示
// Get.dialog(
// const Center(child: CircularProgressIndicator()),
// barrierDismissible: false,
// );
// 清理所有存储
await _storage.erase();
// 或者逐个清理关键存储项
await _storage.write("logintoken", null);
await _storage.write("user_info", null);
await _storage.write("local_avatar", null);
print('清理存储成功');
// 第三方登录退出
try {
final google = Google();
final facebook = Facebook();
await Future.wait([
google.signOutGoogle(),
facebook.signOutFacebook(),
]);
} catch (e) {
print('第三方登录退出错误: $e');
// 继续执行,不中断退出流程
}
// 关闭加载提示
//Get.back();
// 确保导航到登录页面
if (Get.currentRoute != Routes.login) {
await Get.offAllNamed(Routes.login);
}
Get.snackbar('成功', '已退出登录');
print('退出登录成功');
} catch (e) {
//Get.back(); // 关闭加载提示
Get.snackbar('错误', '退出登录失败,请重试');
print('退出登录错误: $e');
}
}
// 注销账号
Future<void> deleteAccount() async {
try {
// 显示加载提示
Get.dialog(
const Center(child: CircularProgressIndicator()),
barrierDismissible: false,
);
// 删除后台用户数据
final responce = await Api.deleteUser();
if (responce == null) {
Get.back(); // 关闭加载提示
Get.snackbar('错误', '删除用户数据失败');
return;
}
// 关闭加载提示
Get.back();
signOut(); // 调用 signOut 方法
Get.snackbar('Success', 'Account has been permanently deleted');
Logger().d('账号删除成功');
} catch (e) {
Get.back(); // 关闭加载提示
Get.snackbar('错误', '删除账号失败,请重试');
Logger().d('账号删除失败: $e');
}
}
} }

293
lib/modules/settings/views/settings_view.dart

@ -59,7 +59,9 @@ class SettingsView extends GetView<SettingsController> {
// 用户信息卡片 // 用户信息卡片
Widget _buildUserInfoCard(bool isDarkMode) { Widget _buildUserInfoCard(bool isDarkMode) {
return Container( return GestureDetector(
onTap: () => Get.toNamed(Routes.editProfile),
child: Container(
padding: EdgeInsets.all(16.w), padding: EdgeInsets.all(16.w),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
@ -113,10 +115,6 @@ class SettingsView extends GetView<SettingsController> {
borderRadius: BorderRadius.circular(30.r), borderRadius: BorderRadius.circular(30.r),
child: controller.userInfo.value.avatar.isEmpty 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, // 图片填充方式
// )
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
color: Colors.blue[600], color: Colors.blue[600],
@ -124,7 +122,8 @@ class SettingsView extends GetView<SettingsController> {
), ),
child: Center( child: Center(
child: Text( child: Text(
controller.userInfo.value.name.isNotEmpty controller
.userInfo.value.name.isNotEmpty
? controller.userInfo.value.name[0] ? controller.userInfo.value.name[0]
.toUpperCase() .toUpperCase()
: '?', : '?',
@ -200,7 +199,8 @@ class SettingsView extends GetView<SettingsController> {
1: 'standardUser', //'标准用户' 1: 'standardUser', //'标准用户'
2: 'proUser', //'专业用户' 2: 'proUser', //'专业用户'
}; };
final membershipString = membershipMap[controller final membershipString = membershipMap[
controller
.userInfo.value.membershipLevel] ?? .userInfo.value.membershipLevel] ??
'Unknown'; 'Unknown';
return Text( return Text(
@ -212,24 +212,24 @@ class SettingsView extends GetView<SettingsController> {
); );
}), }),
), ),
SizedBox(width: 8.w), // SizedBox(width: 8.w),
Flexible( // Flexible(
child: Text( // child: Text(
'${'joinDevice'.tr} DeepSound Pro', // 已连接设备: // '${'joinDevice'.tr} DeepSound Pro', // 已连接设备:
style: TextStyle( // style: TextStyle(
fontSize: 12.sp, // fontSize: 12.sp,
color: isDarkMode // color: isDarkMode
? Colors.white70 // ? Colors.white70
: Colors.black54, // : Colors.black54,
), // ),
overflow: TextOverflow.ellipsis, // overflow: TextOverflow.ellipsis,
), // ),
), // ),
], ],
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Text( Text(
controller.userInfo.value.uid, 'ID:${controller.userInfo.value.uid}',
style: TextStyle( style: TextStyle(
fontSize: 12.sp, fontSize: 12.sp,
color: isDarkMode ? Colors.white70 : Colors.black54, color: isDarkMode ? Colors.white70 : Colors.black54,
@ -265,6 +265,7 @@ class SettingsView extends GetView<SettingsController> {
), ),
)), )),
], ],
),
), ),
), ),
), ),
@ -566,133 +567,133 @@ class SettingsView extends GetView<SettingsController> {
: Colors.grey[200]), : Colors.grey[200]),
// 退出登录 // 退出登录
_buildSimpleNavigationSetting( // _buildSimpleNavigationSetting(
title: 'logout'.tr, // 退出登录 // title: 'logout'.tr, // 退出登录
icon: Icons.logout, // icon: Icons.logout,
iconBgColor: isDarkMode // iconBgColor: isDarkMode
? Colors.red[900]!.withOpacity(0.3) // ? Colors.red[900]!.withOpacity(0.3)
: Colors.red[50]!, // : Colors.red[50]!,
iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, // iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!,
titleColor: // titleColor:
isDarkMode ? Colors.red[300]! : Colors.red[600]!, // isDarkMode ? Colors.red[300]! : Colors.red[600]!,
onTap: () { // onTap: () {
// 退出登录确认对话框 // // 退出登录确认对话框
Get.dialog( // Get.dialog(
AlertDialog( // AlertDialog(
backgroundColor: // backgroundColor:
isDarkMode ? Colors.grey[900] : Colors.white, // isDarkMode ? Colors.grey[900] : Colors.white,
title: Text( // title: Text(
'logout'.tr, // 退出登录 // 'logout'.tr, // 退出登录
style: TextStyle( // style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87, // color: isDarkMode ? Colors.white : Colors.black87,
), // ),
), // ),
content: Text( // content: Text(
'logoutTips'.tr, // 确定要退出当前账号吗? // 'logoutTips'.tr, // 确定要退出当前账号吗?
style: TextStyle( // style: TextStyle(
color: // color:
isDarkMode ? Colors.white70 : Colors.black54, // isDarkMode ? Colors.white70 : Colors.black54,
), // ),
), // ),
actions: [ // actions: [
TextButton( // TextButton(
onPressed: () => Get.back(), // onPressed: () => Get.back(),
child: Text( // child: Text(
'cancel'.tr, // 取消 // 'cancel'.tr, // 取消
style: TextStyle( // style: TextStyle(
color: isDarkMode // color: isDarkMode
? Colors.white70 // ? Colors.white70
: Colors.black54, // : Colors.black54,
), // ),
), // ),
), // ),
TextButton( // TextButton(
onPressed: () { // onPressed: () {
Get.back(); // Get.back();
controller.signOut(); // controller.signOut();
}, // },
child: Text( // child: Text(
'confirm'.tr, // 确定 // 'confirm'.tr, // 确定
style: TextStyle( // style: TextStyle(
color: isDarkMode // color: isDarkMode
? Colors.red[300] // ? Colors.red[300]
: Colors.red[600], // : Colors.red[600],
), // ),
), // ),
), // ),
], // ],
), // ),
); // );
}, // },
isDarkMode: isDarkMode, // isDarkMode: isDarkMode,
), // ),
Divider( // Divider(
height: 1, // height: 1,
color: isDarkMode // color: isDarkMode
? Colors.white.withOpacity(0.1) // ? Colors.white.withOpacity(0.1)
: Colors.grey[200]), // : Colors.grey[200]),
// 注销账号 // 注销账号
_buildSimpleNavigationSetting( // _buildSimpleNavigationSetting(
title: 'deleteAccount'.tr, // 注销账号 // title: 'deleteAccount'.tr, // 注销账号
icon: Icons.delete_forever, // icon: Icons.delete_forever,
iconBgColor: isDarkMode // iconBgColor: isDarkMode
? Colors.red[900]!.withOpacity(0.3) // ? Colors.red[900]!.withOpacity(0.3)
: Colors.red[50]!, // : Colors.red[50]!,
iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!, // iconColor: isDarkMode ? Colors.red[300]! : Colors.red[600]!,
titleColor: // titleColor:
isDarkMode ? Colors.red[300]! : Colors.red[600]!, // isDarkMode ? Colors.red[300]! : Colors.red[600]!,
onTap: () { // onTap: () {
// 注销账号确认对话框 // // 注销账号确认对话框
Get.dialog( // Get.dialog(
AlertDialog( // AlertDialog(
backgroundColor: // backgroundColor:
isDarkMode ? Colors.grey[900] : Colors.white, // isDarkMode ? Colors.grey[900] : Colors.white,
title: Text( // title: Text(
'deleteAccount'.tr, // 注销账号 // 'deleteAccount'.tr, // 注销账号
style: TextStyle( // style: TextStyle(
color: isDarkMode ? Colors.white : Colors.black87, // color: isDarkMode ? Colors.white : Colors.black87,
), // ),
), // ),
content: Text( // content: Text(
'deleteAccountTips'.tr, // 确定要永久删除您的账号吗?此操作不可撤销 // 'deleteAccountTips'.tr, // 确定要永久删除您的账号吗?此操作不可撤销
style: TextStyle( // style: TextStyle(
color: // color:
isDarkMode ? Colors.white70 : Colors.black54, // isDarkMode ? Colors.white70 : Colors.black54,
), // ),
), // ),
actions: [ // actions: [
TextButton( // TextButton(
onPressed: () => Get.back(), // onPressed: () => Get.back(),
child: Text( // child: Text(
'cancel'.tr, // 取消 // 'cancel'.tr, // 取消
style: TextStyle( // style: TextStyle(
color: isDarkMode // color: isDarkMode
? Colors.white70 // ? Colors.white70
: Colors.black54, // : Colors.black54,
), // ),
), // ),
), // ),
TextButton( // TextButton(
onPressed: () { // onPressed: () {
Get.back(); // Get.back();
controller.deleteAccount(); // controller.deleteAccount();
}, // },
child: Text( // child: Text(
'confirm'.tr, // 确定 // 'confirm'.tr, // 确定
style: TextStyle( // style: TextStyle(
color: isDarkMode // color: isDarkMode
? Colors.red[300] // ? Colors.red[300]
: Colors.red[600], // : Colors.red[600],
), // ),
), // ),
), // ),
], // ],
), // ),
); // );
}, // },
isDarkMode: isDarkMode, // isDarkMode: isDarkMode,
), // ),
], ],
), ),
), ),

Loading…
Cancel
Save