mirror of
https://gitee.com/Zhaoxin59/my-chat_-client.git
synced 2026-02-13 16:41:48 +08:00
449 lines
11 KiB
C++
449 lines
11 KiB
C++
#include "datacenter.h"
|
||
|
||
namespace model
|
||
{
|
||
DataCenter* DataCenter::instance = nullptr;
|
||
|
||
DataCenter* DataCenter::getInstance()
|
||
{
|
||
if (instance == nullptr) {
|
||
instance = new DataCenter();
|
||
}
|
||
return instance;
|
||
}
|
||
|
||
DataCenter::~DataCenter()
|
||
{
|
||
//释放所有的成员
|
||
//此处就不必判断nullptr,直接delete即可
|
||
//c++标准中明确规定了,对nullptr进行delete是合法行为,不会有任何副作用
|
||
delete myself;
|
||
delete friendList;
|
||
delete chatSessionList;
|
||
delete memberList;
|
||
delete applyList;
|
||
delete recentMessages;
|
||
delete unreadMessageCount;
|
||
delete searchUserResult;
|
||
delete searchMessageResult;
|
||
}
|
||
|
||
DataCenter::DataCenter() : netClient(this)
|
||
{
|
||
//此处只是把这几个hash类型的属性进行new出实例,其他的QList都暂时不实例化
|
||
//主要是为了使用nullptr表示非法状态
|
||
//对于hash来说,不关心整个的QHash是否是nullptr,而是关心某个key对应的value是否存在
|
||
//通过key是否存在,也能表示该值是否有效
|
||
recentMessages = new QHash<QString, QList<Message>>();
|
||
memberList = new QHash<QString, QList<UserInfo>>();
|
||
unreadMessageCount = new QHash<QString, int>();
|
||
|
||
//加载数据
|
||
loadDataFile();
|
||
}
|
||
|
||
void DataCenter::initDataFile()
|
||
{
|
||
//构造出文件的路径,使用appData存储文件
|
||
QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||
QString filePath = basePath + "/ChatClient.json";
|
||
|
||
QDir dir;
|
||
if (!dir.exists(basePath)) {
|
||
//没有则进行目录的创建
|
||
dir.mkpath(basePath);
|
||
}
|
||
|
||
//构造好文件的路径之后,把文件创建出来
|
||
//写的方式打开,并且写入初始内容
|
||
QFile file(filePath);
|
||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||
LOG() << "initDataFile open file failed!!!" << file.errorString();
|
||
file.close();
|
||
return;
|
||
}
|
||
//打开成功,写入初始内容
|
||
QString data = "{\n\n}";
|
||
file.write(data.toUtf8());
|
||
file.close();
|
||
}
|
||
|
||
void DataCenter::saveDataFile()
|
||
{
|
||
QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||
QString filePath = basePath + "/ChatClient.json";
|
||
|
||
QFile file(filePath);
|
||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||
LOG() << "saveDataFile open file failed!!!" << file.errorString();
|
||
file.close();
|
||
return;
|
||
}
|
||
|
||
//按照json格式进行数据的写入
|
||
//这个对象可以当作map一样来使用
|
||
QJsonObject jsonObj;
|
||
jsonObj["loginSessionId"] = loginSessionId;
|
||
|
||
QJsonObject jsonUnread;
|
||
for (auto it = unreadMessageCount->begin(); it != unreadMessageCount->end(); ++it) {
|
||
//注意此处的qt迭代器使用和stl有区别(不是使用first和second)
|
||
jsonUnread[it.key()] = it.value();
|
||
}
|
||
jsonObj["unread"] = jsonUnread;
|
||
|
||
//把json写入文件
|
||
QJsonDocument jsonDoc(jsonObj);
|
||
QString s = jsonDoc.toJson();
|
||
file.write(s.toUtf8());
|
||
|
||
//关闭文件
|
||
file.close();
|
||
}
|
||
|
||
//加载文件,在DataCenter实例化就应该执行的
|
||
void DataCenter::loadDataFile()
|
||
{
|
||
//确保加载之前就针对文件进行初始化操作
|
||
QString basePath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||
QString filePath = basePath + "/ChatClient.json";
|
||
|
||
//判定文件是否存在,不存在则初始化,并创建出空空白的json文件
|
||
QFileInfo fileInfo(filePath);
|
||
if (!fileInfo.exists()) {
|
||
initDataFile();
|
||
}
|
||
|
||
//按读方式打开文件
|
||
QFile file(filePath);
|
||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||
LOG() << "loadDataFile open file failed!!!" << file.errorString();
|
||
return;
|
||
}
|
||
|
||
//读取文件内容,解析为 JSON对象
|
||
QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll());
|
||
if (jsonDoc.isNull()) {
|
||
LOG() << "loadDataFile parsing the json file failed!!!";
|
||
file.close();
|
||
return;
|
||
}
|
||
|
||
QJsonObject jsonObj = jsonDoc.object();
|
||
this->loginSessionId = jsonObj["loginSessionId"].toString();
|
||
|
||
|
||
this->unreadMessageCount->clear();
|
||
QJsonObject jsonUnread = jsonObj["unread"].toObject();
|
||
for (auto it = jsonUnread.begin(); it != jsonUnread.end(); ++it) {
|
||
this->unreadMessageCount->insert(it.key(), it.value().toInt());
|
||
}
|
||
|
||
file.close();
|
||
}
|
||
|
||
void DataCenter::clearUnread(const QString& chatSessionId)
|
||
{
|
||
(*unreadMessageCount)[chatSessionId] = 0;
|
||
|
||
//手动保存一下结果到文件中
|
||
saveDataFile();
|
||
}
|
||
|
||
void DataCenter::addUnread(const QString& chatSessionId)
|
||
{
|
||
++(*unreadMessageCount)[chatSessionId];
|
||
|
||
//手动保存一下结果到文件
|
||
saveDataFile();
|
||
}
|
||
|
||
int DataCenter::getUnread(const QString& chatSessionId)
|
||
{
|
||
return (*unreadMessageCount)[chatSessionId];
|
||
}
|
||
|
||
void DataCenter::getMyselfAsync()
|
||
{
|
||
//DataCenter 只是负责“处理数据”,
|
||
//而真正负责网络进行通信,需要通过NetClient
|
||
netClient.getMyself(loginSessionId);
|
||
}
|
||
|
||
UserInfo* DataCenter::getMyselfsync()
|
||
{
|
||
return myself;
|
||
}
|
||
|
||
void DataCenter::resetMyself(std::shared_ptr<bite_im::GetUserInfoRsp> resp)
|
||
{
|
||
if (myself == nullptr) {
|
||
myself = new UserInfo();
|
||
}
|
||
const bite_im::UserInfo& userInfo = resp->userInfo();
|
||
myself->load(userInfo);
|
||
}
|
||
|
||
QList<UserInfo>* DataCenter::getFriendList()
|
||
{
|
||
return friendList;
|
||
}
|
||
|
||
void DataCenter::getFriendListAsync()
|
||
{
|
||
netClient.getFriendList(loginSessionId);
|
||
}
|
||
|
||
void DataCenter::resetFriendList(std::shared_ptr<bite_im::GetFriendListRsp> resp)
|
||
{
|
||
if (friendList == nullptr) {
|
||
friendList = new QList<UserInfo>();
|
||
}
|
||
friendList->clear();
|
||
|
||
QList<bite_im::UserInfo> friendListPB = resp->friendList();
|
||
for (auto& f : friendListPB) {
|
||
UserInfo userInfo;
|
||
userInfo.load(f);
|
||
friendList->push_back(userInfo);
|
||
}
|
||
|
||
}
|
||
|
||
QList<ChatSessionInfo>* DataCenter::getChatSessionList()
|
||
{
|
||
return chatSessionList;
|
||
}
|
||
|
||
void DataCenter::getChatSessionListAsync()
|
||
{
|
||
netClient.getChatSessionList(loginSessionId);
|
||
}
|
||
|
||
void DataCenter::resetChatSessionList(std::shared_ptr<bite_im::GetChatSessionListRsp> resp)
|
||
{
|
||
if (chatSessionList == nullptr) {
|
||
chatSessionList = new QList<ChatSessionInfo>();
|
||
}
|
||
chatSessionList->clear();
|
||
|
||
auto& chatSessionListPB = resp->chatSessionInfoList();
|
||
for (auto& c : chatSessionListPB) {
|
||
ChatSessionInfo chatSessionInfo;
|
||
chatSessionInfo.load(const_cast<bite_im::ChatSessionInfo&>(c));
|
||
chatSessionList->push_back(chatSessionInfo);
|
||
}
|
||
}
|
||
|
||
QList<UserInfo>* DataCenter::getApplyList()
|
||
{
|
||
return applyList;
|
||
}
|
||
|
||
void DataCenter::getApplyListAsync()
|
||
{
|
||
netClient.getApplyList(loginSessionId);
|
||
}
|
||
|
||
void DataCenter::resetApplyList(std::shared_ptr<bite_im::GetPendingFriendEventListRsp> resp)
|
||
{
|
||
if (applyList == nullptr) {
|
||
applyList = new QList<UserInfo>();
|
||
}
|
||
applyList->clear();
|
||
|
||
auto& eventList = resp->event();
|
||
for (auto& event : eventList) {
|
||
UserInfo userInfo;
|
||
userInfo.load(event.sender());
|
||
applyList->push_back(userInfo);
|
||
}
|
||
}
|
||
|
||
void DataCenter::getRecnetMessageListAsync(const QString& chatSessionId, bool updateUI)
|
||
{
|
||
netClient.getRecentMessageList(loginSessionId, chatSessionId, updateUI);
|
||
}
|
||
|
||
QList<Message>* DataCenter::getRecentMessageList(const QString& chatSessionId)
|
||
{
|
||
if (!recentMessages->contains(chatSessionId)) {
|
||
return nullptr;
|
||
}
|
||
return &(*recentMessages)[chatSessionId];
|
||
}
|
||
|
||
void DataCenter::resetRecentMessageList(const QString& chatSessionId, std::shared_ptr<bite_im::GetRecentMsgRsp> resp)
|
||
{
|
||
//拿到chatSessionId 对应的消息列表,并清空
|
||
//注意此处务必使用的是引用类型,才是修改哈希表内部的内容
|
||
QList<Message>& messageList = (*recentMessages)[chatSessionId];
|
||
messageList.clear();
|
||
|
||
//遍历响应结果列表
|
||
for (auto& m : resp->msgList()) {
|
||
Message message;
|
||
message.load(m);
|
||
|
||
messageList.push_back(message);
|
||
}
|
||
}
|
||
|
||
void DataCenter::sendTextMessageAsync(const QString& chatSessionId, const QString& content)
|
||
{
|
||
netClient.sendMessage(loginSessionId, chatSessionId, MessageType::TEXT_TYPE, content.toUtf8(), "");
|
||
}
|
||
|
||
void DataCenter::changeNicknameAsync(const QString& nickname)
|
||
{
|
||
netClient.changeNickname(loginSessionId, nickname);
|
||
}
|
||
|
||
void DataCenter::resetNickname(const QString& nickname)
|
||
{
|
||
if (myself == nullptr) {
|
||
return;
|
||
}
|
||
myself->nickname = nickname;
|
||
}
|
||
|
||
void DataCenter::changeDescriptionAsync(const QString& desc)
|
||
{
|
||
netClient.changeDescription(loginSessionId, desc);
|
||
}
|
||
|
||
void DataCenter::resetDescription(const QString& desc)
|
||
{
|
||
if (myself == nullptr) {
|
||
return;
|
||
}
|
||
myself->description = desc;
|
||
}
|
||
|
||
void DataCenter::getVerifyCodeAsync(const QString& email)
|
||
{
|
||
//这个操作,不需要loginSessionId
|
||
//
|
||
netClient.getVerifyCode(email);
|
||
}
|
||
|
||
void DataCenter::resetVerifyCodeId(const QString& verifyCodeId)
|
||
{
|
||
this->currentVerifyCodeId = verifyCodeId;
|
||
}
|
||
|
||
const QString& DataCenter::getVerifyCodeId() const
|
||
{
|
||
return currentVerifyCodeId;
|
||
}
|
||
|
||
void DataCenter::changePhoneAsync(const QString& email, const QString& verifyCodeId, const QString& verifyCode)
|
||
{
|
||
netClient.changeEmail(loginSessionId, email, verifyCodeId, verifyCode);
|
||
}
|
||
|
||
void DataCenter::resetPhone(const QString& email)
|
||
{
|
||
if (myself == nullptr) {
|
||
return;
|
||
}
|
||
myself->phone = email;
|
||
}
|
||
|
||
void DataCenter::changeAvatarAsync(const QByteArray& imageBytes)
|
||
{
|
||
netClient.changeAvatar(loginSessionId, imageBytes);
|
||
}
|
||
|
||
void DataCenter::resetAvatar(const QByteArray& avatar)
|
||
{
|
||
if (myself == nullptr) {
|
||
return;
|
||
}
|
||
myself->avatar = makeIcon(avatar);
|
||
}
|
||
|
||
ChatSessionInfo* DataCenter::findChatSessionById(const QString& chatSessionId)
|
||
{
|
||
if (chatSessionList == nullptr) {
|
||
return nullptr;
|
||
}
|
||
for (auto& info : *chatSessionList) {
|
||
if (info.chatSessionId == chatSessionId) {
|
||
return &info;
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
ChatSessionInfo* DataCenter::findChatSessionByUserId(const QString& userId)
|
||
{
|
||
if (chatSessionList == nullptr) {
|
||
return nullptr;
|
||
}
|
||
for (auto& info : *chatSessionList) {
|
||
if (info.userId == userId) {
|
||
return &info;
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
void DataCenter::topCurrentChatSessionId(const ChatSessionInfo& chatSessionInfo)
|
||
{
|
||
if (chatSessionList == nullptr) {
|
||
return;
|
||
}
|
||
|
||
//把这个元素从列表中找到
|
||
auto it = chatSessionList->begin();
|
||
for (; it != chatSessionList->end(); ++it) {
|
||
if (it->chatSessionId == chatSessionInfo.chatSessionId) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (it == chatSessionList->end()) {
|
||
//上面的循环没有找到匹配的元素,直接返回,正常来说,不会走这个逻辑
|
||
return;
|
||
}
|
||
|
||
//删除并重新插入头部
|
||
ChatSessionInfo backup = chatSessionInfo;
|
||
chatSessionList->erase(it);
|
||
|
||
//把备份的元素插入到头部
|
||
chatSessionList->push_front(backup);
|
||
}
|
||
|
||
UserInfo* DataCenter::findFriendById(const QString& userId)
|
||
{
|
||
if (this->friendList == nullptr) {
|
||
return nullptr;
|
||
}
|
||
for (auto& f : *friendList) {
|
||
if (f.userId == userId) {
|
||
return &f;
|
||
}
|
||
}
|
||
return nullptr;
|
||
}
|
||
|
||
void DataCenter::setCurrentChatSessionId(const QString& chatSessionId)
|
||
{
|
||
this->currentChatSessionId = chatSessionId;
|
||
}
|
||
|
||
const QString& DataCenter::getCurrentSessionId()
|
||
{
|
||
return currentChatSessionId;
|
||
}
|
||
|
||
void DataCenter::addMessage(const Message& message)
|
||
{
|
||
QList<Message>& messageList = (*recentMessages)[message.chatSessionId];
|
||
messageList.push_back(message);
|
||
}
|
||
|
||
} //end namespace model
|