flutter/lib/IM/controller/chat_controller.dart

285 lines
12 KiB
Dart
Raw Permalink Normal View History

2025-07-21 15:46:30 +08:00
import 'package:get/get.dart';
import 'package:loopin/IM/im_service.dart';
2025-08-21 10:50:38 +08:00
import 'package:loopin/models/conversation_type.dart' as myConversationType;
2025-07-21 15:46:30 +08:00
import 'package:loopin/models/conversation_view_model.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
2025-07-21 15:46:30 +08:00
class ChatController extends GetxController {
2025-08-21 10:50:38 +08:00
RxInt count = 20.obs; // 每页条数
2025-07-21 15:46:30 +08:00
RxString nextSeq = '0'.obs; // 页码
2025-08-21 10:50:38 +08:00
RxBool isFinished = false.obs; // 是否拉取完?默认未拉取完
2025-07-21 15:46:30 +08:00
final chatList = <ConversationViewModel>[].obs;
2025-08-21 10:50:38 +08:00
void initChatData() {
chatList.clear();
2025-08-21 10:50:38 +08:00
nextSeq.value = '0';
isFinished.value = false;
}
2025-09-03 11:25:31 +08:00
/// 检测分组
Future<bool> handleGroup({required String conversationID}) async {
final isReal = await ImService.instance.getConversation(conversationID: conversationID);
final V2TimConversation conv = isReal.data;
if (conv.lastMessage != null) {
// 会话存在执行后续逻辑
return true;
} else {
// 会话不存在,结束
return false;
}
}
/// 关注后移除陌生人会话
Future<void> removeNoFriend({required String conversationID}) async {
try {
final isContinue = await handleGroup(conversationID: conversationID);
if (isContinue) {
await ImService.instance.deleteConversationsFromGroup(
groupName: myConversationType.ConversationTypeStatic.noFriend,
conversationIDList: [conversationID],
);
}
} catch (e) {
logger.e('移除陌生人会话分组异常:$e');
}
}
/// 取关后将会话移入陌生人会话
Future<void> mergeNoFriend({required conversationID}) async {
try {
final isContinue = await handleGroup(conversationID: conversationID);
if (isContinue) {
final typeEnum = myConversationType.ConversationTypeStatic.noFriend;
final hasGroupRes = await ImService.instance.getConversationGroupList();
if (hasGroupRes.success) {
final exists = hasGroupRes.data?.any((item) => item == typeEnum) ?? false;
if (!exists) {
// 组不存在创建组并把会话加入group中
await ImService.instance.createConversationGroup(
groupName: typeEnum,
conversationIDList: [conversationID],
);
logger.i('取关触发添加会话分组$typeEnum成功');
} else {
// 分组存在直接添加
await ImService.instance.addConversationsToGroup(
groupName: typeEnum,
conversationIDList: [conversationID],
);
}
}
final res = chatList.firstWhereOrNull((item) => item.conversation.conversationID == conversationID);
if (res != null) {
chatList.remove(res);
}
}
} catch (e) {
logger.w('移除会话列表时发生错误: $e');
}
}
// 关注后更新nofd菜单入口
Future<void> updateNoFriendMenu() async {
final res = await ImService.instance.getConversationListByFilter(
filter: V2TimConversationFilter(conversationGroup: myConversationType.ConversationType.noFriend.name),
nextSeq: 0,
count: 1,
);
if (res.success && res.data != null) {
final convList = res.data!.conversationList ?? [];
if (convList.isNotEmpty) {
// 只要有数据,入口一定存在,找到入口数据替换
final unread = await ImService.instance.getUnreadMessageCountByFilter(
filter: V2TimConversationFilter(
conversationGroup: myConversationType.ConversationType.noFriend.name,
hasUnreadCount: true,
),
);
if (unread.success) {
var viewModelList = await ConversationViewModel.createConversationViewModel(convList: [convList.first]);
final conviewModel = viewModelList.first;
conviewModel.faceUrl = 'assets/images/notify/msr.png';
conviewModel.isCustomAdmin = myConversationType.ConversationTypeStatic.noFriend;
conviewModel.conversation.showName = '陌生人消息';
conviewModel.conversation.unreadCount = unread.data;
conviewModel.conversation.conversationID = myConversationType.ConversationTypeStatic.noFriend;
// final newList = List<ConversationViewModel>.from(chatList);
final index = chatList.indexWhere(
(item) => item.isCustomAdmin == myConversationType.ConversationTypeStatic.noFriend,
);
if (index != -1) {
chatList[index] = conviewModel;
// 排序
chatList.sort((a, b) {
final atime = a.conversation.lastMessage?.timestamp ?? 0;
final btime = b.conversation.lastMessage?.timestamp ?? 0;
return btime.compareTo(atime); // 降序
});
// 更新
chatList.refresh();
}
}
}
} else {
logger.e('刷新入口失败-----${res.desc}');
}
}
2025-08-21 10:50:38 +08:00
// 获取所有会话列表
Future<void> getConversationList() async {
logger.e('开始获取会话列表数据');
2025-08-21 10:50:38 +08:00
if (isFinished.value) {
// 拉取完数据了,直接结束
logger.e('会话触底无数据');
2025-08-21 10:50:38 +08:00
return;
}
try {
final res = await ImService.instance.getConversationList(nextSeq.value, count.value);
2025-07-21 15:46:30 +08:00
if (!res.success || res.data == null) {
logger.e('获取会话失败::${res.desc}');
return;
}
2025-07-21 15:46:30 +08:00
final List<ConversationViewModel> convList = res.data;
for (var conv in convList) {
2025-08-27 23:26:29 +08:00
logger.w('基本会话: ${conv.conversation.toJson()}');
}
2025-08-27 23:26:29 +08:00
// 去重
// 已有会话ID集合
final existingIds = chatList.map((e) => e.conversation.conversationID).where((id) => id.isNotEmpty).toSet();
// 过滤掉已存在的会话
final filtered = convList.where((c) => !existingIds.contains(c.conversation.conversationID)).toList();
2025-07-21 15:46:30 +08:00
2025-08-27 23:26:29 +08:00
chatList.addAll(filtered);
// 不包含noFriend才执行加载数据逻辑,分页加载时候过滤
final hasNoFriend = chatList.any((item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false);
logger.e('开始构建陌生人入口是否包含noFriend?$hasNoFriend');
if (!hasNoFriend) {
getNoFriendData();
}
} catch (e) {
logger.e('获取会话异常::$e');
2025-08-21 10:50:38 +08:00
}
2025-07-21 15:46:30 +08:00
}
2025-08-21 10:50:38 +08:00
2025-09-03 11:25:31 +08:00
///构建陌生人消息菜单入口(更新时候传入对应的会话)
Future<void> getNoFriendData({V2TimConversation? csion}) async {
2025-08-21 10:50:38 +08:00
// 检测会话列表是否已有陌生人消息菜单
2025-09-13 17:01:01 +08:00
final hasNoFriend = chatList
.where((item) => item.conversation.type == 1) // 只检测单聊天 type == 1 的会话
.any((item) => item.isCustomAdmin?.contains(myConversationType.ConversationType.noFriend.name) ?? false);
logger.w('检测是否存在nofriend入口$hasNoFriend');
2025-08-21 10:50:38 +08:00
if (hasNoFriend) {
// 已经有了入口
2025-09-03 11:25:31 +08:00
// 先检测nofriend分组是否还有数据
final noFriendData = await ImService.instance.getConversationListByFilter(
filter: V2TimConversationFilter(conversationGroup: myConversationType.ConversationType.noFriend.name),
nextSeq: 0,
count: 1,
);
2025-09-03 11:25:31 +08:00
if (noFriendData.success && (noFriendData.data?.conversationList?.isNotEmpty == true)) {
// 还存在陌生人会话数据
final ConversationViewModel matchItem = chatList.firstWhere(
(item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false,
orElse: () {
//赋在viewmodel会话上的分组被移除
logger.w("没有找到符合条件的元素,执行移除逻辑");
return ConversationViewModel(conversation: V2TimConversation(conversationID: ''));
},
);
// 获取陌生人未读总数
final unreadTotal = await ImService.instance.getUnreadMessageCountByFilter(
filter: V2TimConversationFilter(
conversationGroup: myConversationType.ConversationType.noFriend.name,
hasUnreadCount: true,
),
);
// 如果上面没找到 就是移除nofriend分组
if (matchItem.conversation.conversationID.isEmpty) {
// 执行移除更新用最新的一条会话数据构建viewmodel
await ConversationViewModel.createConversationViewModel(convList: noFriendData.data!.conversationList!);
} else {
matchItem.conversation.lastMessage = csion!.lastMessage;
matchItem.conversation.unreadCount = unreadTotal.data;
2025-08-21 10:50:38 +08:00
}
2025-09-03 11:25:31 +08:00
} else {
// 没数据,移除入口
chatList.removeWhere((chatItem) => chatItem.isCustomAdmin == myConversationType.ConversationType.noFriend.name);
2025-08-21 10:50:38 +08:00
}
2025-09-03 11:25:31 +08:00
chatList.refresh();
} else {
logger.w('构建陌生人消息入口--开始');
await createNoFriendMenu();
}
}
// 创建陌生人入口
Future<void> createNoFriendMenu() async {
// 没有则执行创建逻辑
final res = await ImService.instance.getConversationListByFilter(
filter: V2TimConversationFilter(conversationGroup: myConversationType.ConversationType.noFriend.name),
nextSeq: 0,
count: 1,
);
if (res.success && res.data != null) {
final convList = res.data!.conversationList ?? [];
if (convList.isNotEmpty) {
// logger.i(res.data!.toJson());
// 有陌生人消息1.获取未读数2.组装converstaionviewmodel
final unread = await ImService.instance.getUnreadMessageCountByFilter(
filter: V2TimConversationFilter(
conversationGroup: myConversationType.ConversationType.noFriend.name,
hasUnreadCount: true,
),
);
if (unread.success) {
var viewModelList = await ConversationViewModel.createConversationViewModel(convList: [convList.first]);
final conviewModel = viewModelList.first;
conviewModel.faceUrl = 'assets/images/notify/msr.png';
conviewModel.isCustomAdmin = myConversationType.ConversationTypeStatic.noFriend;
conviewModel.conversation.showName = '陌生人消息';
conviewModel.conversation.unreadCount = unread.data;
conviewModel.conversation.conversationID = myConversationType.ConversationTypeStatic.noFriend;
// final createItem = ConversationViewModel(
// conversation: conv,
// faceUrl: faceUrl,
// );
final newList = List<ConversationViewModel>.from(chatList);
newList.add(conviewModel);
newList.sort((a, b) {
final atime = a.conversation.lastMessage?.timestamp ?? 0;
final btime = b.conversation.lastMessage?.timestamp ?? 0;
return btime.compareTo(atime); // 降序
});
chatList.value = newList;
}
}
} else {
logger.e('构建失败-----${res.desc}\n${res.data!.toJson()}');
2025-08-21 10:50:38 +08:00
}
}
/// 按会话分组查询 getConversationListByFilter
// void filterConversationList() async {
2025-08-21 10:50:38 +08:00
// final res = await ImService.instance.getConversationListByFilter(
// filter: V2TimConversationFilter(conversationGroup: null),
// nextSeq: nextSeq.value,
// );
// final convList = res.data!.conversationList;
// logger.i(res.data!.toJson());
// chatList.value = convList;
// // for (var element in convList ?? []) {
// // logger.i(element.toJson());
// // // 你可以在这里继续处理 element
// // }
// }
2025-07-21 15:46:30 +08:00
}