2025-07-21 15:46:30 +08:00
|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
2025-09-13 17:01:01 +08:00
|
|
|
|
import 'package:get/get.dart';
|
|
|
|
|
import 'package:loopin/IM/controller/im_user_info_controller.dart';
|
2025-09-03 11:56:14 +08:00
|
|
|
|
import 'package:loopin/IM/im_service.dart';
|
2025-08-26 17:38:59 +08:00
|
|
|
|
import 'package:loopin/models/notify_message.type.dart';
|
2025-08-21 10:50:38 +08:00
|
|
|
|
import 'package:loopin/models/summary_type.dart';
|
2025-09-13 17:01:01 +08:00
|
|
|
|
import 'package:loopin/utils/index.dart';
|
|
|
|
|
import 'package:tencent_cloud_chat_sdk/enum/group_tips_elem_type.dart';
|
2025-07-21 15:46:30 +08:00
|
|
|
|
import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
|
2025-09-13 17:01:01 +08:00
|
|
|
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_change_info.dart';
|
|
|
|
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_group_member_info.dart';
|
2025-07-21 15:46:30 +08:00
|
|
|
|
import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
|
|
|
|
|
|
2025-09-13 17:01:01 +08:00
|
|
|
|
/// 群信息变化类型
|
|
|
|
|
class GroupChangeInfoType {
|
|
|
|
|
/// 群自定义字段变更
|
|
|
|
|
static const int custom = 0;
|
|
|
|
|
|
|
|
|
|
/// 群名称修改
|
|
|
|
|
static const int name = 1;
|
|
|
|
|
|
|
|
|
|
/// 群公告修改
|
|
|
|
|
static const int notification = 3; // 2 文档给出的是2,实际修改返回的3,
|
|
|
|
|
|
|
|
|
|
/// 群简介修改
|
|
|
|
|
static const int introduction = 2; // 3 文档给出的3,实际返回的是2
|
|
|
|
|
|
|
|
|
|
/// 群头像修改
|
|
|
|
|
static const int faceUrl = 4;
|
|
|
|
|
|
|
|
|
|
/// 群主变更
|
|
|
|
|
static const int owner = 5;
|
|
|
|
|
|
|
|
|
|
/// 消息接收选项变更
|
|
|
|
|
static const int receiveMessageOpt = 10;
|
|
|
|
|
|
|
|
|
|
/// 全员禁言字段变更
|
|
|
|
|
static const int shutUpAll = 11;
|
|
|
|
|
}
|
|
|
|
|
|
2025-07-21 15:46:30 +08:00
|
|
|
|
String parseMessageSummary(V2TimMessage msg) {
|
|
|
|
|
switch (msg.elemType) {
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_TEXT:
|
|
|
|
|
return msg.textElem?.text ?? '[文本消息]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_IMAGE:
|
|
|
|
|
return '[图片]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_SOUND:
|
|
|
|
|
return '[语音]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_VIDEO:
|
|
|
|
|
return '[视频]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_FILE:
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return '[文件]'; // 先不做
|
2025-07-21 15:46:30 +08:00
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_LOCATION:
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return '[位置]'; // 先不做
|
2025-07-21 15:46:30 +08:00
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_FACE:
|
|
|
|
|
return '[表情]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_CUSTOM:
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return _parseCustomMessage(msg);
|
2025-07-21 15:46:30 +08:00
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_MERGER:
|
|
|
|
|
return '[合并转发消息]';
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_TIPS:
|
2025-09-13 17:01:01 +08:00
|
|
|
|
// 群 Tips 通知类型
|
|
|
|
|
|
|
|
|
|
// logger.w(msg.toJson());
|
|
|
|
|
final tipType = msg.groupTipsElem?.type ?? 0;
|
|
|
|
|
// logger.e(tipType);
|
|
|
|
|
V2TimGroupMemberInfo? op = msg.groupTipsElem?.opMember;
|
|
|
|
|
String opName = Utils.handleText(op?.nameCard, op?.nickName, '群主');
|
|
|
|
|
if (op != null) {
|
|
|
|
|
opName = op.userID == (Get.find<ImUserInfoController>().userID.value) ? '你' : opName;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// 踢人,邀请,主动退群
|
|
|
|
|
String nickNames = '';
|
|
|
|
|
String kickTips = '';
|
|
|
|
|
String inviteTip = '';
|
|
|
|
|
String quitTips = '';
|
|
|
|
|
|
|
|
|
|
/// 群资料相关的
|
|
|
|
|
String changeInfo = '';
|
|
|
|
|
|
|
|
|
|
/// 群成员信息变更的
|
|
|
|
|
// String memberChangeInfo = '';
|
|
|
|
|
|
|
|
|
|
// 被操作人的信息(踢人,邀请,主动退群,退群后会话将被删除
|
|
|
|
|
List<V2TimGroupMemberInfo?> changed = msg.groupTipsElem?.memberList ?? [];
|
|
|
|
|
// 踢人,邀请,退群
|
|
|
|
|
if (changed.isNotEmpty) {
|
|
|
|
|
final selfID = Get.find<ImUserInfoController>().userID.value;
|
|
|
|
|
final nicknamesList = changed.map((item) {
|
|
|
|
|
if (item == null) return "未知用户";
|
|
|
|
|
if (item.userID == selfID) return "你";
|
|
|
|
|
return Utils.handleText(item.nameCard, item.nickName, "未知用户");
|
|
|
|
|
}).toList();
|
|
|
|
|
nickNames = nicknamesList.join(',');
|
|
|
|
|
inviteTip = '$opName 邀请 $nickNames 加入群聊';
|
|
|
|
|
kickTips = '$opName 将 $nickNames 移出群聊';
|
|
|
|
|
quitTips = '$nickNames 退出了群聊';
|
|
|
|
|
}
|
|
|
|
|
// 群资料相关的
|
|
|
|
|
List<V2TimGroupChangeInfo?> groupChanged = msg.groupTipsElem?.groupChangeInfoList ?? [];
|
|
|
|
|
if (groupChanged.isNotEmpty) {
|
|
|
|
|
// 在群的设置那里,修改方法都是单条,所以只处理单条就可以了
|
|
|
|
|
for (final item in groupChanged) {
|
|
|
|
|
if (item?.type == GroupChangeInfoType.faceUrl) {
|
|
|
|
|
// 群头像变更
|
|
|
|
|
changeInfo = '$opName 修改了群头像';
|
|
|
|
|
} else if (item?.type == GroupChangeInfoType.introduction) {
|
|
|
|
|
// 群简介
|
|
|
|
|
changeInfo = '$opName 将群简介修改为:${item?.value}';
|
|
|
|
|
} else if (item?.type == GroupChangeInfoType.notification) {
|
|
|
|
|
// 群公告
|
|
|
|
|
changeInfo = '$opName 将群公告修改为:${item?.value}';
|
|
|
|
|
} else if (item?.type == GroupChangeInfoType.name) {
|
|
|
|
|
// 群名称
|
|
|
|
|
changeInfo = '$opName 将群名称修改为:${item?.value}';
|
|
|
|
|
} else {
|
|
|
|
|
changeInfo = '群资料发生变更';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 群成员资料变更
|
|
|
|
|
// List<V2TimGroupMemberChangeInfo?> memberChanged = msg.groupTipsElem?.memberChangeInfoList ?? [];
|
|
|
|
|
// if (memberChanged.isNotEmpty) {
|
|
|
|
|
// for (final item in memberChanged) {}
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
if (tipType == GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_INVITE) {
|
|
|
|
|
// 加群,
|
|
|
|
|
return inviteTip;
|
|
|
|
|
} else if (tipType == GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_KICKED) {
|
|
|
|
|
// 踢人
|
|
|
|
|
return kickTips;
|
|
|
|
|
} else if (tipType == GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_QUIT) {
|
|
|
|
|
// 退群
|
|
|
|
|
return quitTips;
|
|
|
|
|
} else if (tipType == GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_GROUP_INFO_CHANGE) {
|
|
|
|
|
//群资料变更groupName & introduction & notification & faceUrl & owner & custom)
|
|
|
|
|
return changeInfo;
|
|
|
|
|
} else if (tipType == GroupTipsElemType.V2TIM_GROUP_TIPS_TYPE_MEMBER_INFO_CHANGE) {
|
|
|
|
|
//群成员资料变更 (opMember 修改群成员资料:muteTime)
|
|
|
|
|
return '群成员资料变更';
|
|
|
|
|
} else {
|
|
|
|
|
return '[收到一条群系统通知]';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case MessageElemType.V2TIM_ELEM_TYPE_GROUP_REPORT:
|
2025-07-21 15:46:30 +08:00
|
|
|
|
default:
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return '[未知消息类型1]';
|
2025-07-21 15:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-03 11:56:14 +08:00
|
|
|
|
// newFocus, //新的关注
|
2025-08-26 17:38:59 +08:00
|
|
|
|
// systemNotify, // 系统->通知
|
|
|
|
|
// systemReport, // 系统->举报下架(视频,视频评论)
|
|
|
|
|
// systemCheck, // 系统->审核结果(复审,驳回 ,通过)
|
|
|
|
|
// systemPush, //系统->推广类的
|
|
|
|
|
// interactionComment, //互动->评论
|
|
|
|
|
// interactionAt, //互动->视频评论中的@
|
|
|
|
|
// interactionLike, //互动->点赞
|
|
|
|
|
// interactionReply, //互动->评论回复
|
|
|
|
|
// orderRecharge, //订单->充值 online
|
|
|
|
|
// orderPay, //订单->订单交易成功通知 online
|
|
|
|
|
// orderRefund, //订单->退款结果通知
|
|
|
|
|
// groupNotifyCheck, //群通知->进群申请 online
|
|
|
|
|
// groupNotifyAccpet, // 群通知->进群审核审核通过 online
|
|
|
|
|
// groupNotifyFail, // 群通知->进群审核审核拒绝 online
|
|
|
|
|
// groupNotifyLeaveUp, // 群通知->群升级为达人群通知
|
2025-08-21 10:50:38 +08:00
|
|
|
|
String _parseCustomMessage(V2TimMessage? msg) {
|
|
|
|
|
if (msg == null) return '[null]';
|
2025-09-09 10:57:52 +08:00
|
|
|
|
String sum;
|
|
|
|
|
// 客户端本地用的是字符串,服务端返回的是JSON(服务端改cloudCustomData的类型为String,或者客户端代码修改发送消息时携带的参数由string变为json)
|
|
|
|
|
final raw = msg.cloudCustomData;
|
|
|
|
|
if (raw == null) {
|
|
|
|
|
sum = '';
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
final decoded = jsonDecode(raw);
|
|
|
|
|
sum = decoded is String ? decoded : raw;
|
|
|
|
|
} catch (_) {
|
|
|
|
|
sum = raw;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// final sum = jsonDecode(msg.cloudCustomData!);
|
2025-08-26 17:38:59 +08:00
|
|
|
|
final elment = msg.customElem; // 所有服务端发送的通知消息都走【自定义消息类型】
|
2025-09-09 10:57:52 +08:00
|
|
|
|
// logger.w('解析自定义消息:$sum,自定义属性:${msg.cloudCustomData}');
|
|
|
|
|
logger.w(sum);
|
|
|
|
|
logger.w('解析element:${elment?.desc ?? 'summary_error'}');
|
2025-07-21 15:46:30 +08:00
|
|
|
|
try {
|
2025-08-21 10:50:38 +08:00
|
|
|
|
switch (sum) {
|
|
|
|
|
case SummaryType.hongbao:
|
|
|
|
|
final hbData = jsonDecode(msg.customElem!.data!);
|
|
|
|
|
return '[红包]${hbData['remark']}';
|
|
|
|
|
case SummaryType.shareTuangou:
|
|
|
|
|
return '[分享商品]';
|
|
|
|
|
case SummaryType.shareVideo:
|
|
|
|
|
return '[分享视频]';
|
2025-08-26 17:38:59 +08:00
|
|
|
|
// 解析服务端通知类的
|
|
|
|
|
/// [des]显示的文本内容
|
|
|
|
|
/// [data] json数据
|
|
|
|
|
/// 名称firstFrameImg:先取cover,如果没有在取firstFrameImg
|
2025-09-03 11:56:14 +08:00
|
|
|
|
case NotifyMessageTypeConstants.newFocus:
|
2025-08-26 17:38:59 +08:00
|
|
|
|
// 关注
|
|
|
|
|
|
|
|
|
|
///发起关注人的[userID],
|
|
|
|
|
///发起关注人的昵称[nickName],
|
|
|
|
|
///发起关注人的头像地址[faceUrl],
|
|
|
|
|
///------
|
|
|
|
|
///客户端检测发起关注人与本人的关注关系
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.systemNotify:
|
|
|
|
|
|
|
|
|
|
///系统级别的没有就先不做
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.systemReport:
|
|
|
|
|
// 视频举报
|
|
|
|
|
|
|
|
|
|
///先只处理视频,评论的先不管
|
|
|
|
|
///被举报的视频[vlogID],
|
|
|
|
|
///被举报的视频标题[title],
|
|
|
|
|
///被举报的视频首帧图[firstFrameImg]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.systemCheck:
|
|
|
|
|
// 视频审核
|
|
|
|
|
|
|
|
|
|
///视频审核结果通知 通过还是驳回
|
|
|
|
|
///被审核的视频[vlogID],
|
|
|
|
|
///被审核的视频标题[title],
|
|
|
|
|
///被审核的视频首帧图[firstFrameImg]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.systemPush:
|
|
|
|
|
|
|
|
|
|
///系统推广类的先不管了
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.interactionComment:
|
|
|
|
|
// 评论视频
|
|
|
|
|
|
|
|
|
|
/// 发起评论人的[userID]
|
|
|
|
|
/// 发起评论人的头像[faceUrl]
|
|
|
|
|
/// 发起评论人的[nickName]
|
|
|
|
|
/// 评论的内容[comment]
|
|
|
|
|
/// 评论的id[commentID]
|
|
|
|
|
/// 被评论的视频[vlogID]
|
|
|
|
|
/// 被评论的视频首帧图[firstFrameImg]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.interactionAt:
|
|
|
|
|
// 视频评论中@互关好友
|
|
|
|
|
|
|
|
|
|
/// 发起@人的[userID]
|
|
|
|
|
/// 发起@人的[nickName]
|
|
|
|
|
/// 发起@人的头像[faceUrl]
|
|
|
|
|
/// 关联视频的首帧图[firstFrameImg]
|
|
|
|
|
/// 关联视频的[vlogID]
|
|
|
|
|
/// 评论的id[commentID]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.interactionLike:
|
|
|
|
|
// 点赞
|
|
|
|
|
|
|
|
|
|
/// 发起点赞人的[userID]
|
|
|
|
|
/// 发起点赞人的头像[faceUrl]
|
|
|
|
|
/// 发起点赞人的[nickName]
|
|
|
|
|
/// 被点赞视频的[vlogID]
|
|
|
|
|
/// 被点赞视频的封面图[firstFrameImg]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.interactionReply:
|
|
|
|
|
// 回复评论
|
|
|
|
|
/// 回复人的[userID]
|
|
|
|
|
/// 回复人的[faceUrl]
|
|
|
|
|
/// 回复人的[nickName]
|
|
|
|
|
/// 关联视频的[vlogID]
|
|
|
|
|
/// 关联视频的首帧图[firstFrameImg]
|
|
|
|
|
/// 被回复评论的[commentID]
|
|
|
|
|
/// 回复的评论内容[comment]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.orderRecharge:
|
|
|
|
|
// 充值成功通知
|
|
|
|
|
/// 订单编号[orderID]
|
|
|
|
|
/// 充值金额[amount]
|
|
|
|
|
/// 充值后帐户余额[totalAmount]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.orderPay:
|
|
|
|
|
// 订单交易结果通知(商品购买成功后)
|
|
|
|
|
/// 订单编号[orderID]
|
|
|
|
|
/// 订单金额[amount]
|
|
|
|
|
/// 商品名称[name]
|
|
|
|
|
/// 商品描述[describe]
|
|
|
|
|
/// 商品价格[price]
|
|
|
|
|
/// 商品主图[pic]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.orderRefund:
|
|
|
|
|
// 订单退款通知
|
|
|
|
|
/// 订单编号[orderID]
|
|
|
|
|
/// 订单金额[amount]
|
|
|
|
|
/// 商品名称[name]
|
|
|
|
|
/// 商品描述[describe]
|
|
|
|
|
/// 商品价格[price]
|
|
|
|
|
/// 商品主图[pic]
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.groupNotifyCheck:
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.groupNotifyAccpet:
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.groupNotifyFail:
|
|
|
|
|
return elment!.desc!;
|
|
|
|
|
case NotifyMessageTypeConstants.groupNotifyLeaveUp:
|
|
|
|
|
return elment!.desc!;
|
2025-07-21 15:46:30 +08:00
|
|
|
|
default:
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return '[未知消息类型2]';
|
2025-07-21 15:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
} catch (_) {
|
2025-08-21 10:50:38 +08:00
|
|
|
|
return '[未知消息类型3]';
|
2025-07-21 15:46:30 +08:00
|
|
|
|
}
|
|
|
|
|
}
|