From 6f11f46706af94c65f3aa89fcc1c821b25ab9e64 Mon Sep 17 00:00:00 2001 From: abu <3109389044@qq.com> Date: Wed, 27 Aug 2025 23:26:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=9A=E8=AF=9D=E6=95=B0=E6=8D=AE=E8=BE=B9?= =?UTF-8?q?=E7=BC=98=E5=8C=96=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/IM/controller/chat_controller.dart | 28 +-- lib/IM/global_badge.dart | 33 +++- lib/IM/im_service.dart | 5 +- lib/models/conversation_view_model.dart | 71 +++++++ lib/pages/chat/chat_no_friend.dart | 9 +- lib/pages/chat/index.dart | 11 +- lib/pages/chat/notify/noFriend.dart | 180 ++++++++---------- .../notify_no_friend_controller.dart | 34 ++++ lib/utils/index.dart | 36 ++-- lib/utils/parse_message_summary.dart | 3 + 10 files changed, 283 insertions(+), 127 deletions(-) create mode 100644 lib/pages/chat/notify_controller/notify_no_friend_controller.dart diff --git a/lib/IM/controller/chat_controller.dart b/lib/IM/controller/chat_controller.dart index 5e4e786..2955ea4 100644 --- a/lib/IM/controller/chat_controller.dart +++ b/lib/IM/controller/chat_controller.dart @@ -37,10 +37,15 @@ class ChatController extends GetxController { final List convList = res.data; for (var conv in convList) { - logger.w('基本会话: ${conv.conversation.toLogString()}'); + 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(convList); + chatList.addAll(filtered); // 不包含noFriend才执行加载数据逻辑,分页加载时候过滤 final hasNoFriend = chatList.any((item) => item.conversation.conversationGroupList?.contains(myConversationType.ConversationType.noFriend.name) ?? false); logger.e('开始构建陌生人入口是否包含noFriend?:$hasNoFriend'); @@ -91,16 +96,17 @@ class ChatController extends GetxController { ), ); if (unread.success) { - final conv = convList.first; - final faceUrl = 'assets/images/notify/msr.png'; - conv.showName = '陌生人消息'; - conv.unreadCount = unread.data; - final createItem = ConversationViewModel( - conversation: conv, - faceUrl: faceUrl, - ); + var viewModelList = await ConversationViewModel.createConversationViewModel(convList: [convList.first]); + final conviewModel = viewModelList.first; + conviewModel.faceUrl = 'assets/images/notify/msr.png'; + conviewModel.conversation.showName = '陌生人消息'; + conviewModel.conversation.unreadCount = unread.data; + // final createItem = ConversationViewModel( + // conversation: conv, + // faceUrl: faceUrl, + // ); final newList = List.from(chatList); - newList.add(createItem); + newList.add(conviewModel); newList.sort((a, b) { final atime = a.conversation.lastMessage?.timestamp ?? 0; final btime = b.conversation.lastMessage?.timestamp ?? 0; diff --git a/lib/IM/global_badge.dart b/lib/IM/global_badge.dart index c8b0852..ed1510a 100644 --- a/lib/IM/global_badge.dart +++ b/lib/IM/global_badge.dart @@ -3,7 +3,9 @@ import 'package:loopin/IM/controller/chat_controller.dart'; import 'package:loopin/IM/controller/tab_bar_controller.dart'; import 'package:loopin/IM/im_service.dart'; import 'package:loopin/models/conversation_type.dart'; +import 'package:loopin/models/conversation_view_model.dart'; import 'package:loopin/models/tab_type.dart'; +import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart'; @@ -31,7 +33,8 @@ class GlobalBadge extends GetxController { }, onNewConversation: (List conversationList) { for (var conv in conversationList) { - logger.i("新会话创建:${conv.conversationGroupList}"); + logger.e('新创建会话:${conv.toLogString()}'); + logger.i("新会话分组类型:${conv.conversationGroupList}"); handleCoverstion(conv); } }, @@ -42,6 +45,8 @@ class GlobalBadge extends GetxController { final updatedIds = conversationList.map((e) => e.conversationID).toSet(); logger.w('要变更的会话id:$updatedIds'); + // 收集可能存在后续分页的会话 + final List willInsert = []; for (int i = 0; i < ctl.chatList.length; i++) { final chatItem = ctl.chatList[i]; logger.w('需要更新的ID:${chatItem.conversation.conversationID}'); @@ -69,8 +74,34 @@ class GlobalBadge extends GetxController { chatItem.conversation = updatedConv; update(); } + } else { + logger.e('会话列表中不包含的会话:$updatedIds'); + for (var cvID in updatedIds) { + // 检测这条会话数据是否存在,如果存在说明在后面的分页中,不存在则是被删除不处理 + final isReal = await ImService.instance.getConversation(conversationID: cvID); + final V2TimConversation realConv = isReal.data; + if (isReal.success) { + if (realConv.conversationID.isNotEmpty) { + // 陌生人会话列表单独处理 + if (Get.isRegistered()) { + final notifyCtl = Get.find(); + notifyCtl.updateLastMsg(conversation: realConv); + } else { + // 收集要插入的数据 + if (realConv.conversationGroupList?.isEmpty ?? false) { + willInsert.add(realConv); + } + } + } + } + } } } + // 添加收集的数据,别忘了分页获取的去重 + if (willInsert.isNotEmpty) { + var viewModelList = await ConversationViewModel.createConversationViewModel(convList: willInsert); + ctl.chatList.insertAll(0, viewModelList); + } // 如果没当前会话列表为空 if (ctl.chatList.isEmpty) { // 重新获取一次 diff --git a/lib/IM/im_service.dart b/lib/IM/im_service.dart index 5175293..7ad4940 100644 --- a/lib/IM/im_service.dart +++ b/lib/IM/im_service.dart @@ -241,19 +241,20 @@ class ImService { } final convList = res.data?.conversationList ?? []; - logger.w('未过滤前到会话数据:$convList'); final userIDList = []; final groupIDList = []; // 提前收集所有需要批量查询的 userID 和 groupID for (var conv in convList) { + logger.e('未过滤前到会话数据:${conv.toLogString()}'); if (conv.userID != null) { userIDList.add(conv.userID!); } else if (conv.groupID != null) { groupIDList.add(conv.groupID!); } } + logger.e('用户ID:$userIDList'); Map userFaceUrlMap = {}; Map groupFaceUrlMap = {}; @@ -268,7 +269,7 @@ class ImService { // 读取管理员标识 final customInfo = user.customInfo; - + logger.w('自定义信息:${user.toJson()}'); if (customInfo != null) { isCustomAdmin[userId] = customInfo['admin'] ?? '0'; } diff --git a/lib/models/conversation_view_model.dart b/lib/models/conversation_view_model.dart index 70f26c6..5afac42 100644 --- a/lib/models/conversation_view_model.dart +++ b/lib/models/conversation_view_model.dart @@ -1,4 +1,6 @@ +import 'package:loopin/IM/im_service.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; +import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart'; class ConversationViewModel { late V2TimConversation conversation; @@ -10,4 +12,73 @@ class ConversationViewModel { this.faceUrl, this.isCustomAdmin = '0', // 默认不是管理员 }); + + static Future> createConversationViewModel({required List convList}) async { + final userIDList = []; + final groupIDList = []; + + // 提前收集所有需要批量查询的 userID 和 groupID + for (var conv in convList) { + logger.e('未过滤前到会话数据:${conv.toLogString()}'); + if (conv.userID != null) { + userIDList.add(conv.userID!); + } else if (conv.groupID != null) { + groupIDList.add(conv.groupID!); + } + } + logger.e('用户ID:$userIDList'); + + Map userFaceUrlMap = {}; + Map groupFaceUrlMap = {}; + Map isCustomAdmin = {}; + if (userIDList.isNotEmpty) { + final userRes = await TencentImSDKPlugin.v2TIMManager.getUsersInfo(userIDList: userIDList); + + if (userRes.code == 0) { + for (var user in userRes.data!) { + final userId = user.userID ?? ''; + userFaceUrlMap[userId] = user.faceUrl; + + // 读取管理员标识 + final customInfo = user.customInfo; + logger.w('自定义信息:${user.toJson()}'); + if (customInfo != null) { + isCustomAdmin[userId] = customInfo['admin'] ?? '0'; + } + } + } + } + + 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], + ); + }).toList(); + + return viewList; + } } diff --git a/lib/pages/chat/chat_no_friend.dart b/lib/pages/chat/chat_no_friend.dart index d57b3cb..783f7bc 100644 --- a/lib/pages/chat/chat_no_friend.dart +++ b/lib/pages/chat/chat_no_friend.dart @@ -9,6 +9,7 @@ import 'package:loopin/IM/im_result.dart'; import 'package:loopin/IM/im_service.dart'; import 'package:loopin/components/preview_video.dart'; import 'package:loopin/models/conversation_type.dart'; +import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.dart'; import 'package:loopin/utils/snapshot.dart'; import 'package:shirne_dialog/shirne_dialog.dart'; import 'package:tencent_cloud_chat_sdk/enum/friend_type_enum.dart'; @@ -181,9 +182,15 @@ class _ChatNoFriendState extends State with SingleTickerProviderSt void cleanUnRead() async { if ((arguments.value.unreadCount ?? 0) > 0) { final res = await ImService.instance.clearConversationUnreadCount(conversationID: arguments.value.conversationID); + if (!res.success) { MyDialog.toast('清理未读异常:${res.desc}', icon: Icon(Icons.warning), style: ToastStyle(backgroundColor: Colors.red.withAlpha(200))); - print('清理未读异常:${res.desc}'); + } + logger.w('清理陌生人会话未读消息,准备刷新消息页的UI,陌生人会话列表的UI'); + // 是否从未读会话列表而来 + if (Get.isRegistered()) { + final ctl = Get.find(); + ctl.updateUnread(conversationID: arguments.value.conversationID); } } } diff --git a/lib/pages/chat/index.dart b/lib/pages/chat/index.dart index 0c52f64..478316a 100644 --- a/lib/pages/chat/index.dart +++ b/lib/pages/chat/index.dart @@ -11,6 +11,7 @@ import 'package:loopin/components/network_or_asset_image.dart'; import 'package:loopin/components/scan_util.dart'; import 'package:loopin/models/conversation_type.dart'; import 'package:loopin/models/conversation_view_model.dart'; +import 'package:loopin/utils/index.dart'; import 'package:loopin/utils/parse_message_summary.dart'; import 'package:shirne_dialog/shirne_dialog.dart'; @@ -328,7 +329,7 @@ class ChatPageState extends State { final isNoFriend = chatList[index].conversation.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false; final isAdmin = chatList[index].isCustomAdmin != null && chatList[index].isCustomAdmin != '0'; - logger.e(chatList[index].isCustomAdmin); + // logger.e(chatList[index].isCustomAdmin); return Ink( // color: chatList[index]['topMost'] == null ? Colors.white : Colors.grey[100], //置顶颜色 child: InkWell( @@ -378,9 +379,11 @@ class ChatPageState extends State { visible: !(isAdmin || isNoFriend), child: Text( // 转成日期字符串显示 - DateTime.fromMillisecondsSinceEpoch( - (chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000, - ).toLocal().toString().substring(0, 16), // 简单截取年月日时分 + // DateTime.fromMillisecondsSinceEpoch( + // (chatList[index].conversation.lastMessage!.timestamp ?? 0) * 1000, + // ).toLocal().toString().substring(0, 16), // 简单截取年月日时分 + Utils.formatTime( + chatList[index].conversation.lastMessage!.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000), style: const TextStyle(color: Colors.grey, fontSize: 12.0), ), ), diff --git a/lib/pages/chat/notify/noFriend.dart b/lib/pages/chat/notify/noFriend.dart index 72ec762..0dfca1e 100644 --- a/lib/pages/chat/notify/noFriend.dart +++ b/lib/pages/chat/notify/noFriend.dart @@ -1,19 +1,17 @@ /// 聊天首页模板 library; -import 'dart:convert'; - import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:loopin/IM/im_service.dart'; import 'package:loopin/behavior/custom_scroll_behavior.dart'; import 'package:loopin/components/network_or_asset_image.dart'; import 'package:loopin/models/conversation_type.dart'; +import 'package:loopin/pages/chat/notify_controller/notify_no_friend_controller.dart'; import 'package:loopin/styles/index.dart'; import 'package:loopin/utils/index.dart'; -import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; +import 'package:loopin/utils/parse_message_summary.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation_filter.dart'; -import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart'; // noFriend, //陌生人消息 @@ -29,10 +27,10 @@ class NofriendState extends State with SingleTickerProviderStateMixin bool hasMore = true; // 是否还有更多数据 final RxBool _throttleFlag = false.obs; // 滚动节流锁 final ScrollController chatController = ScrollController(); - int page = 1; + int page = 0; ///------------------- - RxList convList = [].obs; + final dataController = Get.put(NotifyNoFriendController()); RxList demoList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].obs; @@ -56,27 +54,34 @@ class NofriendState extends State with SingleTickerProviderStateMixin @override void dispose() { - super.dispose(); + logger.e('dispose'); + Get.delete(); chatController.dispose(); + super.dispose(); } - // 分页获取全部数据 + // 分页获取陌生人会话 Future getMsgData() async { final res = await ImService.instance.getConversationListByFilter( filter: V2TimConversationFilter(conversationGroup: ConversationType.noFriend.name), nextSeq: page, ); - logger.i('获取会话数据成功:${res.data!.toJson()}'); + logger.i('获取会话数据成功:${res.data!.toLogString()}'); if (res.success && res.data != null) { final newList = res.data!.conversationList ?? []; + // 已有会话ID集合 + final existingIds = dataController.convList.map((e) => e.conversationID).where((id) => id.isNotEmpty).toSet(); + // 过滤掉已存在的会话 + final filtered = newList.where((c) => !existingIds.contains(c.conversationID)).toList(); + final isFinished = res.data!.isFinished ?? true; - convList.addAll(newList); + dataController.convList.addAll(filtered); if (isFinished) { hasMore = false; // 加载没数据了 - page = int.parse(res.data!.nextSeq ?? '0'); + page = 0; } else { - page++; + page = int.parse(res.data!.nextSeq ?? '0'); } logger.i('获取会话数据成功:$newList'); } else { @@ -106,7 +111,7 @@ class NofriendState extends State with SingleTickerProviderStateMixin ), title: Text( '陌生人消息', - style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), + style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold), ), actions: [], ), @@ -121,106 +126,87 @@ class NofriendState extends State with SingleTickerProviderStateMixin displacement: 10.0, onRefresh: handleRefresh, child: Obx(() { + // final chatList = controller.chatList; + return ListView.builder( - controller: chatController, shrinkWrap: true, physics: BouncingScrollPhysics(), - // itemCount: convList.length, - itemCount: demoList.length, + itemCount: dataController.convList.length, itemBuilder: (context, index) { - // ----测试数据 - final jsonData = '{"faceUrl":"","nickName":"测试昵称","userID":"213213"}'; - final item = jsonDecode(jsonData); // 数据 - final desc = '测试desc'; - final cloudCustomData = 'interactionLike'; - V2TimMessage element = V2TimMessage(elemType: 2, isRead: index > 2 ? true : false); - return Container( - width: double.infinity, - padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0), - child: Row( - spacing: 10.0, - children: [ - // 头像 - InkWell( - onTap: () async { - // 点击头像转到对方主页 - // 先获取视频详情 - // 如果cloudCustomData是interactionComment,interactionAt,interactionReply,传参时带上评论id, - // - // final res = await Http.get('${VideoApi.detail}/${item['vlogID']}'); - // Get.toNamed('/vloger', arguments: res['data']); - Get.toNamed('/vloger'); - }, - child: ClipOval( - child: NetworkOrAssetImage( - imageUrl: item['faceUrl'], - width: 50, - height: 50, - ), - ), - ), + final conv = dataController.convList[index]; + final isNoFriend = conv.conversationGroupList?.contains(ConversationType.noFriend.name) ?? false; - // 消息 - Expanded( - child: InkWell( - onTap: () { - // 点击头像转到对应的聊天 - }, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + return Ink( + // color: conv['topMost'] == null ? Colors.white : Colors.grey[100], //置顶颜色 + child: InkWell( + splashColor: Colors.grey[200], + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 15.0, vertical: 10.0), + child: Row( + spacing: 10.0, + children: [ + // 头图 + ClipOval( + child: NetworkOrAssetImage( + imageUrl: conv.faceUrl, + width: 50, + height: 50, + ), + ), + + // 消息 + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + conv.showName ?? '未知', + style: TextStyle(fontSize: 16, fontWeight: FontWeight.normal), + ), + const SizedBox(height: 2.0), + Text( + conv.lastMessage != null ? parseMessageSummary(conv.lastMessage!) : '', + style: const TextStyle(color: Colors.grey, fontSize: 13.0), + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + // 右侧 + + Column( + crossAxisAlignment: CrossAxisAlignment.end, children: [ - // 昵称 - Text( - item['nickName'] ?? '未知', - style: TextStyle( - fontSize: 16, - fontWeight: FontWeight.normal, + Visibility( + visible: true, + child: Text( + // 转成日期字符串显示 + Utils.formatTime(conv.lastMessage!.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000), + style: const TextStyle(color: Colors.grey, fontSize: 12.0), ), ), - const SizedBox(height: 2.0), - // 描述内容 - Text( - maxLines: 2, - overflow: TextOverflow.ellipsis, - style: const TextStyle(color: Colors.grey, fontSize: 12.0), - // desc, - '很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容很长文本内容', - ), - Text( - Utils.formatTime(element.timestamp ?? DateTime.now().millisecondsSinceEpoch ~/ 1000), - style: TextStyle( - color: Colors.grey[600], - fontSize: 12, - ), + const SizedBox(height: 5.0), + // 数字角标 + Visibility( + visible: (conv.unreadCount ?? 0) > 0, + child: FStyle.badge(conv.unreadCount ?? 0), ), ], ), - ), - ), - - // 右侧 - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ Visibility( - visible: true, - // 视频首图 - child: NetworkOrAssetImage( - imageUrl: item['firstFrameImg'], - placeholderAsset: 'assets/images/bk.jpg', - width: 40, - height: 60, + visible: false, + child: const Icon( + Icons.arrow_forward_ios, + color: Colors.blueGrey, + size: 14.0, ), ), - const SizedBox(width: 5.0), - // 角标 - Visibility( - visible: !(element.isRead ?? true), - child: FStyle.badge(0, isdot: true), - ), ], ), - ], + ), + onTap: () { + Get.toNamed('/chatNoFriend', arguments: conv); + }, ), ); }, diff --git a/lib/pages/chat/notify_controller/notify_no_friend_controller.dart b/lib/pages/chat/notify_controller/notify_no_friend_controller.dart new file mode 100644 index 0000000..b4f889b --- /dev/null +++ b/lib/pages/chat/notify_controller/notify_no_friend_controller.dart @@ -0,0 +1,34 @@ +import 'package:get/get.dart'; +import 'package:loopin/IM/im_service.dart'; +import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart'; + +class NotifyNoFriendController extends GetxController { + final RxList convList = [].obs; + + void updateUnread({required String conversationID}) { + final index = convList.indexWhere((c) => c.conversationID == conversationID); + if (index != -1) { + final conv = convList[index]; + convList[index] = conv..unreadCount = 0; + } else { + logger.e('会话不存在,更新未读失败'); + } + } + + void updateLastMsg({required V2TimConversation conversation}) { + final index = convList.indexWhere((c) => c.conversationID == conversation.conversationID); + if (index != -1) { + convList[index] = conversation; + convList.refresh(); + // convList.value = List.from(convList)..[index] = conversation; + } else { + // 根据会话id查询会话检测是否存在 + logger.e('会话不存在,更新会话失败'); + // 如果存在,说明在后面的分页中,先insert进去 convlist做去重处理 + } + } + + void insertData({required List conversationList}) { + convList.insertAll(0, conversationList); + } +} diff --git a/lib/utils/index.dart b/lib/utils/index.dart index eb35840..f0871fb 100644 --- a/lib/utils/index.dart +++ b/lib/utils/index.dart @@ -160,19 +160,33 @@ class Utils { // 处理IM消息时间显示 static String formatTime(int timestamp) { - // 获取消息时间 - final messageTime = DateTime.fromMillisecondsSinceEpoch( - timestamp * 1000, - ).toLocal(); - // 获取当前时间 + // 确保是毫秒级 + int ms = timestamp.toString().length == 10 ? timestamp * 1000 : timestamp; + + final messageTime = DateTime.fromMillisecondsSinceEpoch(ms).toLocal(); final now = DateTime.now(); - if (messageTime.year == now.year) { - // 同一年:显示月-日 - return '${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}'; - } else { - // 不同年:显示年-月-日 时:分 - return '${messageTime.year}-${messageTime.month.toString().padLeft(2, '0')}-${messageTime.day.toString().padLeft(2, '0')}'; + + bool isSameDay = messageTime.year == now.year && messageTime.month == now.month && messageTime.day == now.day; + + if (isSameDay) { + // 同一天:显示时:分 + return '${messageTime.hour.toString().padLeft(2, '0')}:${messageTime.minute.toString().padLeft(2, '0')}'; } + + if (messageTime.year == now.year) { + // 同一年:显示月-日 时:分 + return '${messageTime.month.toString().padLeft(2, '0')}-' + '${messageTime.day.toString().padLeft(2, '0')} ' + '${messageTime.hour.toString().padLeft(2, '0')}:' + '${messageTime.minute.toString().padLeft(2, '0')}'; + } + + // 不同年:显示完整日期 + return '${messageTime.year}-' + '${messageTime.month.toString().padLeft(2, '0')}-' + '${messageTime.day.toString().padLeft(2, '0')} ' + '${messageTime.hour.toString().padLeft(2, '0')}:' + '${messageTime.minute.toString().padLeft(2, '0')}'; } String _formatHourMinute(DateTime dt) { diff --git a/lib/utils/parse_message_summary.dart b/lib/utils/parse_message_summary.dart index 41e76be..c5fb883 100644 --- a/lib/utils/parse_message_summary.dart +++ b/lib/utils/parse_message_summary.dart @@ -1,5 +1,6 @@ import 'dart:convert'; +import 'package:loopin/IM/push_service.dart'; import 'package:loopin/models/notify_message.type.dart'; import 'package:loopin/models/summary_type.dart'; import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart'; @@ -52,6 +53,8 @@ String _parseCustomMessage(V2TimMessage? msg) { if (msg == null) return '[null]'; final sum = msg.cloudCustomData; final elment = msg.customElem; // 所有服务端发送的通知消息都走【自定义消息类型】 + logger.w('解析自定义消息:${msg.toJson()}'); + logger.w('解析element:${elment?.desc ?? 'summary_error'}'); try { switch (sum) { case SummaryType.hongbao: