Files
51dj_android/lib/im_manager/model/im_message_resp.dart
T
2026-10-08 11:37:25 +07:00

204 lines
6.2 KiB
Dart

import 'package:flutter_mm_core/im_core/model/model_conversation.dart';
import 'package:flutter_mm_core/im_core/model/model_message.dart';
import 'package:flutter_mm_core/im_core/model/model_user_info.dart';
import 'package:jydj/tools_base/global_store/store.dart';
import '../im_ad/im_ad_item.dart';
/// 会话
class IMSessionModel {
int? peerId;
String? avatar;
String? nickName;
String? lastText;
String? updatedAt;
int? messageType;
int seq = 0;
// 对方在线状态,来自 IM SDK 的 ModelConversation.onlineInfo.online
bool? online;
// SDK 内部会话主键(${otherId}_${isGroup}),用于 setConversationRead 等 API
String? primaryId;
// SDK 的 IM userId(区分业务 peerId);私信详情用它做精确路由
int? imUserId;
int? unreadCount; // 未读数
ImAdItem? adItem;
bool get isAdStyle => adItem != null;
bool get hasUnRead => (unreadCount ?? 0) > 0;
String? get updatedYMD {
if (updatedAt?.split(" ").isNotEmpty == true) {
return updatedAt?.split(" ").first;
}
if (updatedAt?.split("T").isNotEmpty == true) {
return updatedAt?.split("T").first;
}
return updatedAt;
}
ModelConversation? originModel;
IMSessionModel({this.peerId, this.nickName, this.avatar});
static List<IMSessionModel> covertData(ModelConversationListResult conList) {
List<IMSessionModel> sessionList = [];
for (int i = 0; i < (conList.conversations.length); i++) {
ModelConversation conversation = conList.conversations[i];
ModelUserInfo? userInfo = conversation.userInfo;
IMSessionModel sessionInfo = IMSessionModel();
sessionInfo.peerId = userInfo?.id ?? int.tryParse(conversation.targetId ?? '');
sessionInfo.avatar = userInfo?.imgUrl;
sessionInfo.nickName = userInfo?.name;
sessionInfo.lastText = conversation.content;
sessionInfo.online = conversation.onlineInfo?.online;
sessionInfo.primaryId = conversation.primaryId;
sessionInfo.unreadCount = conversation.unreadCount;
sessionInfo.messageType = conversation.messageType;
sessionInfo.imUserId = int.tryParse(conversation.targetId ?? '');
sessionInfo.seq = conversation.seq;
sessionInfo.originModel = conversation;
if (conversation.time > 0) {
var dateTimeStr = _conversationTimeToIsoString(conversation.time);
sessionInfo.updatedAt = dateTimeStr;
}
sessionList.add(sessionInfo);
}
return sessionList;
}
static String _conversationTimeToIsoString(int rawTime) {
if (rawTime <= 0) return '';
final milliseconds = rawTime >= 1000000000000 ? rawTime : rawTime * 1000;
return DateTime.fromMillisecondsSinceEpoch(milliseconds).toString();
}
}
class IMMessageResp {
bool? enabled;
int? userId;
int? imUserId;
int? peerId;
int? peerImUserId;
List<IMMessageModel>? messages;
IMMessageResp();
IMMessageResp.fromJson(Map<String, dynamic> json) {
enabled = json['enabled'];
userId = json['userId'];
imUserId = json['imUserId'];
peerId = json['peerId'];
peerImUserId = json['peerImUserId'];
if (json['messages'] is List) {
messages = [];
json['messages'].forEach((v) {
messages!.add(IMMessageModel.fromJson(v));
});
}
}
}
class IMMessageModel {
String? messageId;
String? senderId;
String? receiverId;
String? content;
dynamic messageType;
int? messageState; // 发送状态 0发送中 1失败 2成功 (MessageSendStatus)
String? localId; // 客户端本地ID,发送中/失败状态更新用
int? seq;
int? createdAt;
int? timestamp;
bool? fromSelf;
String? senderNickName;
String? senderAvatar;
String? receiverNickName;
String? receiverAvatar;
/// 业务扩展字段,服务端透传原始字符串;内容不要求是 JSON。
String? extra;
String? url; //文件地址
String? localPath; //下载后的本地路径
ModelMessage? originMsgModel;
IMMessageModel();
IMMessageModel.fromJson(Map<String, dynamic> json) {
receiverAvatar = json['receiverAvatar'];
receiverNickName = json['receiverNickName'];
senderAvatar = json['senderAvatar'];
senderNickName = json['senderNickName'];
messageId = json['messageId'];
senderId = json['senderId']?.toString();
receiverId = json['receiverId']?.toString();
content = json['content'];
messageType = json['messageType'];
seq = json['seq'];
createdAt = json['createdAt'];
fromSelf = json['fromSelf'];
}
/// 图片消息有两种:
/// - chatMessageType=2 (SDK 原生 IMAGE):用 m.url / m.localPath(完整 CDN 链接)
/// - chatMessageType=100 (CUSTOMIZED):双层解析 m.extra 拿 url
static IMMessageModel convertModel(ModelMessage model) {
IMMessageModel msgModel = IMMessageModel();
msgModel.originMsgModel = model;
msgModel.messageId = model.messageId;
msgModel.content = model.content;
msgModel.senderId = model.senderID;
msgModel.receiverId = model.receiverID;
msgModel.createdAt = model.timestamp;
msgModel.timestamp = model.timestamp;
msgModel.seq = model.sequence;
msgModel.messageType = model.chatMessageType;
msgModel.messageState = model.messageState;
msgModel.localId = model.localId;
if (model.senderID == globalStore.meInfo?.imUserId?.toString()) {
msgModel.fromSelf = true;
}
final type = model.chatMessageType ?? 0;
if (type == 2) {
// SDK 原生 IMAGE
if ((model.url ?? '').isNotEmpty) {
msgModel.url = model.url;
} else if ((model.localPath ?? '').isNotEmpty) {
msgModel.localPath = model.localPath;
}
}
msgModel.extra = model.extra;
return msgModel;
}
String? get image {
if (url?.isNotEmpty == true) {
return url;
}
if (localPath?.isNotEmpty == true) {
return localPath;
}
return null;
}
}
class IMSendFileInfo {
double? height;
int? type; // 1 图片, 2文件
String? url;
IMSendFileInfo({this.height, this.type, this.url});
IMSendFileInfo.fromJson(Map<String, dynamic> json) {
height = json['height'];
type = json['type'];
url = json['url'] ?? '';
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = <String, dynamic>{};
data['height'] = height;
data['type'] = type;
data['url'] = url;
return data;
}
}