flutter/lib/IM/im_service.dart

725 lines
23 KiB
Dart
Raw Normal View History

2025-07-21 15:46:30 +08:00
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
2025-08-21 10:50:38 +08:00
import 'package:loopin/IM/controller/chat_controller.dart';
import 'package:loopin/IM/controller/im_user_info_controller.dart';
2025-07-21 15:46:30 +08:00
import 'package:loopin/IM/controller/tab_bar_controller.dart';
import 'package:loopin/IM/global_badge.dart';
import 'package:loopin/IM/im_core.dart';
import 'package:loopin/IM/im_friend_listeners.dart';
import 'package:loopin/IM/im_message_listeners.dart';
import 'package:loopin/IM/im_result.dart';
2025-08-21 10:50:38 +08:00
import 'package:loopin/IM/push_service.dart';
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:loopin/utils/wxsdk.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_application_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_response_type_enum.dart';
import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/enum/history_msg_get_type_enum.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_operation_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_follow_type_check_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_info_result.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_friend_operation_result.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_change_info.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_param.dart';
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_search_result.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_full_info.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_user_info_result.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_conversation_manager.dart';
2025-08-21 10:50:38 +08:00
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_friendship_manager.dart';
import 'package:tencent_cloud_chat_sdk/native_im/adapter/tim_message_manager.dart';
2025-07-21 15:46:30 +08:00
import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
final logger = Logger();
/// IM 服务封装类
class ImService {
ImService._();
static final instance = ImService._();
/// 登录
Future<ImResult> login({
required String userID,
required String userSig,
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.login(
userID: userID,
userSig: userSig,
);
final result = ImResult(
success: res.code == 0,
code: res.code,
desc: res.desc,
);
if (result.success) {
logger.i("IM 登录成功:$userID");
// 初始化会话数据
final ctl = Get.find<ChatController>();
await ctl.getConversationList();
/// 初始化微信 SDK
2025-08-21 10:50:38 +08:00
await Wxsdk.init();
// 注册用户信息(基本信息+自定义信息)
if (!Get.isRegistered<ImUserInfoController>()) {
final imInfo = Get.put(ImUserInfoController(), permanent: true);
await imInfo.refreshUserInfo();
} else {
await Get.find<ImUserInfoController>().refreshUserInfo();
}
2025-07-21 15:46:30 +08:00
// 登录成功后注册高级消息监听器
final messageService = ImMessageListenerService();
Get.put<ImMessageListenerService>(messageService, permanent: true);
await messageService.init();
// 注册关系链监听器
final friendListener = ImFriendListeners();
Get.put<ImFriendListeners>(friendListener, permanent: true);
friendListener.register();
/// 注册消息未读数监听器
Get.put(GlobalBadge(), permanent: true);
// 初始化push服务
PushService().initPush(
sdkAppId: 1600080789,
appKey: 'vkFpe55aYqfV7Sk5uGaoxhEstJ3tcI9dquk7JwG1GloDSLD2HeMWeQweWWXgNlhC',
);
2025-07-21 15:46:30 +08:00
} else {
logger.i("IM 登录失败:${result.code} - ${result.desc}");
Get.snackbar(
'登录失败',
'${result.code} - ${result.desc}',
backgroundColor: Colors.red.withAlpha(230),
colorText: Colors.white,
icon: const Icon(Icons.error_outline, color: Colors.white),
);
}
return result;
}
/// 登出
Future<ImResult> logout() async {
final res = await TencentImSDKPlugin.v2TIMManager.logout();
if (res.code == 0) {
/// 移出消息监听器
await Get.delete<ImMessageListenerService>(force: true);
2025-07-21 15:46:30 +08:00
/// 移出关系链监听器
Get.find<ImFriendListeners>().unregister();
await Get.delete<ImFriendListeners>(force: true);
2025-07-21 15:46:30 +08:00
/// 清理tabbar
Get.find<TabBarController>().badgeMap.clear();
2025-08-21 10:50:38 +08:00
/// 清理会话列表数据
Get.find<ChatController>().initChatData();
2025-07-21 15:46:30 +08:00
/// 移出未读消息监听器
Get.find<GlobalBadge>().onClose();
await Get.delete<GlobalBadge>(force: true);
2025-07-21 15:46:30 +08:00
2025-08-21 10:50:38 +08:00
/// 移除推送服务
await PushService.unInitPush();
2025-08-21 10:50:38 +08:00
2025-07-21 15:46:30 +08:00
/// 反初始化
await ImCore.unInit();
2025-07-21 15:46:30 +08:00
}
2025-08-21 10:50:38 +08:00
return ImResult.wrapNoData(res);
}
/// 设置会话自定义属性
Future<ImResult<List<V2TimConversationOperationResult>>> setConversationCustomData({
required String customData,
required List<String> conversationIDList,
}) async {
final res = await TIMConversationManager.instance.setConversationCustomData(customData: customData, conversationIDList: conversationIDList);
return ImResult.wrap(res);
}
/// 获取符合过滤条件的未读消息总数
Future<ImResult<int>> getUnreadMessageCountByFilter({
required V2TimConversationFilter filter,
}) async {
final res = await TIMConversationManager.instance.getUnreadMessageCountByFilter(
filter: filter,
);
return ImResult.wrap(res);
}
/// 删除会话
Future<ImResult<void>> deleteConversation({
required String conversationID,
}) async {
final res = await TIMConversationManager.instance.deleteConversation(conversationID: conversationID);
return ImResult.wrapNoData(res);
}
/// 创建会话分组
Future<ImResult<List<V2TimConversationOperationResult>>> createConversationGroup({
required String groupName,
required List<String> conversationIDList,
}) async {
final res = await TIMConversationManager.instance.createConversationGroup(
groupName: groupName,
conversationIDList: conversationIDList,
);
return ImResult.wrap(res);
}
/// 获取会话分组列表
Future<ImResult<List<String>>> getConversationGroupList() async {
final res = await TIMConversationManager.instance.getConversationGroupList();
return ImResult.wrap(res);
}
/// 将会话添加到分组
Future<ImResult<List<V2TimConversationOperationResult>>> addConversationsToGroup({
required String groupName,
required List<String> conversationIDList,
}) async {
final res = await TIMConversationManager.instance.addConversationsToGroup(
groupName: groupName,
conversationIDList: conversationIDList,
2025-07-21 15:46:30 +08:00
);
2025-08-21 10:50:38 +08:00
return ImResult.wrap(res);
}
///将会话移除分组
Future<ImResult<List<V2TimConversationOperationResult>>> deleteConversationsFromGroup({
required String groupName,
required List<String> conversationIDList,
}) async {
final res = await TIMConversationManager.instance.deleteConversationsFromGroup(
groupName: groupName,
conversationIDList: conversationIDList,
);
return ImResult.wrap(res);
}
/// 高级查询会话列表
Future<ImResult<V2TimConversationResult>> getConversationListByFilter({
required V2TimConversationFilter filter,
required int nextSeq,
int count = 20,
}) async {
final res = await TIMConversationManager.instance.getConversationListByFilter(
filter: filter,
nextSeq: nextSeq,
count: count,
);
return ImResult.wrap(res);
2025-07-21 15:46:30 +08:00
}
/// 查询会话记录
Future<ImResult> getConversationList(String nextSeq, int count) async {
2025-08-21 10:50:38 +08:00
// final res = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversationList(nextSeq: nextSeq, count: count);
final res = await getConvData(nextSeq, count);
if (res.success == false) {
2025-07-21 15:46:30 +08:00
return ImResult(
success: false,
code: res.code,
desc: res.desc,
);
}
final convList = res.data?.conversationList ?? [];
2025-07-21 15:46:30 +08:00
final userIDList = <String>[];
final groupIDList = <String>[];
// 提前收集所有需要批量查询的 userID 和 groupID
for (var conv in convList) {
2025-08-27 23:26:29 +08:00
logger.e('未过滤前到会话数据:${conv.toLogString()}');
if (conv.userID != null) {
userIDList.add(conv.userID!);
} else if (conv.groupID != null) {
groupIDList.add(conv.groupID!);
2025-07-21 15:46:30 +08:00
}
}
2025-08-27 23:26:29 +08:00
logger.e('用户ID$userIDList');
2025-07-21 15:46:30 +08:00
Map<String, String?> userFaceUrlMap = {};
Map<String, String?> groupFaceUrlMap = {};
Map<String, String> isCustomAdmin = {};
2025-07-21 15:46:30 +08:00
if (userIDList.isNotEmpty) {
final userRes = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: userIDList);
2025-07-21 15:46:30 +08:00
if (userRes.code == 0) {
for (var user in userRes.data!) {
final userId = user.userID ?? '';
userFaceUrlMap[userId] = user.faceUrl;
// 读取管理员标识
final customInfo = user.customInfo;
2025-08-27 23:26:29 +08:00
logger.w('自定义信息:${user.toJson()}');
2025-07-21 15:46:30 +08:00
if (customInfo != null) {
isCustomAdmin[userId] = customInfo['admin'] ?? '0';
2025-07-21 15:46:30 +08:00
}
}
}
}
if (groupIDList.isNotEmpty) {
final groupRes = await TencentImSDKPlugin.v2TIMManager.getGroupManager().getGroupsInfo(groupIDList: groupIDList);
if (groupRes.code == 0) {
for (var groupResult in groupRes.data!) {
final info = groupResult.groupInfo;
if (info != null) {
groupFaceUrlMap[info.groupID] = info.faceUrl;
}
}
}
}
final viewList = convList.map((conv) {
String? faceUrl = conv.faceUrl;
if (faceUrl == null || faceUrl.isEmpty) {
if (conv.userID != null) {
faceUrl = userFaceUrlMap[conv.userID!];
} else if (conv.groupID != null) {
faceUrl = groupFaceUrlMap[conv.groupID!];
}
}
return ConversationViewModel(
conversation: conv,
faceUrl: faceUrl,
isCustomAdmin: isCustomAdmin[conv.userID],
);
2025-07-21 15:46:30 +08:00
}).toList();
2025-08-21 10:50:38 +08:00
// 筛选数据,过滤掉陌生人消息
viewList.removeWhere((conv) {
final special = conv.conversation.conversationGroupList ?? [];
return special.contains('noFriend');
});
ChatController chatcontroller = Get.find<ChatController>();
logger.e('新的分页内容:${res.data!.toLogString()},控制器中的:${chatcontroller.nextSeq.value}');
String newNextSeq = res.data?.nextSeq ?? '0';
bool isEnd = res.data?.isFinished ?? true;
if (isEnd) {
//没数据了,关闭拉取;
chatcontroller.isFinished.value = isEnd;
} else {
// 没拉完,记录游标
chatcontroller.nextSeq.value = newNextSeq;
}
// 更新分页
chatcontroller.nextSeq.value = res.data!.nextSeq!;
if (res.data!.isFinished == false) {
if (viewList.length < 20) {
// 递归补偿拉取
final nextRes = await getConversationList(
res.data!.nextSeq!,
count,
);
if (nextRes.success && nextRes.data != null) {
viewList.addAll(nextRes.data as List<ConversationViewModel>);
}
}
}
2025-07-21 15:46:30 +08:00
return ImResult(
success: res.code == 0,
code: res.code,
desc: res.desc,
data: viewList,
);
}
2025-08-21 10:50:38 +08:00
///获取所有会话数据
Future<ImResult<V2TimConversationResult>> getConvData(String nextSeq, int count) async {
final res = await TencentImSDKPlugin.v2TIMManager.getConversationManager().getConversationList(nextSeq: nextSeq, count: count);
return ImResult.wrap(res);
2025-07-21 15:46:30 +08:00
}
///获取指定会话
Future<ImResult> getConversation({
required String conversationID,
}) async {
final res = await TIMConversationManager.instance.getConversation(conversationID: conversationID); //c2c_conversationID,group_conversationID
return ImResult<V2TimConversation?>(
success: res.code == 0 && res.data != null,
code: res.code,
desc: res.desc,
data: res.data,
);
}
/// 搜索本地消息
Future<ImResult<V2TimMessageSearchResult>> searchLocalMessages({
required String page,
required String conversationID,
/// 关键词匹配机制or=0and=1
int type = 1,
/// ['你好','周末']
required List<String> keywordList,
/// 默认自定义消息
List<int> messageTypeList = const [1, 2],
}) async {
final searchParam = V2TimMessageSearchParam(
type: type,
conversationID: conversationID,
keywordList: keywordList,
messageTypeList: messageTypeList,
pageSize: 100,
// pageIndex: page,
searchCursor: page,
);
final V2TimValueCallback<V2TimMessageSearchResult> res = await TIMMessageManager.instance.searchLocalMessages(searchParam: searchParam);
return ImResult.wrap(res);
}
2025-08-21 10:50:38 +08:00
/// 获取消息
Future<ImResult<List<V2TimMessage>>> findMessages({
required List<String> messageIDList,
}) async {
final res = await TIMMessageManager.instance.findMessages(messageIDList: messageIDList);
return ImResult.wrap(res);
}
/// 修改消息
Future<ImResult<V2TimMessageChangeInfo>> modifyMessage({
required V2TimMessage message,
}) async {
final res = await TIMMessageManager.instance.modifyMessage(message: message);
return ImResult.wrap(res);
}
2025-07-21 15:46:30 +08:00
/// 获取聊天记录 如果是群聊传 groupID单聊传 userID二选一
Future<ImResult<List<V2TimMessage>>> getHistoryMessageList({
HistoryMsgGetTypeEnum getType = HistoryMsgGetTypeEnum.V2TIM_GET_LOCAL_OLDER_MSG,
String? userID,
String? groupID,
int? lastMsgSeq,
2025-08-21 10:50:38 +08:00
int count = 10,
2025-07-21 15:46:30 +08:00
V2TimMessage? lastMsg,
List<int>? messageTypeList,
List<int>? messageSeqList,
int? timeBegin,
int? timePeriod,
}) async {
if ((userID == null || userID.isEmpty) && (groupID == null || groupID.isEmpty)) {
return ImResult(
success: false,
code: -1,
desc: 'userID 或 groupID 必须至少传入一个',
data: [],
);
}
final isC2C = userID != null && groupID == null;
final manager = TencentImSDKPlugin.v2TIMManager.getMessageManager();
V2TimValueCallback<List<V2TimMessage>> res;
if (!isC2C && lastMsg == null && lastMsgSeq != null) {
// 群聊
res = await manager.getHistoryMessageList(
getType: getType,
userID: userID,
groupID: groupID,
count: count,
lastMsgSeq: lastMsgSeq, //群聊用,包含最后一条msg
messageTypeList: messageTypeList,
messageSeqList: messageSeqList,
timeBegin: timeBegin,
timePeriod: timePeriod,
);
} else {
// 单聊
res = await manager.getHistoryMessageList(
getType: getType,
userID: userID,
groupID: groupID,
count: count,
lastMsg: lastMsg, // 单聊用不包含最后一条msg
messageTypeList: messageTypeList,
messageSeqList: messageSeqList,
timeBegin: timeBegin,
timePeriod: timePeriod,
);
}
return ImResult<List<V2TimMessage>>(
success: res.code == 0,
code: res.code,
desc: res.desc,
data: res.data ?? [],
);
}
///
/// 清理指定单聊会话的未读数
///
Future<ImResult> clearConversationUnreadCount({
required String conversationID,
// 0表示全部清除
int cleanTimestamp = 0,
int cleanSequence = 0,
}) async {
final res = await TIMConversationManager.instance.cleanConversationUnreadMessageCount(
conversationID: conversationID,
cleanTimestamp: cleanTimestamp, // 单聊生效
cleanSequence: cleanSequence, // 群聊生效
);
2025-08-21 10:50:38 +08:00
return ImResult.wrapNoData(res);
}
/// 获取自己的userId
Future<ImResult> selfUserId() async {
V2TimValueCallback<String> self = await TencentImSDKPlugin.v2TIMManager.getLoginUser();
String? userId = self.data;
return ImResult(
success: self.code == 0,
code: self.code,
desc: self.desc,
data: userId,
);
}
/// 查询当前登录用户的个人信息
Future<ImResult> selfInfo() async {
// 获取当前登录的用户 ID
final idRes = await selfUserId();
// 获取用户信息
V2TimValueCallback<List<V2TimUserFullInfo>> res = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: [idRes.data]);
2025-07-21 15:46:30 +08:00
return ImResult(
success: res.code == 0,
code: res.code,
desc: res.desc,
2025-08-21 10:50:38 +08:00
data: res.data?.isNotEmpty == true ? res.data!.first : null,
);
}
/// 查询其他人的信息
Future<ImResult> otherInfo(id) async {
// 获取用户信息
V2TimValueCallback<List<V2TimUserFullInfo>> res = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: [id]);
return ImResult(
success: res.code == 0,
code: res.code,
desc: res.desc,
data: res.data?.isNotEmpty == true ? res.data!.first : null,
);
}
/// 设置个人资料
Future<ImResult> setSelfInfo({
required V2TimUserFullInfo userFullInfo,
}) async {
final res = await TencentImSDKPlugin.v2TIMManager.setSelfInfo(
userFullInfo: userFullInfo,
);
return ImResult.wrapNoData(res);
}
/// 检查是否是好友(双向或单向)
Future<ImResult> isMyFriend(String userID, FriendTypeEnum checkType) async {
final res = await TIMFriendshipManager.instance.checkFriend(
userIDList: [userID],
checkType: checkType, //V2TIM_FRIEND_TYPE_BOTH V2TIM_FRIEND_TYPE_SINGLE
);
if (res.code == 0 && res.data != null && res.data!.isNotEmpty) {
final resultType = res.data!.first.resultType;
final isFriend = resultType == 3; //0=无, 1=单向, 2=我在对方列表3=双向
return ImResult(
success: true,
desc: res.desc,
code: res.code,
data: isFriend,
);
} else {
return ImResult(
success: false,
code: res.code,
desc: res.desc,
data: false,
);
}
}
/// 添加好友
Future<ImResult<V2TimFriendOperationResult>> addFriend({
required String userID,
String? remark,
String? friendGroup,
String? addWording,
String? addSource,
required FriendTypeEnum addType,
}) async {
final res = await TIMFriendshipManager.instance.addFriend(
userID: userID,
remark: remark,
friendGroup: friendGroup,
addWording: addWording,
addSource: addSource,
addType: addType,
);
return ImResult.wrap(res);
}
///接受好友申请
Future<ImResult<V2TimFriendOperationResult>> acceptFriendApplication({
required FriendResponseTypeEnum responseType,
required FriendApplicationTypeEnum type, // V2TIM_FRIEND_ACCEPT_AGREE同意添加单向好友V2TIM_FRIEND_ACCEPT_AGREE_AND_ADD同意并添加为双向好友
required String userID,
}) async {
final res = await TIMFriendshipManager.instance.acceptFriendApplication(
responseType: responseType,
type: type,
userID: userID,
);
return ImResult.wrap(res);
}
/// 拉黑
Future<ImResult<List<V2TimFriendOperationResult>>> addToBlackList({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.addToBlackList(userIDList: userIDList);
return ImResult.wrap(res);
}
/// 取消拉黑
Future<ImResult<List<V2TimFriendOperationResult>>> deleteFromBlackList({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.deleteFromBlackList(userIDList: userIDList);
return ImResult.wrap(res);
}
///获取好友列表
Future<ImResult<List<V2TimFriendInfo>>> getFriendList() async {
final res = await TIMFriendshipManager.instance.getFriendList();
return ImResult.wrap(res);
}
/// set好友备注
Future<ImResult> setFriendInfo({
required String userID,
String? friendRemark,
Map<String, String>? friendCustomInfo,
}) async {
late V2TimCallback res;
res = await TIMFriendshipManager.instance.setFriendInfo(
userID: userID,
friendRemark: friendRemark,
friendCustomInfo: friendCustomInfo,
);
return ImResult.wrapNoData(res);
}
/// 获取好友信息
Future<ImResult<List<V2TimFriendInfoResult>>> getFriendInfo({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.getFriendsInfo(userIDList: userIDList);
return ImResult.wrap(res);
}
///关注
Future<ImResult<List<V2TimFollowOperationResult>>> followUser({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.followUser(
userIDList: userIDList,
);
return ImResult.wrap(res);
}
///取关
Future<ImResult<List<V2TimFollowOperationResult>>> unfollowUser({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.unfollowUser(
userIDList: userIDList,
);
return ImResult.wrap(res);
}
/// check关注的类型
/// 0不是好友也没有关注
/// 1你关注了对方单向
/// 2对方关注了你单向
/// 3互相关注双向好友
Future<ImResult<List<V2TimFollowTypeCheckResult>>> checkFollowType({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.checkFollowType(
userIDList: userIDList,
);
return ImResult.wrap(res);
}
///获取指定用户的 关注/粉丝/互关 数量信息
Future<ImResult<List<V2TimFollowInfo>>> getUserFollowInfo({
required List<String> userIDList,
}) async {
final res = await TIMFriendshipManager.instance.getUserFollowInfo(userIDList: userIDList);
return ImResult.wrap(res);
}
/// 获取双向关注列表(互关好友)
/// [nextCursor] 分页游标,首次传空字符串
Future<ImResult<V2TimUserInfoResult>> getMutualFollowersList({
required String nextCursor,
}) async {
final res = await TIMFriendshipManager.instance.getMutualFollowersList(
nextCursor: nextCursor,
);
return ImResult.wrap(res);
}
/// 获取我的粉丝列表
/// [nextCursor] 分页游标,首次传空字符串
Future<ImResult<V2TimUserInfoResult>> getMyFollowersList({
required String nextCursor,
}) async {
final res = await TIMFriendshipManager.instance.getMyFollowersList(
nextCursor: nextCursor,
2025-07-21 15:46:30 +08:00
);
2025-08-21 10:50:38 +08:00
return ImResult.wrap(res);
2025-07-21 15:46:30 +08:00
}
2025-09-03 11:25:31 +08:00
/// 获取我的关注列表
/// [nextCursor] 分页游标,首次传空字符串
Future<ImResult<V2TimUserInfoResult>> getMyFollowingList({
required String nextCursor,
}) async {
final res = await TIMFriendshipManager.instance.getMyFollowingList(
nextCursor: nextCursor,
);
return ImResult.wrap(res);
}
2025-07-21 15:46:30 +08:00
}