From fb2ee6fd1318a1152256b00d1ca84041ff85ca01 Mon Sep 17 00:00:00 2001 From: Jolie <412895109@qq.com> Date: Tue, 11 Nov 2025 16:19:45 +0800 Subject: [PATCH] =?UTF-8?q?feat(chat):=20=E5=AE=9E=E7=8E=B0=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E5=88=97=E8=A1=A8=E5=B1=95=E7=A4=BA=E4=B8=8E=E5=8F=91?= =?UTF-8?q?=E9=80=81=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加消息列表状态管理 - 实现消息发送并更新列表 - 支持分页加载历史消息 - 构建文本消息展示UI - 添加消息方向判断逻辑 - 实现加载更多消息功能 --- lib/controller/message/chat_controller.dart | 58 ++++++++++++++- lib/pages/message/chat_page.dart | 79 ++++++++++++++++++++- 2 files changed, 133 insertions(+), 4 deletions(-) diff --git a/lib/controller/message/chat_controller.dart b/lib/controller/message/chat_controller.dart index 270d404..adbe2df 100644 --- a/lib/controller/message/chat_controller.dart +++ b/lib/controller/message/chat_controller.dart @@ -8,14 +8,21 @@ class ChatController extends GetxController { // 用户信息 final Rx userInfo = Rx(null); + + // 消息列表 + final RxList messages = RxList([]); + + // 加载更多的游标 + String? _cursor; ChatController({required this.userId}); @override void onInit() { super.onInit(); - // 初始化时获取用户信息 + // 初始化时获取用户信息和消息列表 fetchUserInfo(); + fetchMessages(); } /// 获取用户信息 @@ -43,7 +50,12 @@ class ChatController extends GetxController { Future sendMessage(String content) async { try { final message = await IMManager.instance.sendTextMessage(content, userId); - return message != null; + if (message != null) { + // 发送成功后将消息添加到列表开头 + messages.insert(0, message); + return true; + } + return false; } catch (e) { if (Get.isLogEnable) { Get.log('发送消息失败: $e'); @@ -51,4 +63,46 @@ class ChatController extends GetxController { return false; } } + + /// 获取消息列表 + Future fetchMessages({bool loadMore = false}) async { + try { + final List fetchedMessages = await IMManager.instance.getMessages( + userId, + pageSize: 20, + startMsgId: loadMore ? _cursor : null, + ); + + // 过滤掉null消息 + final List validMessages = fetchedMessages.whereType().toList(); + + if (loadMore) { + // 加载更多时添加到列表末尾 + messages.addAll(validMessages); + } else { + // 刷新时替换整个列表 + messages.assignAll(validMessages); + } + + // 更新游标 + if (validMessages.isNotEmpty) { + _cursor = validMessages.last.msgId; + } + + if (Get.isLogEnable) { + Get.log('获取消息成功,数量: ${validMessages.length}'); + } + } catch (e) { + if (Get.isLogEnable) { + Get.log('获取消息失败: $e'); + } + } + } + + /// 加载更多消息 + Future loadMoreMessages() async { + if (_cursor != null) { + await fetchMessages(loadMore: true); + } + } } \ No newline at end of file diff --git a/lib/pages/message/chat_page.dart b/lib/pages/message/chat_page.dart index dbd219b..7290fc5 100644 --- a/lib/pages/message/chat_page.dart +++ b/lib/pages/message/chat_page.dart @@ -2,6 +2,7 @@ import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; +import 'package:im_flutter_sdk/im_flutter_sdk.dart'; import '../../controller/message/chat_controller.dart'; import '../../generated/assets.dart'; @@ -12,6 +13,77 @@ class ChatPage extends StatelessWidget { const ChatPage({required this.userId, super.key}); + // 构建消息项 + Widget _buildMessageItem(EMMessage message, bool isSentByMe) { + // 只处理文本消息,其他类型消息可以根据需要扩展 + if (message.body.type == MessageType.TXT) { + final textBody = message.body as EMTextMessageBody; + return Container( + padding: EdgeInsets.symmetric( + horizontal: 16.w, + vertical: 8.h, + ), + child: Row( + mainAxisAlignment: isSentByMe ? MainAxisAlignment.end : MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (!isSentByMe) _buildAvatar(), + if (!isSentByMe) SizedBox(width: 8.w), + Container( + constraints: BoxConstraints(maxWidth: 240.w), + padding: EdgeInsets.symmetric( + horizontal: 12.w, + vertical: 8.h, + ), + decoration: BoxDecoration( + color: isSentByMe ? Color(0xff98E165) : Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(12.w), + topRight: Radius.circular(12.w), + bottomLeft: isSentByMe ? Radius.circular(12.w) : Radius.circular(0), + bottomRight: isSentByMe ? Radius.circular(0) : Radius.circular(12.w), + ), + ), + child: Text( + textBody.content, + style: TextStyle( + fontSize: 14.sp, + color: isSentByMe ? Colors.black : Colors.black, + ), + ), + ), + if (isSentByMe) SizedBox(width: 8.w), + if (isSentByMe) _buildAvatar(), + ], + ), + ); + } + + // 非文本消息显示占位符 + return Container( + padding: EdgeInsets.symmetric( + horizontal: 16.w, + vertical: 8.h, + ), + child: Text('不支持的消息类型'), + ); + } + + // 构建头像 + Widget _buildAvatar() { + return Container( + width: 40.w, + height: 40.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(20.w), + image: DecorationImage( + image: AssetImage(Assets.imagesAvatarsExample), + fit: BoxFit.cover, + ), + ), + ); + } + @override Widget build(BuildContext context) { return GetBuilder( @@ -47,9 +119,12 @@ class ChatPage extends StatelessWidget { alignment: Alignment.topCenter, child: ListView.builder( reverse: true, - itemCount: 10, + itemCount: controller.messages.length, itemBuilder: (context, index) { - return Container(); + final message = controller.messages[index]; + print('message: $message'); + final isSentByMe = message.direction == MessageDirection.SEND; + return _buildMessageItem(message, isSentByMe); }, ), ),