flutter/lib/IM/controller/chat_controller.dart
2025-09-13 17:01:01 +08:00

285 lines
12 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'package:get/get.dart';
import 'package:loopin/IM/im_service.dart';
import 'package:loopin/models/conversation_type.dart' as myConversationType;
import 'package:loopin/models/conversation_view_model.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
class ChatController extends GetxController {
RxInt count = 20.obs; // 每页条数
RxString nextSeq = '0'.obs; // 页码
RxBool isFinished = false.obs; // 是否拉取完?默认未拉取完
final chatList = <ConversationViewModel>[].obs;
void initChatData() {
chatList.clear();
nextSeq.value = '0';
isFinished.value = false;
}
/// 检测分组
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}');
}
}
// 获取所有会话列表
Future<void> getConversationList() async {
logger.e('开始获取会话列表数据');
if (isFinished.value) {
// 拉取完数据了,直接结束
logger.e('会话触底无数据');
return;
}
try {
final res = await ImService.instance.getConversationList(nextSeq.value, count.value);
if (!res.success || res.data == null) {
logger.e('获取会话失败::${res.desc}');
return;
}
final List<ConversationViewModel> convList = res.data;
for (var conv in convList) {
logger.w('基本会话: ${conv.conversation.toJson()}');
}
// 去重
// 已有会话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();
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');
}
}
///构建陌生人消息菜单入口(更新时候传入对应的会话)
Future<void> getNoFriendData({V2TimConversation? csion}) async {
// 检测会话列表是否已有陌生人消息菜单
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');
if (hasNoFriend) {
// 已经有了入口
// 先检测nofriend分组是否还有数据
final noFriendData = await ImService.instance.getConversationListByFilter(
filter: V2TimConversationFilter(conversationGroup: myConversationType.ConversationType.noFriend.name),
nextSeq: 0,
count: 1,
);
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;
}
} else {
// 没数据,移除入口
chatList.removeWhere((chatItem) => chatItem.isCustomAdmin == myConversationType.ConversationType.noFriend.name);
}
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()}');
}
}
/// 按会话分组查询 getConversationListByFilter
// void filterConversationList() async {
// 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
// // }
// }
}