Files
MyChat_Client/model/data.h
2025-06-08 20:20:37 +08:00

311 lines
10 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include <QDateTime>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QIcon>
#include <QString>
#include <QUuid>
#include "base.qpb.h"
// 创建命名空间
namespace model {
///////////////////////////
//工具函数,后续很多模块可能会用到
///////////////////////////
//获取仅当前的源文件名
static inline QString getFileName(const QString& path) {
QFileInfo fileinfo(path);
return fileinfo.fileName();
}
//封装一个宏作为日志打印的方式
#define TAG QString("[%1:%2]").arg(model::getFileName(__FILE__), QString::number(__LINE__))
#define LOG() qDebug().noquote() << TAG
//避免链接阶段出现“函数重定义的问题”
static inline QString formatTime(int64_t timestamp) {
//先把时间戳转换为datetime对象
QDateTime datetime = QDateTime::fromSecsSinceEpoch(timestamp);
//把datetime对象转化为格式化的时间
return datetime.toString("MM-dd HH:mm:ss");
}
//通过这个函数得到秒级别的时间
static inline int64_t getTime() {
return QDateTime::currentSecsSinceEpoch();
}
//根据QByteArray转换为QIcon
static inline QIcon makeIcon(const QByteArray& byteArray) {
//存储和操作图像数据的类
QPixmap pixmap;
pixmap.loadFromData(byteArray);
QIcon icon(pixmap);
return icon;
}
// 读写文件操作
// 从指定的文件中读取所有的二进制内容得到一个QByteArray
static inline QByteArray loadFileToByteArray(const QString& path) {
QFile file(path);
bool ok = file.open(QFile::ReadOnly);
if(!ok) {
qDebug() << "文件打开失败!!!";
return QByteArray();
}
QByteArray content = file.readAll();
file.close();
return content;
}
//将QByteArray的内容写入到某个指定的文件里
static inline void writeByteArrayToFile(const QString& path, const QByteArray& content) {
QFile file(path);
bool ok = file.open(QFile::WriteOnly);
if(!ok) {
qDebug() << "文件打开失败!!!";
return;
}
file.write(content);
file.flush();
file.close();
}
///////////////////////////
// 用户信息
///////////////////////////
class UserInfo {
public:
//初始化,避免一些随机值可能的负面影响
QString userId = ""; //用户编号
QString nickname = ""; //用户昵称
QString description = ""; //用户签名
QString phone = ""; //手机号码
QIcon avatar; //用户头像
//从protobuffer的UserInfo对象转换为当前代码的UserInfo对象
void load(const bite_im::UserInfo& userInfo) {
this->userId = userInfo.userId();
this->nickname = userInfo.nickname();
this->phone = userInfo.phone();
this->description = userInfo.description();
if (userInfo.avatar().isEmpty()) {
//使用默认的头像即可
this->avatar = QIcon(":resource/image/defaultAvatar.png");
}
else {
this->avatar = makeIcon(userInfo.avatar());
}
}
};
///////////////////////////
//消息信息
///////////////////////////
enum MessageType {
TEXT_TYPE, //文本消息
IMAGE_TYPE, //图片消息
FILE_TYPE, //文件消息
SPEECH_TYPE //语音消息
};
class Message {
public:
QString messageId = ""; //消息的编号
QString chatSessionId = ""; //消息所属会话的编号
QString time = ""; //消息的时间,通过格式化的方式来表示
MessageType messageType = TEXT_TYPE; //消息类型
UserInfo sender; //发送者信息
QByteArray content; //消息的正文内容
QString fileId = ""; //文件的身份标识,当为文件,图片,语音,视频有效,当为文本则为""
QString fileName = ""; //文件名称
static Message makeMessage(MessageType messageType, const QString& chatSessionId, const UserInfo& sender,
const QByteArray& content, const QString& extraInfo) {
if(messageType == TEXT_TYPE) {
return makeTextMessage(chatSessionId, sender, content);
} else if(messageType == IMAGE_TYPE) {
return makeImageMessage(chatSessionId, sender, content);
} else if(messageType == FILE_TYPE) {
return makeFileMessage(chatSessionId, sender, content, extraInfo);
} else if(messageType == SPEECH_TYPE) {
return makeSpeechMessage(chatSessionId, sender, content);
} else {
//触发了未知消息类型
return Message();
}
}
void load(const bite_im::MessageInfo& messageInfo) {
this->messageId = messageInfo.messageId();
this->chatSessionId = messageInfo.chatSessionId();
this->time = formatTime(messageInfo.timestamp());
this->sender.load(messageInfo.sender());
//设置消息的类型
auto type = messageInfo.message().messageType();
if (type == bite_im::MessageTypeGadget::MessageType::STRING) {
this->messageType = TEXT_TYPE;
this->content = messageInfo.message().stringMessage().content().toUtf8();
}
else if (type == bite_im::MessageTypeGadget::MessageType::IMAGE) {
this->messageType = IMAGE_TYPE;
if (messageInfo.message().imageMessage().hasImageContent()) {
this->content = messageInfo.message().imageMessage().imageContent();
}
if (messageInfo.message().imageMessage().hasFileId()) {
this->fileId = messageInfo.message().imageMessage().fileId();
}else if (type == bite_im::MessageTypeGadget::MessageType::FILE) {
this->messageType = FILE_TYPE;
if (messageInfo.message().fileMessage().hasFileContents()) {
this->content = messageInfo.message().fileMessage().fileContents();
}
if (messageInfo.message().fileMessage().hasFileId()) {
this->fileId = messageInfo.message().fileMessage().fileId();
}
this->fileName = messageInfo.message().fileMessage().fileName();
}
else if (type == bite_im::MessageTypeGadget::MessageType::SPEECH) {
this->messageType = SPEECH_TYPE;
if (messageInfo.message().speechMessage().hasFileContents()) {
this->content = messageInfo.message().speechMessage().fileContents();
}
if (messageInfo.message().speechMessage().hasFileId()) {
this->fileId = messageInfo.message().speechMessage().fileId();
}
}
else {
// 错误的类型, 啥都不做了, 只是打印一个日志
LOG() << "非法的消息类型! type=" << type;
}
}
}
private:
static QString makeId() {
//Uuid这东西背后也是一套算法能够生成“全球唯一的身份标识”
//Qt对UUID也有封装
//{75eb37e5-5af5-4bfb-8d0e-5261038a9107}(16进制的整数)
return "M" + QUuid::createUuid().toString().mid(25, 12);
}
static Message makeTextMessage(const QString& chatSessionId,const UserInfo& sender, const QByteArray& content) {
Message message;
//此处需要确保生成的messageId是唯一的
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = TEXT_TYPE;
//对于文本消息来说,以下属性并不使用,所以设置为""
message.fileId = "";
message.fileName = "";
return message;
}
static Message makeImageMessage(const QString& chatSessionId,const UserInfo& sender, const QByteArray& content) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = IMAGE_TYPE;
//后续使用时再进一步进行设置
message.fileId = "";
//此处并不使用,设置为""
message.fileName = "";
return message;
}
static Message makeFileMessage(const QString& chatSessionId,const UserInfo& sender, const QByteArray& content, const QString& fileName) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = FILE_TYPE;
//后续使用时再进一步进行设置
message.fileId = "";
//此处并不使用,设置为""
message.fileName = fileName;
return message;
}
static Message makeSpeechMessage(const QString& chatSessionId,const UserInfo& sender, const QByteArray& content) {
Message message;
message.messageId = makeId();
message.chatSessionId = chatSessionId;
message.sender = sender;
message.time = formatTime(getTime());
message.content = content;
message.messageType = SPEECH_TYPE;
//后续使用时再进一步进行设置
message.fileId = "";
//此处并不使用,设置为""
message.fileName = "";
return message;
}
};
///////////////////////////
//会话信息
///////////////////////////
class ChatSessionInfo {
public:
QString chatSessionId = ""; //会话编号
QString chatSessionName = ""; //会话名字(单聊或群聊)
Message lastMessage; //表示会话的最新消息
QIcon avatar; //会话的头像(单聊或群聊)
QString userId = ""; //(单聊为对方的id群聊为"")
void load(bite_im::ChatSessionInfo& chatSessionInfo) {
this->chatSessionId = chatSessionInfo.chatSessionId();
this->chatSessionName = chatSessionInfo.chatSessionName();
if (chatSessionInfo.hasSingleChatFriendId()) {
this->userId = chatSessionInfo.singleChatFriendId();
}
if (chatSessionInfo.hasPrevMessage()) {
lastMessage.load(chatSessionInfo.prevMessage());
}
if (chatSessionInfo.hasAvatar() && !chatSessionInfo.avatar().isEmpty()) {
//如果有头像,则设置这个头像
this->avatar = makeIcon(chatSessionInfo.avatar());
}
else {
//如果没有,则会根据是单聊还是群聊,使用不同的默认头像
if (userId != "") {
//单聊
this->avatar = QIcon(":/resource/image/defaultAvatar.png");
}
else {
//群聊
this->avatar = QIcon(":/resource/image/groupAvatar.png");
}
}
}
};
} //end namespace model