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.
 
 
 
 
 

555 lines
18 KiB

import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:im_flutter_sdk/im_flutter_sdk.dart';
import '../../im/im_manager.dart';
import '../../model/home/marriage_data.dart';
import '../../pages/home/report_page.dart';
import '../../pages/home/user_information_page.dart';
import '../message/conversation_controller.dart';
class ChatSettingsController extends GetxController {
final String userId;
final MarriageData? userData;
final _storage = GetStorage();
// 用户信息
final Rx<EMUserInfo?> userInfo = Rx<EMUserInfo?>(null);
// 用户miId(用于跳转到用户主页)
String? miId;
// 是否拉黑
final RxBool isBlacklisted = RxBool(false);
// 是否关注
final RxBool isFollowing = RxBool(false);
// 备注名
final RxString remark = RxString('');
ChatSettingsController({
required this.userId,
this.userData,
});
@override
void onInit() {
super.onInit();
try {
// 验证 userId
if (userId.isEmpty) {
print('❌ [ChatSettings] userId 为空');
return;
}
// 如果传入了用户信息,优先使用(同步操作,安全)
if (userData != null) {
try {
miId = userData!.miId;
} catch (e) {
print('❌ [ChatSettings] 设置 miId 失败: $e');
}
}
// 加载备注名(同步,立即执行,安全)
try {
loadRemark();
} catch (e) {
print('❌ [ChatSettings] 加载备注名失败: $e');
}
// 延迟执行异步操作,避免阻塞 UI
Future.microtask(() {
try {
// 如果传入了用户信息,同步到缓存
if (userData != null) {
_syncUserDataToCache();
}
// 初始化时获取用户信息(异步,不阻塞)
fetchUserInfo();
// 检查黑名单状态(异步,不阻塞)
checkBlacklistStatus();
// 检查关注状态(异步,不阻塞)
checkFollowStatus();
} catch (e, stackTrace) {
print('❌ [ChatSettings] 异步初始化失败: $e');
print('堆栈跟踪: $stackTrace');
}
});
} catch (e, stackTrace) {
print('❌ [ChatSettings] onInit 失败: $e');
print('堆栈跟踪: $stackTrace');
}
}
/// 将传入的用户信息同步到 ConversationController 缓存
void _syncUserDataToCache() {
try {
if (userData == null) return;
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final extendedInfo = ExtendedUserInfo(
userId: userId,
nickName: userData!.nickName,
avatarUrl: userData!.profilePhoto.trim().replaceAll('`', ''),
);
conversationController.cacheUserInfo(userId, extendedInfo);
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 已同步用户信息到缓存: nickName=${userData!.nickName}');
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 获取 ConversationController 失败: $e');
}
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 同步用户信息到缓存失败: $e');
}
}
}
/// 获取用户信息
Future<void> fetchUserInfo() async {
try {
// 0. 如果传入了用户信息,优先使用(已在 onInit 中处理)
if (userData != null) {
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 使用传入的用户信息: nickName=${userData!.nickName}, miId=${userData!.miId}');
}
// 仍然尝试从IM获取,以便更新 userInfo.value
}
// 1. 优先从ConversationController的缓存中获取用户信息
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final cachedUserInfo = conversationController.getCachedUserInfo(userId);
if (cachedUserInfo != null && (cachedUserInfo.nickName != null || cachedUserInfo.avatarUrl != null)) {
// 使用缓存中的用户信息创建 EMUserInfo
// 注意:EMUserInfo 可能没有公开构造函数,所以我们先尝试从IM获取
// 如果IM没有,我们使用缓存的信息来显示
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 从缓存获取到用户信息: userId=$userId, nickName=${cachedUserInfo.nickName}');
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 获取 ConversationController 失败: $e');
}
}
}
// 2. 尝试从IM获取用户信息
EMUserInfo? info;
try {
info = await IMManager.instance.getUserInfo(userId);
if (info != null && (info.nickName?.isNotEmpty ?? false)) {
userInfo.value = info;
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 从IM获取到用户信息: ${info.nickName}');
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 从IM获取用户信息失败: $e');
}
}
// 3. 如果IM没有用户信息,尝试从会话历史消息中提取
if (userInfo.value == null || (userInfo.value?.nickName?.isEmpty ?? true)) {
await _fetchUserInfoFromConversation();
}
// 4. 尝试从会话历史消息中获取miId
await _tryGetMiIdFromConversation();
} catch (e) {
if (Get.isLogEnable) {
Get.log('❌ [ChatSettings] 获取用户信息失败: $e');
}
}
}
/// 从会话历史消息中提取用户信息
Future<void> _fetchUserInfoFromConversation() async {
try {
final conversation = await EMClient.getInstance.chatManager.getConversation(
userId,
type: EMConversationType.Chat,
createIfNeed: false,
);
if (conversation == null) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 会话不存在: $userId');
}
return;
}
final messages = await conversation.loadMessages(loadCount: 20);
for (var message in messages) {
try {
final attributes = message.attributes;
if (attributes == null || attributes.isEmpty) {
continue;
}
String? nickName;
String? avatarUrl;
if (message.direction == MessageDirection.RECEIVE) {
// 接收到的消息:从扩展字段中提取发送者信息(sender_ 前缀)
final fromUserId = message.from;
if (fromUserId != null && fromUserId == userId) {
nickName = attributes['sender_nickName'] as String? ?? attributes['nickName'] as String?;
avatarUrl = attributes['sender_avatarUrl'] as String? ?? attributes['avatarUrl'] as String?;
}
} else if (message.direction == MessageDirection.SEND) {
// 发送的消息:从扩展字段中提取接收者信息(receiver_ 前缀)
final toUserId = message.to;
if (toUserId != null && toUserId == userId) {
nickName = attributes['receiver_nickName'] as String?;
avatarUrl = attributes['receiver_avatarUrl'] as String?;
}
}
if (nickName != null || avatarUrl != null) {
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 从消息扩展字段提取到用户信息: nickName=$nickName, avatarUrl=$avatarUrl');
}
// 将提取到的用户信息保存到 ConversationController 的缓存中
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final extendedInfo = ExtendedUserInfo(
userId: userId,
nickName: nickName,
avatarUrl: avatarUrl,
);
conversationController.cacheUserInfo(userId, extendedInfo);
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 获取 ConversationController 失败: $e');
}
}
}
// 如果IM没有返回用户信息,尝试再次从IM获取(可能信息已更新)
if (userInfo.value == null || (userInfo.value?.nickName?.isEmpty ?? true)) {
try {
final imInfo = await IMManager.instance.getUserInfo(userId);
if (imInfo != null) {
userInfo.value = imInfo;
}
} catch (e) {
// 忽略错误,使用缓存的信息
}
}
break;
}
} catch (e) {
continue;
}
}
// 再次尝试从缓存获取
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final cachedUserInfo = conversationController.getCachedUserInfo(userId);
if (cachedUserInfo != null && userInfo.value == null) {
// 如果IM没有返回用户信息,但缓存中有,尝试再次从IM获取
// 或者直接使用缓存的信息(通过 getDisplayName 方法)
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 使用缓存中的用户信息: nickName=${cachedUserInfo.nickName}');
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('⚠️ [ChatSettings] 获取 ConversationController 失败: $e');
}
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('❌ [ChatSettings] 从会话提取用户信息失败: $e');
}
}
}
/// 尝试从会话历史消息中获取miId
Future<void> _tryGetMiIdFromConversation() async {
try {
final conversation = await EMClient.getInstance.chatManager.getConversation(
userId,
type: EMConversationType.Chat,
createIfNeed: false,
);
if (conversation != null) {
final messages = await conversation.loadMessages(loadCount: 20);
for (var message in messages) {
try {
final attributes = message.attributes;
if (attributes != null && attributes.isNotEmpty) {
// 尝试从消息扩展字段中获取miId
final msgMiId = attributes['sender_miId'] as String? ??
attributes['receiver_miId'] as String? ??
attributes['miId'] as String?;
if (msgMiId != null && msgMiId.isNotEmpty) {
miId = msgMiId;
if (Get.isLogEnable) {
Get.log('从消息扩展字段获取到miId: $miId');
}
break;
}
}
} catch (e) {
continue;
}
}
}
} catch (e) {
if (Get.isLogEnable) {
Get.log('从会话获取miId失败: $e');
}
}
}
/// 检查黑名单状态
Future<void> checkBlacklistStatus() async {
try {
// 从服务器获取黑名单列表
final blacklist = await IMManager.instance.getBlacklist();
isBlacklisted.value = blacklist.contains(userId);
} catch (e) {
if (Get.isLogEnable) {
Get.log('检查黑名单状态失败: $e');
}
isBlacklisted.value = false;
}
}
/// 检查关注状态
Future<void> checkFollowStatus() async {
try {
// TODO: 调用实际的API检查关注状态
// 这里暂时模拟
isFollowing.value = false;
} catch (e) {
if (Get.isLogEnable) {
Get.log('检查关注状态失败: $e');
}
}
}
/// 切换黑名单状态
Future<void> toggleBlacklist(bool value) async {
try {
if (value) {
// 加入黑名单
await IMManager.instance.addToBlacklist(userId);
isBlacklisted.value = true;
SmartDialog.showToast('已加入黑名单');
} else {
// 移出黑名单
await IMManager.instance.removeFromBlacklist(userId);
isBlacklisted.value = false;
SmartDialog.showToast('已移出黑名单');
}
update();
} catch (e) {
if (Get.isLogEnable) {
Get.log('操作黑名单失败: $e');
}
SmartDialog.showToast('操作失败,请重试');
}
}
/// 切换关注状态
Future<void> toggleFollow() async {
try {
if (isFollowing.value) {
// 取消关注
// TODO: 调用实际的取消关注API
isFollowing.value = false;
SmartDialog.showToast('已取消关注');
} else {
// 关注
// TODO: 调用实际的关注API
isFollowing.value = true;
SmartDialog.showToast('已关注');
}
update();
} catch (e) {
if (Get.isLogEnable) {
Get.log('操作关注失败: $e');
}
SmartDialog.showToast('操作失败,请重试');
}
}
/// 加载备注名
void loadRemark() {
final savedRemark = _storage.read<String>('remark_$userId');
if (savedRemark != null) {
remark.value = savedRemark;
}
}
/// 设置备注名
Future<void> setRemark(String newRemark) async {
try {
// 保存到本地存储
await _storage.write('remark_$userId', newRemark);
remark.value = newRemark;
SmartDialog.showToast('备注名设置成功');
update();
} catch (e) {
if (Get.isLogEnable) {
Get.log('设置备注名失败: $e');
}
SmartDialog.showToast('设置失败,请重试');
}
}
/// 获取显示名称(优先显示备注名,其次显示昵称)
String getDisplayName() {
try {
if (remark.value.isNotEmpty) {
return remark.value;
}
// 优先使用传入的用户信息
if (userData != null && userData!.nickName.isNotEmpty) {
return userData!.nickName;
}
// 其次使用 IM 返回的用户信息
if (userInfo.value != null && userInfo.value!.nickName != null && userInfo.value!.nickName!.isNotEmpty) {
return userInfo.value!.nickName!;
}
// 如果 IM 没有,尝试从 ConversationController 缓存中获取
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final cachedUserInfo = conversationController.getCachedUserInfo(userId);
if (cachedUserInfo != null && cachedUserInfo.nickName != null && cachedUserInfo.nickName!.isNotEmpty) {
return cachedUserInfo.nickName!;
}
} catch (e) {
// 忽略错误,使用默认值
}
}
return userId.isNotEmpty ? userId : '未知用户';
} catch (e) {
print('❌ [ChatSettings] getDisplayName 失败: $e');
return userId.isNotEmpty ? userId : '未知用户';
}
}
/// 获取用户头像URL
String? getAvatarUrl() {
try {
// 优先使用传入的用户信息
if (userData != null && userData!.profilePhoto.isNotEmpty) {
return userData!.profilePhoto.trim().replaceAll('`', '');
}
// 其次使用 IM 返回的用户信息
if (userInfo.value != null && userInfo.value!.avatarUrl != null && userInfo.value!.avatarUrl!.isNotEmpty) {
return userInfo.value!.avatarUrl!;
}
// 如果 IM 没有,尝试从 ConversationController 缓存中获取
if (Get.isRegistered<ConversationController>()) {
try {
final conversationController = Get.find<ConversationController>();
final cachedUserInfo = conversationController.getCachedUserInfo(userId);
if (cachedUserInfo != null && cachedUserInfo.avatarUrl != null && cachedUserInfo.avatarUrl!.isNotEmpty) {
return cachedUserInfo.avatarUrl!;
}
} catch (e) {
// 忽略错误,返回 null
}
}
return null;
} catch (e) {
print('❌ [ChatSettings] getAvatarUrl 失败: $e');
return null;
}
}
/// 举报用户
void reportUser() {
// 跳转到举报页面
Get.to(() => ReportPage(id: userId, userId: userId, type: 1,));
}
/// 跳转到用户主页
Future<void> navigateToUserProfile() async {
try {
String? targetMiId;
String targetUserId = userId;
// 优先使用传入的用户信息中的 miId
if (userData != null && userData!.miId.isNotEmpty) {
targetMiId = userData!.miId;
targetUserId = userData!.userId.isNotEmpty ? userData!.userId : userId;
} else if (miId != null && miId!.isNotEmpty) {
// 如果已经有miId,直接使用
targetMiId = miId;
} else {
// 如果没有miId,尝试从会话中获取
await _tryGetMiIdFromConversation();
if (miId != null && miId!.isNotEmpty) {
targetMiId = miId;
}
}
// 验证参数
if (targetMiId == null || targetMiId.isEmpty) {
SmartDialog.showToast('无法获取用户信息,请稍后重试');
if (Get.isLogEnable) {
Get.log('❌ [ChatSettings] 无法跳转到用户主页:miId为空');
}
return;
}
if (targetUserId.isEmpty) {
SmartDialog.showToast('用户ID无效');
if (Get.isLogEnable) {
Get.log('❌ [ChatSettings] 无法跳转到用户主页:userId为空');
}
return;
}
if (Get.isLogEnable) {
Get.log('✅ [ChatSettings] 跳转到用户主页:miId=$targetMiId, userId=$targetUserId');
}
// 跳转到用户主页
await Get.to(() => UserInformationPage(
miId: targetMiId!,
));
} catch (e, stackTrace) {
if (Get.isLogEnable) {
Get.log('❌ [ChatSettings] 跳转到用户主页失败: $e');
Get.log('堆栈跟踪: $stackTrace');
}
SmartDialog.showToast('跳转失败,请稍后重试');
}
}
}