You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

446 lines
14 KiB

import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter/material.dart';
//import 'package:http/http.dart';
import 'package:image_picker/image_picker.dart';
import 'package:logger/logger.dart';
import '../../../data/models/user_Info.dart';
import '../../settings/controllers/settings_controller.dart';
import 'dart:io';
import 'dart:convert';
import 'package:flutter_image_compress/flutter_image_compress.dart';
import 'package:path_provider/path_provider.dart';
import '../../../data/services/network/api.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 {
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<User> userInfo = User.instance.obs; // 响应式用户信息对象,使用单例模式确保全局唯一性
final RxString localAvatar = ''.obs; // 本地头像路径,便于响应式更新UI
// 使用响应式变量
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';
// _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() {
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;
}
} catch (e) {
print('Failed to load language preference: $e');
}
}
// 保存用户语言偏好设置
Future<void> saveLanguagePreference(Locale locale) async {
try {
await _storage.write('languageCode', locale.languageCode);
await _storage.write('countryCode', locale.countryCode);
} catch (e) {
print('Failed to save language preference: $e');
}
}
// 切换应用语言
void changeLanguage(String languageCode, String countryCode) {
// 使用Future.delayed来避免在构建过程中更新UI
Future.delayed(Duration.zero, () async {
final locale = Locale(languageCode, countryCode);
await saveLanguagePreference(locale);
Get.updateLocale(locale);
currentLanguage.value = languageCode;
});
}
// Future<void> 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;
// }
// 验证base64图片数据
// Future<void> _verifyBase64Image(String base64String) async {
// try {
// // 解码base64数据
// List<int> imageBytes = base64Decode(base64String);
// // 获取应用文档目录
// final appDir = await getApplicationDocumentsDirectory();
// final verifyPath = '${appDir.path}/verify_base64_${DateTime.now().millisecondsSinceEpoch}.jpg';
// // 将解码后的数据写入文件
// final file = File(verifyPath);
// await file.writeAsBytes(imageBytes);
// // 记录验证文件的路径
// Logger().d('Base64验证图片已保存到: $verifyPath');
// // 显示图片预览对话框
// Get.dialog(
// Dialog(
// child: Column(
// mainAxisSize: MainAxisSize.min,
// children: [
// Padding(
// padding: const EdgeInsets.all(16.0),
// child: Text('Base64 图片验证', style: TextStyle(fontWeight: FontWeight.bold)),
// ),
// Image.file(File(verifyPath)),
// Padding(
// padding: const EdgeInsets.all(16.0),
// child: ElevatedButton(
// onPressed: () => Get.back(),
// child: Text('关闭'),
// ),
// ),
// ],
// ),
// ),
// );
// Get.snackbar('验证', '已将Base64转换回图片,请查看预览');
// } catch (e) {
// Logger().e('验证Base64图片失败: $e');
// Get.snackbar('错误', 'Base64验证失败: $e');
// }
// }
// 更新用户信息到后端
Future<void> _syncWithBackend() async {
try {
// 准备数据
Map<String, dynamic> data = {
"image": "", // 默认空字符串
"language": currentLanguage.value, //当前用户语言
"name": userInfo.value.name, //当前用户名
};
// 如果有头像,转换为base64
if (localAvatar.value.isNotEmpty) {
//如果本地头像路径不为空,即代表有头像
try {
File imageFile = File(localAvatar.value);
if (await imageFile.exists()) {
List<int> imageBytes = await imageFile.readAsBytes();
String base64Image = base64Encode(imageBytes);
data["image"] = base64Image;
// // 验证base64数据 - 将base64转回图片并保存到本地
// await _verifyBase64Image(base64Image);
} else {
Logger().e('头像文件不存在');
}
} catch (e) {
Logger().e('读取头像文件失败: $e');
}
}
Logger().d('准备更新用户信息: $data');
// 调用API
final response = await Api.updateUserSetting(data);
Logger().d('--更新用户信息响应: $response');
if (response != null) {
Logger().d('更新成功: $response');
Get.snackbar('成功', '同步到服务器成功');
userInfo.update((u) {
if (u != null) {
u.name = response['name'] ?? '';
u.avatar = response['avatar'] ?? '';
}
});
Logger().d('更新后的用户信息: ${userInfo.value.toJson()}');
} else {
Logger().e('更新失败: $response');
Get.snackbar('错误', '同步到服务器失败,请重试');
return;
}
} catch (e) {
Logger().e('同步到后端失败: $e');
Get.snackbar('Error', '同步到服务器失败,请重试');
throw e;
}
}
void loadUserInfo() {
final userJson = _storage.read(userKey);
if (userJson != null) {
userInfo.value = User.instance;
Logger().d('从本地加载用户信息: $userJson');
// 如果有远程头像地址,下载并保存到本地
if (userInfo.value.avatar.isNotEmpty) {
Logger().d('远程头像地址: ${userInfo.value.avatar}');
_downloadAndSaveAvatar(userInfo.value.avatar);
}
}
}
// 下载并保存远程头像
Future<void> _downloadAndSaveAvatar(String url) async {
try {
Logger().d('开始下载头像: $url');
final dio = Dio(BaseOptions(
headers: {
'accept': '*/*',
'Authorization': _storage.read<String>("logintoken"),
},
));
final response = await dio.get(
url,
options: Options(responseType: ResponseType.bytes),
);
Logger().d('下载状态: ${response.statusCode}');
if (response.statusCode == 200) {
// 保存到应用文档目录
final appDir = await getApplicationDocumentsDirectory();
final fileName = 'avatar_${DateTime.now().millisecondsSinceEpoch}.jpg';
final localPath = '${appDir.path}/$fileName';
// 写入文件
final file = File(localPath);
await file.writeAsBytes(response.data);
// 更新本地头像路径
localAvatar.value = localPath;
await _storage.write('local_avatar', localPath);
Logger().d('头像已下载到本地: $localPath');
//Get.snackbar('头像', '头像已下载到本地');
}
} catch (e) {
Logger().e('下载头像失败: $e');
}
}
Future<void> saveUserInfo() async {
await _storage.write(userKey, userInfo.value.toJson());
}
// 更新用户头像
Future<void> updateUserAvatar() async {
final XFile? image = await _picker.pickImage(
source: ImageSource.gallery, // 从相册选择
maxWidth: 800,
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;
}
});
// 更新本地头像路径
localAvatar.value = image.path;
await _storage.write('local_avatar', image.path);
// await saveUserInfo(); //保存到本地
//await _syncWithBackend(); //同步到后端
// 通知 SettingsController 更新
// if (Get.isRegistered<SettingsController>()) {
// Get.find<SettingsController>().loadUserInfo();
// }
}
}
// 更新用户名
Future<void> updateUserNameAndAvatar(String name) async {
if (name.trim().isEmpty) {
Logger().e('无效名称: $name');
return;
}
try {
userInfo.update((user) {
if (user != null) {
user.name = name.trim();
Logger().d('名称更新为: ${user.name}');
}
});
//await saveUserInfo(); //保存到本地
await _syncWithBackend(); //同步到后端
//同步更新 SettingsController
if (Get.isRegistered<SettingsController>()) {
final settingsController = Get.find<SettingsController>();
settingsController.userInfo.value.name = userInfo.value.name;
settingsController.userInfo.value.avatar =
'${userInfo.value.avatar}?time=${DateTime.now().millisecondsSinceEpoch}';
//settingsController.loadUserInfo();
settingsController.userInfo.refresh();
}
} catch (e) {
Logger().e('更新用户名和头像错误: $e');
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');
}
}
}