AIChatProject
基于Qt框架的智能即时聊天室项目

AIChatProject - By Wild_Pointer

AIChatProject是一套基于Qt框架的开源智能即时聊天室系统,在经过多次反复优化迭代下成长为多功能的交友应用。
源码可自由下载使用,更多信息参考个人博客:
在使用AiChatProject进行二次开发(策略、模块等)的过程中有任何疑问,可通过QQ邮箱或者谷歌邮箱,也欢迎在分享你的使用心得或者使用中产生的bug,方便作者后续更新迭代!
AIChatProject介绍
智能即时聊天室系统(AIChatProject)是一个高效、灵活的即时通讯解决方案。它融合了百度的开源大型语言模型——文心一言,通过API接口实现深度集成。系统专为聊天和文件传输等核心功能设计,以便快速搭建定制化的即时通讯应用。采用客户端/服务器(C/S)架构,确保了应用的稳定性和扩展性。数据存储依托于MySQL数据库,保障了数据的安全性和高效管理。客户端之间的信息交换通过JSON格式实现,简洁而高效。此外,系统利用TCP协议进行数据传输,确保了通信的可靠性和稳定性。
项目技术栈:
数据库
- MySQL
技术栈
C++11
Qt6
线程池
TCP协议
POST方法
JSON格式
- 模块设计概述:
- 数据传输:
- 通过QTcpSocket使用TCP协议对客户端与服务端之间的数据进行传输,并且使用JSON格式对传递的数据进行格式化操作。服务端返回的JSON格式自带错误码,方便客户端对响应的请求反馈给用户
- 线程模块:
- 针对AIChatProject项目,作者采用QThreadPool模块,在客户端与服务端都定义了多线程模块。针对服务端共有两个线程,一个是数据库链接线程,一个是处理服务端数据线程。针对客户端定义了两个线程,分别用于处理与服务端数据传输以及对智能聊天数据的传输
- AI智能模块:
- 通过QNetWork模块,对其鉴权元素进行处理,对特定的地址进行POST请求,获取Token。后续使用Token对发出的询问进行加密,返回智能机器人的响应信息
- 列表模块:
- 针对列表模块使用了模型/视图架构,针对好友,群聊以及智能聊天机器人分别对其映射,将数据与视图隔离,规范了代码,降低耦合
- 检测模块:
- 针对用户作输入操作时,该项目采用正则表达式检测用户异常输出,防止恶意的SQL注入攻击及不规范的输入,减少服务端的恶意请求,降低成本
- 加密模块:
- 针对用户登录时,项目使用MD5加密算法对其密码等数据进行加密,减少用户被恶意攻击,数据泄漏的几率
环境准备
- 推荐使用Qt6版本进行部署
- 支持的数据库版本:MySQL 8.0
- 支持的系统版本:Windows 10以上
- 支持的C++版本:C++ 11/64位(推荐使用C++ 11)
Qt模块准备
下载源码后,需要在Pro文件导入以下模块:
sqlnetworkwebsockets注意:源码中的Pro文件以及列举了Qt6所需的所有模块,其中Qt6不支持MySQL数据库驱动,需要手动配置
代码示例
AIChatProject采用了统一的命名和注释格式,具体可参考以下代码:
/* 处理保存加密请求返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_EncryptResult(const QJsonObject &jsonObject){ QString returnData = jsonObject["return"].toString(); //返回服务器处理加密信息结果给主线程处理 if(returnData == "True"){ emit return_SaveEncryptResult(true,""); return 1; }else if(returnData == "False"){ emit return_SaveEncryptResult(false,""); return 0; }}其中函数命名使用驼峰法,并且注释中带有函数参数以及默认返回值int,方便后续对异常的捕获进行诊断
运行示例

作者留言
个人博客:wild-pointer.top
通过QQ邮箱联系我:3020922258@qq.com
通过谷歌邮箱联系我:wildpointer794@gmail.com
语言组成
- C++
- 98.5%
- QMake
- 1.5%
文件结构
查看完整文件清单(206 个文件)
Object/MyObject.pro Object/image/Image.qrc Object/image/icons/Chat/logo_Show.png Object/image/icons/Chat/logo_Show2.png Object/image/icons/Emotion/lab_1.png Object/image/icons/Emotion/lab_10.png Object/image/icons/Emotion/lab_11.png Object/image/icons/Emotion/lab_12.png Object/image/icons/Emotion/lab_13.png Object/image/icons/Emotion/lab_14.png Object/image/icons/Emotion/lab_15.png Object/image/icons/Emotion/lab_16.png Object/image/icons/Emotion/lab_17.png Object/image/icons/Emotion/lab_18.png Object/image/icons/Emotion/lab_19.png Object/image/icons/Emotion/lab_2.png Object/image/icons/Emotion/lab_20.png Object/image/icons/Emotion/lab_21.png Object/image/icons/Emotion/lab_22.png Object/image/icons/Emotion/lab_23.png Object/image/icons/Emotion/lab_24.png Object/image/icons/Emotion/lab_25.png Object/image/icons/Emotion/lab_26.png Object/image/icons/Emotion/lab_27.png Object/image/icons/Emotion/lab_28.png Object/image/icons/Emotion/lab_29.png Object/image/icons/Emotion/lab_3.png Object/image/icons/Emotion/lab_30.png Object/image/icons/Emotion/lab_4.png Object/image/icons/Emotion/lab_5.png Object/image/icons/Emotion/lab_6.png Object/image/icons/Emotion/lab_7.png Object/image/icons/Emotion/lab_8.png Object/image/icons/Emotion/lab_9.png Object/image/icons/becurrent/1.png Object/image/icons/becurrent/2.png Object/image/icons/becurrent/3.png Object/image/icons/becurrent/4.png Object/image/icons/becurrent/Ai.png Object/image/icons/becurrent/Ai2.png Object/image/icons/becurrent/Img.png Object/image/icons/becurrent/QQ_Logo.png Object/image/icons/becurrent/addfriend.png Object/image/icons/becurrent/arrow-down-blue.png Object/image/icons/becurrent/arrow-down.png Object/image/icons/becurrent/arrow-up-bold.png Object/image/icons/becurrent/close.png Object/image/icons/becurrent/emotion.png Object/image/icons/becurrent/file.png Object/image/icons/becurrent/fileinfo.png Object/image/icons/becurrent/minus.png Object/image/icons/becurrent/qqicon_p_blue.png Object/image/icons/becurrent/qqicon_p_gray.png Object/image/icons/becurrent/qqicon_q_blue.png Object/image/icons/becurrent/qqicon_q_gray.png Object/image/icons/becurrent/record.png Object/image/icons/becurrent/search.png Object/image/icons/becurrent/security.png Object/image/icons/becurrent/setting.png Object/image/icons/logo/Register_Img.gif Object/image/icons/logo/Top.gif Object/image/icons/logo/addWidget.gif Object/image/qssFile/scrollbar.qss Object/image/user/Ai_Logn.png Object/image/user/My.jpg Object/image/user/headImg_1.jpg Object/image/user/headImg_2.jpg Object/image/user/headImg_3.jpg Object/image/user/headImg_4.jpg Object/image/user/headImg_5.jpg Object/image/user/headImg_6.jpg Object/image/user/headImg_7.jpg Object/image/user/headImg_8.jpg Object/image/user/touxiang01.jpg Object/image/user/touxiang02.jpg Object/main.cpp Object/modelFile/AiList_Model.cpp Object/modelFile/AiList_Model.h Object/modelFile/FriendList_Model.cpp Object/modelFile/FriendList_Model.h Object/modelFile/GroupList_Model.cpp Object/modelFile/GroupList_Model.h Object/srcFile/AiSrc/AI.cpp Object/srcFile/AiSrc/AI.h Object/srcFile/AiSrc/AiThread.cpp Object/srcFile/AiSrc/AiThread.h Object/srcFile/FileSrc/FileInfo.h Object/srcFile/FileSrc/FileThread.h Object/srcFile/HOST.cpp Object/srcFile/HOST.h Object/srcFile/JSON.h Object/srcFile/NetWork.cpp Object/srcFile/NetWork.h Object/srcFile/SQL.h Object/srcFile/TcpThread.cpp Object/srcFile/TcpThread.h Object/srcFile/USER.cpp Object/srcFile/USER.h Object/srcFile/UdpThread.h Object/uiFile/AiModel/AiChat.cpp Object/uiFile/AiModel/AiChat.h Object/uiFile/AiModel/AiChat.ui Object/uiFile/AiModel/AiInfo.cpp Object/uiFile/AiModel/AiInfo.h Object/uiFile/AiModel/AiInfo.ui Object/uiFile/Chatbubble/ChatBox.cpp Object/uiFile/Chatbubble/ChatBox.h Object/uiFile/Chatbubble/Recvbox.cpp Object/uiFile/Chatbubble/Recvbox.h Object/uiFile/Chatbubble/Recvbox.ui Object/uiFile/Chatbubble/Sendbox.cpp Object/uiFile/Chatbubble/Sendbox.h Object/uiFile/Chatbubble/Sendbox.ui Object/uiFile/Chatbubble/recvFilebox.cpp Object/uiFile/Chatbubble/recvFilebox.h Object/uiFile/Chatbubble/recvFilebox.ui Object/uiFile/Chatbubble/sendFilebox.cpp Object/uiFile/Chatbubble/sendFilebox.h Object/uiFile/Chatbubble/sendFilebox.ui Object/uiFile/Emotion.h Object/uiFile/Emotion/Emotion.cpp Object/uiFile/Emotion/Emotion.h Object/uiFile/Emotion/Emotion.ui Object/uiFile/FriendModel/FriendChat.cpp Object/uiFile/FriendModel/FriendChat.h Object/uiFile/FriendModel/FriendChat.ui Object/uiFile/FriendModel/FriendInfo.cpp Object/uiFile/FriendModel/FriendInfo.h Object/uiFile/FriendModel/FriendInfo.ui Object/uiFile/GroupModel/GroupChat.cpp Object/uiFile/GroupModel/GroupChat.h Object/uiFile/GroupModel/GroupChat.ui Object/uiFile/GroupModel/GroupInfo.cpp Object/uiFile/GroupModel/GroupInfo.h Object/uiFile/GroupModel/GroupInfo.ui Object/uiFile/HeadImg.cpp Object/uiFile/HeadImg.h Object/uiFile/HeadImg.ui Object/uiFile/Login.cpp Object/uiFile/Login.h Object/uiFile/Login.ui Object/uiFile/Register.cpp Object/uiFile/Register.h Object/uiFile/Register.ui Object/uiFile/SetUp/AiSetup.cpp Object/uiFile/SetUp/AiSetup.h Object/uiFile/SetUp/AiSetup.ui Object/uiFile/SetUp/FileSetup.cpp Object/uiFile/SetUp/FileSetup.h Object/uiFile/SetUp/FileSetup.ui Object/uiFile/SetUp/SetUp.cpp Object/uiFile/SetUp/SetUp.h Object/uiFile/SetUp/SetUp.ui Object/uiFile/SetUp/UserSetup.cpp Object/uiFile/SetUp/UserSetup.h Object/uiFile/SetUp/UserSetup.ui Object/uiFile/Setup.cpp Object/uiFile/UserInfo.cpp Object/uiFile/UserInfo.h Object/uiFile/UserInfo.ui Object/uiFile/addinfo/AddFriend.cpp Object/uiFile/addinfo/AddFriend.h Object/uiFile/addinfo/AddFriend.ui Object/uiFile/addinfo/AddGroup.cpp Object/uiFile/addinfo/AddGroup.h Object/uiFile/addinfo/AddGroup.ui Object/uiFile/addinfo/AddInfo.cpp Object/uiFile/addinfo/AddInfo.h Object/uiFile/addinfo/AddInfo.ui Object/uiFile/addinfo/AddVerify.cpp Object/uiFile/addinfo/AddVerify.h Object/uiFile/addinfo/AddVerify.ui README.md README_IMG/1.gif README_IMG/logo.png Server/MyServer.pro Server/icons.qrc Server/image/becurrent/IPdizhi_1.png Server/image/becurrent/close.png Server/image/becurrent/minus.png Server/image/icons.qrc Server/main.cpp Server/mainwindow.cpp Server/srcFile/UdpThread.cpp Server/srcFile/UdpThread.h Server/srcFile/sqlThread/SqlThread.cpp Server/srcFile/sqlThread/SqlThread.h Server/srcFile/tcpThread/TcpThread.cpp Server/srcFile/tcpThread/TcpThread.h Server/uiFile/FileInfo.cpp Server/uiFile/FileInfo.h Server/uiFile/FileInfo.ui Server/uiFile/GroupInfo.cpp Server/uiFile/GroupInfo.h Server/uiFile/GroupInfo.ui Server/uiFile/SqlInfo.cpp Server/uiFile/SqlInfo.h Server/uiFile/SqlInfo.ui Server/uiFile/UserInfo.cpp Server/uiFile/UserInfo.h Server/uiFile/UserInfo.ui Server/uiFile/mainWidget.cpp Server/uiFile/mainWidget.h Server/uiFile/mainWidget.ui 信息码示例.docx 通信协议文档.docx
关键源码
Object/srcFile/AiSrc/AI.cpp
#include "AI.h"#include <QDebug>AI::AI(){ //初始化对象 ai_Name = "智能机器人"; ai_Sign = "你好!我是小源,你的专属聊天机器人"; ai_ApiKey = ""; ai_ApiSecret = "";}AI::~AI(){}/* 设置机器人昵称 * name:设置的昵称*/int AI::handle_SetAiName(const QString &name){ ai_Name = name; return 1;}/* 设置机器人介绍 * sign:设置的介绍*/int AI::handle_SetAiSign(const QString &sign){ ai_Sign = sign; return 1;}/* 鉴权元素APIKey * ApiKey:设置的APIKey*/int AI::handle_SetApiKey(const QString &ApiKey){ ai_ApiKey = ApiKey; return 1;}/* 设置鉴权元素APISecret * ApiSecret:设置的APISecret*/int AI::handle_SetApiSecret(const QString &ApiSecret){ ai_ApiSecret = ApiSecret; return 1;}/* 设置全部对象 * ai_Name:机器人名称 ai_Sign:机器人介绍 * ai_ApiKey:鉴权元素APIKey ai_ApiSecret:鉴权元素APISecret*/int AI::handle_SetAllObject(const QString &ai_Name, const QString &ai_Sign, const QString &ai_ApiKey, const QString &ai_ApiSecret){ handle_SetAiName(ai_Name); handle_SetAiSign(ai_Sign); handle_SetApiKey(ai_ApiKey); handle_SetApiSecret(ai_ApiSecret); emit new_AIInfo(); return 1;}/* 获取机器人信息 * Type:信息类型 * 返回值:const QString&(具体机器人信息)*/const QString& AI::handle_GetAiInfo(setAiFlagbit flag){ //判断枚举值 switch (flag){ case aiName: return ai_Name; //返回用户数据 break; case aiSign: return ai_Sign; //返回用户账号 break; case aiAPIKey: return ai_ApiKey; //返回用户昵称 break; case aiAPISecret: return ai_ApiSecret;//返回用户性别 break; }}Object/srcFile/AiSrc/AiThread.cpp
#include "AiThread.h"AiThread::AiThread(QObject *parent) : QObject{parent} , QRunnable{}{ setAutoDelete(true); //设置自动析构}AiThread::AiThread(const QString& response, QObject *parent) : QRunnable{} , QObject{parent}{ setAutoDelete(true); //设置自动析构 responseData = response; //设置询问语句}AiThread::~AiThread(){}/* 解析回复语句 * text:回复语句 * 返回值:const QString&(解析后的语句)*/QString AiThread::handle_GetAnswerText(const QString &text){ QString hex; //定义正则表达式,用于获取指定result值后的数据 QRegularExpression regular("\"result\":\"(.*?)\""); QRegularExpressionMatch match = regular.match(text); QString matchedString = match.captured(); //捕获匹配正则表达式的数据 //设置正则表达式,用于匹配\x后面的数据 regular.setPattern("\\\\x([0-9A-Fa-f]{2})"); //迭代正则表达式匹配的结果 QRegularExpressionMatchIterator iteration = regular.globalMatch(matchedString); while (iteration.hasNext()) { //循环遍历寻找匹配数据 QRegularExpressionMatch match = iteration.next(); hex = match.captured(1); bool ok; int decimal = hex.toInt(&ok, 16); if (ok) { matchedString.replace(match.capturedStart(), match.capturedLength(), QString(QChar(decimal))); } } //文本处理 matchedString.replace("result\":\"", ""); matchedString.replace("\\n", "\n"); return matchedString;}/* 线程执行内容*/void AiThread::run(){ //解析回复语句 emit getAnswer(handle_GetAnswerText(responseData));}Object/srcFile/NetWork.cpp
#include "NetWork.h"NetWork::NetWork(){ //初始化对象 APIKey = ""; APISecret = ""; accessToken = ""; manager = new QNetworkAccessManager(this); connect(&my_AI, AI::new_AIInfo,this,NetWork::handle_NewKeyandSecret);}NetWork::~NetWork(){ if(reply!=nullptr){ reply->deleteLater(); delete reply; } delete manager;}/* 获取Accesstoken*/int NetWork::handle_GetAccessToken(){ if (reply->error() == QNetworkReply::NoError) { QByteArray responseData = reply->readAll(); //修改正则表达式 Regex.setPattern("\"access_token\":\"([^\"]+)\""); //在JSON字符串中进行匹配 QRegularExpressionMatch match = Regex.match(responseData); // 如果找到匹配项,则提取access_token数据 accessToken = match.captured(1); if (match.hasMatch()) { accessToken = match.captured(1); return 1; } } else { accessToken = " "; //Token置为空 QMessageBox::warning(nullptr,"错误",reply->errorString(),QMessageBox::Ok); return 0; }}/* 更新鉴权元素*/int NetWork::handle_NewKeyandSecret(){ accessToken = " "; //将之前获取到的Token置为空 //设置鉴权元素 handle_SetAuthentication(my_AI.handle_GetAiInfo(AI::aiAPIKey),my_AI.handle_GetAiInfo(AI::aiAPISecret)); return 1;}/* 判断是否存在鉴权元素 * 返回值:bool(存在为真,不存在为假)*/bool NetWork::handle_InspectKeyandSecret(){ if(APIKey.isEmpty() || APISecret.isEmpty()){ QMessageBox::warning(nullptr,"错误","未设置APIKey或APISecret",QMessageBox::Ok); return false; } else if(accessToken.isEmpty()){ QMessageBox::warning(nullptr,"错误","token为空",QMessageBox::Ok); return false; } return true;}/* 设置鉴权元素*/int NetWork::handle_SetAuthentication(const QString &key, const QString &secret){ //更新APIKey和APISecret APIKey = key; APISecret = secret; //初始化POST请求的参数 QUrlQuery params; params.addQueryItem("grant_type", "client_credentials"); params.addQueryItem("client_id", APIKey); params.addQueryItem("client_secret", APISecret); QByteArray postData = params.toString(QUrl::FullyEncoded).toUtf8(); // 设置URL和请求头部 request.setUrl(QUrl("https://aip.baidubce.com/oauth/2.0/token")); request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); request.setRawHeader("Accept", "application/json"); //将请求数据作为第二个参数传递给post函数 if(reply!=nullptr){ reply->deleteLater(); } reply = manager->post(request, postData); connect(reply, &QNetworkReply::finished,this,&NetWork::handle_GetAccessToken); return 1;}/* 修改询问语句 * enquiretext:询问语句 * 返回值:QString&(修改后的询问语句)*/QString NetWork::handle_SetEnquireText(const QString& enquiretext){ //清空请求内容和回复语句 payload = ""; // 准备请求数据 QJsonObject messageObject; messageObject["role"] = "user"; messageObject["content"] = enquiretext; QJsonArray messagesArray; messagesArray.append(messageObject); QJsonObject requestBody; requestBody["messages"] = messagesArray; // 将JSON对象转换为字符串 QJsonDocument doc(requestBody); payload = doc.toJson(); // 设置请求头 QString url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + accessToken; request.setUrl(QUrl(url)); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); //发送POST请求 reply = manager->post(request, payload); // 等待响应完成 QEventLoop loop; QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); loop.exec(); // 读取响应数据 if (reply->error() == QNetworkReply::NoError) { return reply->readAll(); } else { QMessageBox::warning(nullptr,"错误",reply->errorString(),QMessageBox::Ok); return " "; }}Object/srcFile/TcpThread.cpp
#include "TcpThread.h"#include <QDebug>TcpThread::TcpThread(QObject *parent) : QObject{parent} , QRunnable{}{ //线程自动析构 setAutoDelete(true);}TcpThread::TcpThread(QTcpSocket *socket, QObject *parent) : QRunnable{}, QObject{parent}, server_DataService{socket}{ ok = true; //初始化线程状态 file_Name = ""; //文件名称 file_Path = ""; //文件保存路径 receiveSize = 0; //接收的文件大小 sendingSize = 0; //发送的文件大小 sendingType = " "; //发送的文件类型 setAutoDelete(true); //设置线程自动析构 sendingFileObj = " "; //发送文件的好友 isdisconnect = false; //初始化连接服务器状态 init_TcpConnect(); //初始化TCP链接信号槽 server_DataService->connectToHost("127.0.0.1",13020); //链接服务器}TcpThread::~TcpThread(){ server_DataService->deleteLater();}void TcpThread::run(){ while(ok);}////-----------------------------------处理文件模块函数---------------------------------------------------------/* 设置发送的文件大小 * value:文件大小*/int TcpThread::handle_SetSendingFileSize(qint64 value){ sendingSize = value; return 1;}/* 返回服务器同意接受文件Json*/int TcpThread::handle_FileStateAsJson(){ QJsonObject Json; Json.insert("type","FileState"); Json.insert("data","Yes"); QJsonDocument jsonDoc(Json); QByteArray byteArray = jsonDoc.toJson(QJsonDocument::Compact); sending_ToServer(byteArray); return 1;}/* 接收文件数据 * filedata:文件数据*/int TcpThread::handle_ReceiveFileData(QByteArray filedata){ qint64 len = file.write(filedata); //将接收到的数据写入文件 receiveSize += len; if(receiveSize == file_Size){ file.close(); receiveSize = 0; if(file_Type == "Img"){ emit relay_FriendImgToUserInfo(sendingFileObj,file_Path); }else{ emit handle_ShowReceiveFileSchedule(sendingFileObj,receiveSize); } } if(file_Type == "File"){ emit handle_ShowReceiveFileSchedule(sendingFileObj,receiveSize); } return 1;}/* 发送文件至服务端 * filePath:发送的文件路径*/int TcpThread::sending_FileToServer(const QString& filePath){ qint64 len = 0; qint64 sending = 0; file.setFileName(filePath); if(!file.open(QIODevice::ReadOnly)){ return 0; } do{ char buf[4*1024]; len = file.read(buf, sizeof(buf)); len = server_DataService->write(buf, len); sending += len; emit handle_ShowFileTransferSchedule(receiveFileObj,sending); if(sending == sendingSize){ //确保发送的字节数不超过文件大小 file.close(); break; } }while(len > 0); return 1;}/* 设置发送的文件类型 * type:文件类型*/int TcpThread::handle_SetSendingFileType(const QString &type){ sendingType = type; return 1;}/* 设置接收文件的好友 * Obj:接收文件的好友*/int TcpThread::handle_SetReceiveFileObj(const QString &Obj){ receiveFileObj = Obj; return 1;}/* 处理要接受的文件信息Json * jsonObject:文件Json信息 dir:创建的路径*/int TcpThread::handle_ReceiveFileInfo(const QString& dir, const QJsonObject &jsonObject){ QDir().mkdir(dir); //设置保存的文件夹 QJsonObject Object = jsonObject["data"].toObject(); sendingFileObj = Object["sendingObj"].toString(); file_Size = Object["fileSize"].toInt(); file_Name = Object["fileName"].toString(); file_Path = QDir::currentPath() + "/" + dir + "/" + file_Name; file.setFileName(file_Path); //保存的图像路径 file.open(QIODevice::WriteOnly); //打开文件等待接收 if(dir == "Img"){ handle_FileStateAsJson(); //返回同意接受文件信息 }else{ emit handle_ShowFileInfoinChat(sendingFileObj,jsonObject); } return 1;}////-----------------------------------处理表情模块函数---------------------------------------------------------/* 处理好友表情 * jsondata:服务端返回的数据*/int TcpThread::handle_FriendEmotionResult(const QJsonObject& jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); emit relay_FriendEmotionToUserInfo(dataObject["sendingObj"].toString(),dataObject["emotion"].toString()); return 1;}////-----------------------------------处理信息模块函数---------------------------------------------------------/* 处理好友信息 * jsondata:服务端返回的数据*/int TcpThread::handle_FriendMessingResult(const QJsonObject& jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); emit relay_FriendMessingToUserInfo(dataObject["sendingObj"].toString(),dataObject["message"].toString()); return 1;}/* 处理群聊信息 * jsondata:服务端返回的数据*/int TcpThread::handle_GroupMessingResult(const QJsonObject& jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); emit relay_GroupMessingToUserInfo(dataObject); return 1;}////-----------------------------------Json模块函数---------------------------------------------------------/* 处理服务端返回的Json * jsondata:服务端返回的数据*/int TcpThread::handle_ReturnJsonData(QByteArray jsondata){ QJsonDocument jsonDocument = QJsonDocument::fromJson(jsondata); QJsonObject jsonObject = jsonDocument.object(); read_Type = jsonObject["type"].toString(); //获取Json中所含的操作类型 if(read_Type == "login"){ //处理登录返回的用户信息 handle_LoginReturnUserInfo(jsonObject); } else if(read_Type == "register"){ //处理用户注册操作返回的信息 handle_UserRegisterResult(jsonObject); } else if(read_Type == "encrypt"){ //处理加密操作返回的信息 handle_EncryptResult(jsonObject); } else if(read_Type == "selectFriend"){ //处理查询好友信息操作返回的信息 handle_SeleteFriendInfo(jsonObject); } else if(read_Type == "selectGroup"){ //处理查询群聊信息操作返回的信息 handle_SeleteGroupInfo(jsonObject); } else if(read_Type == "setAi" || read_Type == "getAi"){ //处理AI操作返回的信息 handle_AiResult(jsonObject); } else if(read_Type == "friendVerify"){ //处理好友添加请求返回的信息 handle_FriendVerify(jsonObject); } else if(read_Type == "return_AddFriendLinkResult"){ //处理新增好友链接返回的信息 emit relay_AddFriendLinkResult(jsonObject); } else if(read_Type == "return_AddGroupLinkResult"){ //处理新增群聊链接返回的信息 emit relay_AddGroupLinkResult(jsonObject); } else if(read_Type == "receive_FriendMessage"){ //处理好友发送的信息 handle_FriendMessingResult(jsonObject); } else if(read_Type == "receive_GroupMessage"){ //处理群聊发送的信息 handle_GroupMessingResult(jsonObject); } else if(read_Type == "receive_FriendEmotion"){ //处理好友发送的表情 handle_FriendEmotionResult(jsonObject); } else if(read_Type == "friend_SendingFile"){ //处理好友发送的文件信息 file_Type = "File"; handle_ReceiveFileInfo(file_Type, jsonObject); } else if(read_Type == "friend_SendingImg"){ //处理好友发送的图片信息 file_Type = "Img"; handle_ReceiveFileInfo(file_Type, jsonObject); } else{ //接收的数据为文件数据 handle_ReceiveFileData(jsondata); } return 1;}////-----------------------------------TCP模块函数---------------------------------------------------------/* 初始化Tcp链接*/int TcpThread::init_TcpConnect(){ //链接服务器成功 connect(server_DataService,&QTcpSocket::connected,this,&TcpThread::handle_ConnectedSuccess); //链接服务器失败 connect(server_DataService,&QTcpSocket::disconnected,this,&TcpThread::handle_DisConnected); //处理接收到的数据 connect(server_DataService,&QAbstractSocket::readyRead,this,&TcpThread::receive_ServerMessage); return 1;}/* 关闭线程 * number:线程ID*/int TcpThread::handle_CloseThread(const QString& number){ //请求更改用户状态为离线 QJsonObject Json; Json.insert("type","exitClient"); Json.insert("data",number); QJsonDocument jsonDoc(Json); QByteArray byteArray = jsonDoc.toJson(QJsonDocument::Compact); sending_ToServer(byteArray); ok = false; return 1;}/* 连接服务器成功*/int TcpThread::handle_ConnectedSuccess(){ isdisconnect = true; return 1;}/* 服务器链接断开*/int TcpThread::handle_DisConnected(){ while(!isdisconnect){ server_DataService->connectToHost("127.0.0.1",13020); //链接服务器 } return 1;}/* 接收服务器发送的信息*/void TcpThread::receive_ServerMessage(){ handle_ReturnJsonData(server_DataService->readAll()); //解析数据}/* 发送消息至服务器 * jsondata:发送的Json数据*/int TcpThread::sending_ToServer(const QByteArray &jsondata){ if(!isdisconnect){ server_DataService->connectToHost("127.0.0.1",13020); //链接服务器 } server_DataService->write(jsondata); server_DataService->flush(); //确保消息被发送 return 1;}////-----------------------------------添加好友模块函数------------------------------------------------------/* 处理查询好友信息操作返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_SeleteFriendInfo(const QJsonObject &jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); if(jsonObject["return"].toString() == "True"){ emit return_AddFriendInfo(jsonObject["code"].toString(), dataObject["friendstate"].toString(), dataObject["friendname"].toString(), dataObject["friendsex"].toString(), dataObject["friendsign"].toString(), dataObject["friendnumber"].toString(), dataObject["friendheadimg"].toString()); return 1; } else{ emit return_AddFriendInfo(jsonObject["code"].toString()," "," "," "," "," "," "); return 0; }}/* 处理好友验证的请求的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_FriendVerify(const QJsonObject &jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); emit return_FriendVerify(dataObject["friendname"].toString(), dataObject["friendsex"].toString(), dataObject["friendsign"].toString(), dataObject["friendnumber"].toString(), dataObject["friendheadimg"].toString()); return 1;}////-----------------------------------添加群聊模块函数------------------------------------------------------/* 处理查询群聊信息操作返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_SeleteGroupInfo(const QJsonObject &jsonObject){ QJsonObject dataObject = jsonObject["data"].toObject(); if(jsonObject["return"].toString() == "True"){ emit return_AddGroupInfo(jsonObject["code"].toString(), dataObject["groupnumber"].toString(), dataObject["groupname"].toString(), dataObject["groupheadimg"].toString()); return 1; } else{ emit return_AddGroupInfo(jsonObject["code"].toString()," "," "," "); return 0; }}////-----------------------------------AI模块函数-----------------------------------------------------------/* 处理获取Ai(设置Ai)请求返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_AiResult(const QJsonObject &jsonObject){ //获取返回的结果 QJsonObject dataObject = jsonObject["data"].toObject(); QString read_APIkey = dataObject["APIkey"].toString(); //读取的APIkey QString read_Aisign = dataObject["Aisign"].toString(); //读取的Ai介绍 QString read_Ainame = dataObject["Ainame"].toString(); //读取的Ai昵称 QString read_APIsecret = dataObject["APIsecret"].toString(); //读取的APIsecret if(jsonObject["return"].toString()== "True" && read_Type == "setAi"){ emit return_SetAiResult(true,read_Ainame,read_Aisign,read_APIkey,read_APIsecret); return 1; } else if(jsonObject["return"].toString() == "False" && read_Type == "setAi"){ emit return_SetAiResult(false,read_Ainame,read_Aisign,read_APIkey,read_APIsecret); return 0; } else if(jsonObject["return"].toString() == "True" && read_Type == "getAi"){ emit return_GetAiResult(true,read_Ainame,read_Aisign,read_APIkey,read_APIsecret); return 1; } else if(jsonObject["return"].toString() == "False" && read_Type == "getAi"){ emit return_GetAiResult(false,read_Ainame,read_Aisign,read_APIkey,read_APIsecret); return 0; }}////-----------------------------------加密模块函数-----------------------------------------------------------/* 处理保存加密请求返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_EncryptResult(const QJsonObject &jsonObject){ QString returnData = jsonObject["return"].toString(); //返回服务器处理加密信息结果给主线程处理 if(returnData == "True"){ emit return_SaveEncryptResult(true,""); return 1; } else if(returnData == "False"){ emit return_SaveEncryptResult(false,""); return 0; }}////-----------------------------------注册模块函数-----------------------------------------------------------/* 处理注册请求返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_UserRegisterResult(const QJsonObject &jsonObject){ QString returnData = jsonObject["return"].toString(); //注册用户请求结果返回给UserInfo界面处理 if(returnData == "True"){ emit return_RegisterResult(true); return 1; } else if(returnData == "False"){ emit return_RegisterResult(false); return 0; }}////-----------------------------------登录模块函数-----------------------------------------------------------/* 处理登录返回的信息 * jsonObject:服务端返回的用户数据*/int TcpThread::handle_LoginReturnUserInfo(const QJsonObject &jsonObject){ QString read_Return = jsonObject["return"].toString(); //读取的操作结果 if(read_Return == "True"){ //登录成功 QJsonObject userObject = jsonObject["data"].toObject(); //用户信息 emit return_UserInfo(true,jsonObject["code"].toString(),userObject["userSex"].toString(), userObject["userName"].toString(),userObject["userSign"].toString(), userObject["userNumber"].toString(),userObject["userHeadimg"].toString()); if(jsonObject["code"].toString() == "1"){ handle_LoginReturnGroupInfo(jsonObject["groupinfo"].toObject()); //处理群聊信息 handle_LoginReturnFriendInfo(jsonObject["friendinfo"].toObject()); //处理好友信息 } return 1; } else if(read_Return == "False"){ emit return_UserInfo(false,jsonObject["code"].toString()," "," "," "," "," "); return 0; }}/* 处理登录返回的好友信息 * friendinfo:服务端返回的好友数据*/int TcpThread::handle_LoginReturnFriendInfo(const QJsonObject &friendinfo){ int len = friendinfo["friendLen"].toInt(); //获取好友个数 for(int i=1; i<=len; ++i){ QString number = QStringLiteral("friend%1").arg(i); QJsonObject numberInfo = friendinfo[number].toObject(); //获取编号为number的好友信息 emit return_FriendInfo(numberInfo["name"].toString(),numberInfo["sign"].toString(), numberInfo["number"].toString(),numberInfo["headimg"].toString(), numberInfo["state"].toString()); } return 1;}/* 处理登录返回的群聊信息 * groupinfo:服务端返回的群聊数据*/int TcpThread::handle_LoginReturnGroupInfo(const QJsonObject &groupinfo){ int len = groupinfo["groupLen"].toInt(); //获取好友个数 for(int i=1; i<=len; ++i){ QString number = QStringLiteral("group%1").arg(i); QJsonObject numberInfo = groupinfo[number].toObject(); //获取编号为number的群聊信息 emit return_GroupInfo(numberInfo["name"].toString(),numberInfo["id"].toString(), numberInfo["headimg"].toString()); } return 1;}Object/srcFile/USER.cpp
#include "USER.h"USER::USER(){ //初始化对象 user_Name = ""; user_Number= ""; user_Sex = "男"; user_Sign = "当前还没有个性签名喔!"; user_Headimg = ":/new/Chat/icons/Chat/logo_Show.png";}USER::~USER(){}/* 设置用户性别 * Sex:性别*/int USER::set_UserSex(const QString &Sex){ user_Sex = Sex; return 1;}/* 设置用户昵称 * Name:昵称*/int USER::set_UserName(const QString &Name){ user_Name = Name; return 1;}/* 设置用户签名 * Sign:签名*/int USER::set_UserSign(const QString &Sign){ user_Sign = Sign; return 1;}/* 设置用户账号 * Number:账号*/int USER::set_UserNumber(const QString &Number){ user_Number = Number; return 1;}/* 设置用户头像 * HeadimgPath:头像路径*/int USER::set_UserHeadimgPath(const QString &HeadimgPath){ user_Headimg = HeadimgPath; return 1;}/* 获取用户信息 * Type:信息类型 * 返回值:const QString&(用户信息)*/const QString& USER::get_UserInfo(setUserFlagbit flag){ //判断枚举值 switch (flag){ case Data: return user_Data; //返回用户数据 break; case Number: return user_Number; //返回用户账号 break; case Name: return user_Name; //返回用户昵称 break; case Sex: return user_Sex; //返回用户性别 break; case Headimg: return user_Headimg; //返回用户头像 break; case Sign: return user_Sign; //返回用户个签 break; }}/* 设置全部对象 * user_Sex:用户性别 user_Name:用户昵称 user_Sign:用户签名 user_Number:用户账号 user_Headimg:用户头像*/int USER::set_AllObject(const QString &user_Sex,const QString &user_Name,const QString &user_Sign, const QString &user_Number,const QString &user_Headimg){ //设置信息 set_UserSex(user_Sex); set_UserName(user_Name); set_UserSign(user_Sign); set_UserNumber(user_Number); set_UserHeadimgPath(user_Headimg); //发出更新信号 emit new_USER(); return 1;}Object/main.cpp
#include <QApplication>#include "srcFile/USER.h"#include "uiFile/Login.h"#include "srcFile/NetWork.h"#include "srcFile/AiSrc/AI.h"//全局变量的声明AI my_AI;USER my_USER;NetWork my_NETWORK;int main(int argc, char *argv[]){ QApplication a(argc, argv); Login logon_Ui; logon_Ui.show(); return a.exec();}Server/srcFile/tcpThread/TcpThread.cpp
#include "TcpThread.h"#include <QDebug>TcpThread::TcpThread(QObject *parent) : QObject{parent} , QRunnable{}{ setAutoDelete(true);//设置线程自动析构}TcpThread::TcpThread(QTcpSocket *socket, int value, QObject *parent) : QObject{parent} , QRunnable{}{ //初始化对象 file_Size = 0; recvedSize = 0; file_Name = " "; file_Type = " "; file_State = true; ReceiveFileObj = " "; tcpThread_UserID = " "; tcpthread_UserPort = " "; Tcpthread_number = value; Tcpthread_Socket = socket; init_TcpConnect(); //初始化Tcp链接 setAutoDelete(true);//设置线程自动析构}TcpThread::~TcpThread(){}void TcpThread::run(){ handle_ClientConnected();//客户端成功连接 while(!TCPdiscon);}/* 设置用户项Id * port:线程端口 ItemId:用户项Id*/void TcpThread::handle_SetUserItemId(const QString &port, const int &ItemId){ if(tcpthread_UserPort == port){ userItem_Id = ItemId; }}////---------------------------------------文件模块函数----------------------------------------------------------/* 处理好友发送文件Json操作 * dataObject:接收到的文件数据*/int TcpThread::handle_FriendSendingFile(QJsonObject dataObject){ if(file_State){ file_Type = "File"; handle_FileSavePath(dataObject); return 1; }}/* 处理客户端发送的文件 * dataObject:接收到的文件数据*/void TcpThread::handle_SendingFile(QByteArray dataObject){ file_State = false; qint64 len = file.write(dataObject); //将接收到的数据写入文件 recvedSize += len; if(recvedSize == file_Size){ file.close(); recvedSize = 0; file_State = true; if(file_Type == "Img"){ emit relay_FileJsonToMainWidget(ReceiveFileObj,file_Path,handle_FileJsonPackageAsJSON("friend_SendingImg",ReceiveFileObj)); //请求发送给好友 } else if(file_Type == "File"){ emit relay_FileJsonToMainWidget(ReceiveFileObj,file_Path,handle_FileJsonPackageAsJSON("friend_SendingFile",ReceiveFileObj)); //请求发送给好友 } file_Type = " "; }}/* 处理客户端发送的文件保存路径 * dataObject:接收到的数据*/int TcpThread::handle_FileSavePath(QJsonObject dataObject){ QDir().mkdir("files"); //设置保存的文件夹 QJsonObject Object = dataObject["data"].toObject(); ReceiveFileObj = Object["receiveObj"].toString(); Object = dataObject["fileInfo"].toObject(); file_Size = Object["fileSize"].toInt(); file_Name = Object["fileName"].toString(); file_Path = QDir::currentPath() + "/files/" + ReceiveFileObj + file_Name; file.setFileName(file_Path); //保存的路径 file.open(QIODevice::WriteOnly); //打开文件等待接收}/* 处理同意接收文件操作 * dataObject:接收到的数据*/void TcpThread::handle_FileStateisOk(QJsonObject dataObject){ if(dataObject["data"].toString() == "Yes"){ qint64 len = 0; qint64 sending = 0; file.setFileName(file_Path); if(!file.open(QIODevice::ReadOnly)){ return; } do{ char buf[4*1024]; len = file.read(buf, sizeof(buf)); len = Tcpthread_Socket->write(buf, len); sending += len; if(sending == file_Size){ //确保发送的字节数不超过文件大小 file.close(); break; } }while(len > 0); }}/* 转发至好友的文件Json数据 * type:文件类型 number:接收的账号*/QJsonObject TcpThread::handle_FileJsonPackageAsJSON(const QString& type,const QString& number){ QJsonObject Json; Json.insert("type",type); QJsonObject dataObj; dataObj.insert("sendingObj",tcpThread_UserID); dataObj.insert("receiveObj",number); dataObj.insert("fileName",file_Name); dataObj.insert("fileSize",file_Size); Json.insert("data",dataObj); return Json;}/* 发送请求客户端接收文件信息*/void TcpThread::handle_RequestFileInfo(const QString &number, const QString &path, const QJsonObject &FileJson){ file_Path = path; return_ClientData(number,FileJson);}////---------------------------------------图片发送模块函数----------------------------------------------------------/* 处理好友发送图片Json操作 * dataObject:接收到的数据*/int TcpThread::handle_FriendSendingImg(QJsonObject dataObject){ if(file_State){ file_Type = "Img"; QDir().mkdir("images"); //设置保存的文件夹 handle_FileSavePath(dataObject); return 1; }}////---------------------------------------表情发送模块函数----------------------------------------------------------/* 处理好友发送表情操作 * dataObject:接收到的数据*/int TcpThread::handle_FriendSendingEmotion(QJsonObject dataObject){ emit relay_EmotionToMainWidget(dataObject["sendingObj"].toString(),dataObject["receiveObj"].toString(), dataObject["emotion"].toString()); return 1;}////---------------------------------------消息发送模块函数----------------------------------------------------------/* 处理好友发送消息操作 * dataObject:接收到的数据*/int TcpThread::handle_FriendSendingMessage(QJsonObject dataObject){ emit relay_MessageToMainWidget(dataObject["sendingObj"].toString(),dataObject["receiveObj"].toString(), dataObject["message"].toString()); return 1;}/* 处理群聊发送消息操作 * dataObject:接收到的数据*/void TcpThread::handle_GroupSendingMessage(QJsonObject dataObject){ QJsonObject Json; Json.insert("data",dataObject); Json.insert("type","receive_GroupMessage"); emit relay_GroupMessageToMainWidget(Json);}////---------------------------------------用户退出模块函数----------------------------------------------------------/* 处理退出客户端操作*/int TcpThread::handle_ExitClient(){ QString Sql_Code = QStringLiteral("UPDATE user SET state = '0' WHERE number = '%1'") .arg(tcpThread_UserID); emit request_SqlNewUserStateinExit(Sql_Code); //请求数据库更新用户状态为离线 return 1;}////---------------------------------------Tcp模块函数----------------------------------------------------------/* 初始化Tcp链接*/int TcpThread::init_TcpConnect(){ //客户端断开连接 connect(Tcpthread_Socket,&QAbstractSocket::disconnected,this,&TcpThread::handle_ClientDisconnected); //读取客户端发送的信息 connect(Tcpthread_Socket,&QAbstractSocket::readyRead,this,&TcpThread::get_ClientSendingData); return 1;}/* 读取客户短消息*/int TcpThread::get_ClientSendingData(){ execute_JsonOperate(Tcpthread_Socket->readAll()); return 1;}/* 返回信息至客户端 * id:线程ID rootObj:返回客户端的Json*/int TcpThread::return_ClientData(const QString &id, QJsonObject rootObj){ if(tcpThread_UserID == id){ QJsonDocument jsonDocument(rootObj); QByteArray jsonData = jsonDocument.toJson(); Tcpthread_Socket->write(jsonData); Tcpthread_Socket->flush(); return 1; } return 0;}/* 客户端成功连接*/int TcpThread::handle_ClientConnected(){ tcpthread_UserPort = QString::number(Tcpthread_Socket->peerPort()); if (Tcpthread_Socket->peerAddress().toString().startsWith("::ffff:")){ emit request_NewUserConnect(Tcpthread_Socket->peerAddress().toString().mid(7), QString::number(Tcpthread_Socket->peerPort())); } else{ emit request_NewUserConnect(Tcpthread_Socket->peerAddress().toString(), QString::number(Tcpthread_Socket->peerPort())); } return 1;}/* 客户端断开连接*/int TcpThread::handle_ClientDisconnected(){ handle_ExitClient(); //设置用户为离线状态 Tcpthread_Socket->deleteLater(); TCPdiscon = true; return 1;}/* 返回群聊消息至客户端 * rootObj:群聊消息*/int TcpThread::return_GroupinClien(QJsonObject rootObj){ QJsonDocument jsonDocument(rootObj); QByteArray jsonData = jsonDocument.toJson(); Tcpthread_Socket->write(jsonData); Tcpthread_Socket->flush();}/* 执行Json中的操作*/void TcpThread::execute_JsonOperate(QByteArray data_Array){ //解析Json QJsonDocument jsonDocument = QJsonDocument::fromJson(data_Array); QJsonObject jsonObject = jsonDocument.object(); QJsonObject dataObject = jsonObject["data"].toObject(); read_type = jsonObject["type"].toString(); if(!ismark){ //认领线程 tcpThread_UserID = dataObject["userNumber"].toString(); //标记线程ID emit request_NewUserNumber(userItem_Id,tcpThread_UserID);//更新用户账号信息 ismark = true; } if(read_type == "encrypt"){ //处理加密操作 handle_EncryptRequest(dataObject); } else if(read_type == "login"){ //处理登录操作 handle_UserLoginRequest(dataObject); } else if(read_type == "getAI"){ //处理获取Ai信息操作 handle_GetAiInfoRequest(dataObject); } else if(read_type == "setAI"){ //处理设置Ai信息操作 handle_SetAiInfoRequest(dataObject); } else if(read_type == "register"){ //处理注册操作 handle_UserRegisterRequest(dataObject); } else if(read_type == "exitClient"){ //处理退出客户端操作 handle_ExitClient(); } else if(read_type == "selectFriend"){ //处理查找好友信息操作 handle_SelectFriendInfo(dataObject); } else if(read_type == "selectGroup"){ //处理查找群聊信息操作 handle_SelectGroupInfo(dataObject); } else if(read_type == "applyForfriendVerify"){ //处理请求好友验证操作 handle_AddFriendVerify(dataObject); } else if(read_type == "applyForgroupVerify"){ //处理请求群聊验证操作 handle_AddGroupVerify(dataObject); } else if(read_type == "addfriendResult"){ //处理好友验证结果操作 handle_AddFriendResult(dataObject); } else if(read_type == "friend_SendingMessing"){ //处理好友发送消息操作 handle_FriendSendingMessage(dataObject); } else if(read_type == "Sending_GroupData"){ //处理群聊发送消息操作 handle_GroupSendingMessage(dataObject); } else if(read_type == "friend_SendingEmotion"){ //处理好友发送表情操作 handle_FriendSendingEmotion(dataObject); } else if(read_type == "friend_SendingImg"){ //处理好友发送图片操作 file_Type = "Img"; handle_FriendSendingImg(jsonObject); } else if(read_type == "friend_SendingFile"){ //处理好友发送文件操作 file_Type = "File"; handle_FriendSendingFile(jsonObject ); } else if(read_type == "FileState"){ //处理同意接收文件操作 handle_FileStateisOk(jsonObject ); } else{ read_type = "sendingFile"; //处理文件操作 handle_SendingFile(data_Array); } emit request_NewUserOperator(userItem_Id,read_type); //更新用户当前操作}/* 处理关闭客户端线程操作 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int TcpThread::handle_TCPDisconnect(){ TCPdiscon = true; return 1;}////---------------------------------------添加好友模块函数----------------------------------------------------------/* 处理请求好友验证操作 * dataObject:接收到的数据 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int TcpThread::handle_AddFriendVerify(QJsonObject dataObject){ QString Sql_Code = QStringLiteral("SELECT * FROM user WHERE number = '%1';").arg(tcpThread_UserID); emit relay_AddFriendVerify(dataObject["friendNumber"].toString(),Sql_Code);}/* 处理好友验证结果操作 * dataObject:接收到的数据 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int TcpThread::handle_AddFriendResult(QJsonObject dataObject){ emit request_AddFriendLinkData(tcpThread_UserID,dataObject["friendNumber"].toString());}/* 处理获取好友信息请求 * dataObject:接收到的数据 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int TcpThread::handle_SelectFriendInfo(QJsonObject dataObject){ //查询是否存在该账号 QString friend_Number = dataObject["friendNumber"].toString(); QString Sql_Code = QStringLiteral("SELECT * FROM user WHERE number = '%1'").arg(friend_Number); emit request_SqlSeleteFriendInfo(tcpThread_UserID,Sql_Code); return 1;}////---------------------------------------添加群聊模块函数-----------------------------------------------------/* 处理获取群聊信息请求 * dataObject:接收到的数据*/int TcpThread::handle_SelectGroupInfo(QJsonObject dataObject){ //查询是否存在该账号 QString group_Number = dataObject["groupNumber"].toString(); QString Sql_Code = QStringLiteral("SELECT * FROM groupinfo WHERE group_id = '%1';").arg(group_Number); emit request_SqlSeleteGroupInfo(tcpThread_UserID,Sql_Code); return 1;}/* 处理请求群聊验证操作 * dataObject:接收到的数据*/int TcpThread::handle_AddGroupVerify(QJsonObject dataObject){ emit request_AddGroupLinkData(tcpThread_UserID,dataObject["groupNumber"].toString());}////---------------------------------------Ai模块函数----------------------------------------------------------/* 处理获取Ai信息请求 * dataObject:接收到的数据*/int TcpThread::handle_GetAiInfoRequest(QJsonObject dataObject){ Q_UNUSED(dataObject); QString query = QStringLiteral("SELECT * FROM aiinfo WHERE number = '%1';").arg(tcpThread_UserID); emit request_SqlSeleteAiInfo(tcpThread_UserID,query);}/* 处理获取Ai信息请求 * dataObject:接收到的数据*/int TcpThread::handle_SetAiInfoRequest(QJsonObject dataObject){ QString query =QStringLiteral("UPDATE aiinfo SET number = '%1', sign = '%2', name = '%3', APIKey = '%4', APISecret = '%5'" " WHERE number = '%6'") .arg(tcpThread_UserID) .arg(dataObject["Aisign"].toString()) .arg(dataObject["Ainame"].toString()) .arg(dataObject["APIkey"].toString()) .arg(dataObject["APIsecret"].toString()) .arg(tcpThread_UserID); emit request_SqlSetAiInfo(tcpThread_UserID,query); //请求数据库设置Ai信息 return 1;}////---------------------------------------加密模块函数----------------------------------------------------------/* 处理客户端用户数据加密请求 * dataObject:接收到的数据*/int TcpThread::handle_EncryptRequest(QJsonObject dataObject){ QString query = QStringLiteral("UPDATE user SET encrypt_Pswd = '%1' WHERE number = '%2';") .arg(dataObject["userEncrypt"].toString()).arg(tcpThread_UserID); //定义执行的Sql语句 emit request_SaveEncryptData(tcpThread_UserID,query); //请求数据库保存加密数据 return 1;}////---------------------------------------注册模块函数----------------------------------------------------------/* 处理用户注册请求 * dataObject:接收到的数据*/int TcpThread::handle_UserRegisterRequest(QJsonObject dataObject){ QString query = QStringLiteral("INSERT INTO user (name, number, password, sex, sign, headimg_Path, encrypt_Pswd, state)" "VALUES ('%1', '%2', '%3', '%4', '%5', '%6', '%7','0')") .arg(dataObject["userName"].toString()) .arg(dataObject["userNumber"].toString()) .arg(dataObject["userPassword"].toString()) .arg(dataObject["userSex"].toString()) .arg(dataObject["userSign"].toString()) .arg(dataObject["userHeadimg"].toString()) .arg(" "); emit request_SqlAddUserInfo(tcpThread_UserID,query); //请求数据库添加用户信息 return 1;}////---------------------------------------登录模块函数----------------------------------------------------------/* 处理客户端用户登录请求 * dataObject:接收到的数据*/int TcpThread::handle_UserLoginRequest(QJsonObject dataObject){ QString query = QStringLiteral("SELECT * FROM user " "WHERE number = '%1' AND password = '%2';") .arg(dataObject["userNumber"].toString()) .arg(dataObject["userPassword"].toString()); emit request_VerifyUserInfo(tcpThread_UserID,query); //发送信号验证登录信息 return 1;}Server/srcFile/sqlThread/SqlThread.cpp
#include "SqlThread.h"#include <QDebug>SqlThread::SqlThread(QObject *parent) : QObject{parent} , QRunnable{}{ //初始化数据库线程 init_SqlThread();}/* 创建指定操作的线程 * type:操作类型 query:Sql语句*/SqlThread::SqlThread(const QString &type,const QString &query,QObject *parent) : QObject{parent} , QRunnable{}{ //初始化数据库线程 init_SqlThread();}SqlThread::~SqlThread(){ delete Data_Base; delete sql_Code;}/* 线程执行函数*/void SqlThread::run(){ if (Data_Base->open()) { //尝试连接数据库 sql_Code = new QSqlQuery(*Data_Base); } else { QString Str = QStringLiteral("连接数据库失败:%1").arg(Data_Base->lastError().text()); QMessageBox::information(nullptr,"提示",Str,QMessageBox::Ok); } while(!SQLdiscon);}////---------------------------------------用户退出模块函数----------------------------------------------------------/* 处理注册用户操作 * sqlcode:执行的Sql语句*/int SqlThread::handle_NewUserStateinExit(const QString &sqlcode){ sql_Code->exec(sqlcode); return 1;}////---------------------------------------注册模块函数----------------------------------------------------------/* 处理注册用户操作 * id:线程ID query:执行的Sql语句*/int SqlThread::handle_RegisterUserResult(const QString &id, const QString &query){ QJsonObject rootObj; //返回客户端的Json对象 if(sql_Code->exec(query)){ //注册用户成功 rootObj.insert("type","register"); rootObj.insert("code","21"); rootObj.insert("return","True"); rootObj.insert("userNumber",id); emit return_UserRegisterResult(id,rootObj); //返回操作结果 return 1; } else{ //注册用户失败 rootObj.insert("type","register"); rootObj.insert("code","20"); rootObj.insert("return","False"); rootObj.insert("userNumber",id); emit return_UserRegisterResult(id,rootObj); //返回操作结果 return 0; } return -1;}////---------------------------------------Ai模块函数----------------------------------------------------------/* 设置Ai信息 * id:线程ID query:执行的Sql语句*/int SqlThread::handle_SetAiInfo(const QString &id, const QString &query){ if(sql_Code->exec(query)){ //执行设置Ai信息操作 QJsonObject rootObj; //传输的Json数据 QString selete = QStringLiteral("SELECT * FROM aiinfo WHERE number = '%1';").arg(id); if(sql_Code->exec(selete) && sql_Code->next()){ //执行查询Ai信息操作 handle_AiInfoPackageAsJSON(rootObj,"51","True","setAi"); emit return_SetAiResult(id,rootObj); return 1; } else{ handle_AiInfoPackageAsJSON(rootObj,"50","True","setAi"); emit return_SetAiResult(id,rootObj); return 0; } } return -1;}/* 获取Ai信息 * id:线程ID query:执行的Sql语句*/int SqlThread::handle_GetAiInfo(const QString &id, const QString &query){ QJsonObject rootObj; //传输的Json数据 if(sql_Code->exec(query)){ while(sql_Code->next()){ //开始查询 if(sql_Code->record().count()){ //查询到Ai信息 handle_AiInfoPackageAsJSON(rootObj,"41","True","getAi"); emit return_GetAiOperateResult(id,rootObj); return 1; } } } handle_AiInfoPackageAsJSON(rootObj,"42","False","getAi"); //未查询到Ai信息 emit return_GetAiOperateResult(id,rootObj); return 0;}/* 将Ai信息结果封装成Json * rootObj:返回客户端的Json code:信息码 result:操作结果 type:操作类型*/int SqlThread::handle_AiInfoPackageAsJSON(QJsonObject &rootObj, const QString &code, const QString &result, const QString &type){ QJsonObject dataObj; rootObj.insert("type",type); rootObj.insert("return",result); rootObj.insert("code",code); dataObj.insert("userNumber",sql_Code->value("number").toString()); dataObj.insert("APIkey",sql_Code->value("APIKey").toString()); dataObj.insert("Aisign",sql_Code->value("sign").toString()); dataObj.insert("Ainame",sql_Code->value("name").toString()); dataObj.insert("APIsecret",sql_Code->value("APIsecret").toString()); rootObj.insert("data",dataObj);}////---------------------------------------Sql模块函数----------------------------------------------------------/* 初始化数据库线程*/int SqlThread::init_SqlThread(){ setAutoDelete(true); //设置线程自动析构 //配置数据库信息 Data_Base = new QSqlDatabase(); *Data_Base = QSqlDatabase::addDatabase("QMYSQL"); Data_Base->setHostName("127.0.0.1"); Data_Base->setPort(3306); Data_Base->setUserName("root"); Data_Base->setPassword("******"); Data_Base->setDatabaseName("qqdate");}/* 初始化数据库线程*/int SqlThread::handle_SQLDisconnect(){ SQLdiscon = true; return 1;}////---------------------------------------加密模块函数----------------------------------------------------------/* 处理添加用户加密数据操作 * id:线程ID query:执行的Sql语句*/int SqlThread::handle_AddEncryptData(const QString &id, const QString &query){ QMutexLocker locker(&mutex); QJsonObject rootObj; //传输的Json对象 if(sql_Code->exec(query)){ //加密数据添加成功 rootObj.insert("type","encrypt"); rootObj.insert("code","31"); rootObj.insert("return","True"); emit return_AddEncryptResult(id,rootObj); //返回操作结果 return 1; } else{ //加密数据添加失败 rootObj.insert("type","encrypt"); rootObj.insert("code","31"); rootObj.insert("return","True"); emit return_AddEncryptResult(id,rootObj); //返回操作结果 return 0; } return -1; //添加数据异常}////---------------------------------------登录模块函数----------------------------------------------------------/* 处理登录请求验证用户数据 * id:线程ID query:执行的Sql语句*/int SqlThread::handle_LoginVerifyUserData(const QString &id, const QString &query){ QMutexLocker locker(&mutex); QJsonObject rootObj; //登录结果Json对象 if(sql_Code->exec(query)){ rootObj.insert("type","login"); if(sql_Code->next()){ QJsonObject dataObj; //初始化用户信息Json对象 QJsonObject groupObj; //初始化群聊信息Json对象 QJsonObject friendObj; //初始化好友信息Json对象 dataObj.insert("userSex",sql_Code->value("sex").toString()); dataObj.insert("userSign",sql_Code->value("sign").toString()); dataObj.insert("userName",sql_Code->value("name").toString()); dataObj.insert("userNumber",sql_Code->value("number").toString()); dataObj.insert("userHeadimg",sql_Code->value("headimg_Path").toString()); rootObj.insert("data",dataObj); if(sql_Code->value("state").toString() == "0"){ selete_UserinGroupinfo(groupObj,id); //查找用户群聊 selete_UserinFreindinfo(friendObj,id); //查找用户好友 rootObj.insert("groupinfo",groupObj); rootObj.insert("friendinfo",friendObj); QString update = QStringLiteral("UPDATE user SET state = '1' WHERE number = '%1'") .arg(id); sql_Code->exec(update); //更新用户状态 rootObj.insert("code","1"); rootObj.insert("return","True"); emit return_LoginVerifyUserResult(id,rootObj); return 1; } else if(sql_Code->value("state").toString() == "1"){ //查找到用户,但用户已登录 rootObj.insert("code","0"); rootObj.insert("return","True"); emit return_LoginVerifyUserResult(id,rootObj); return 0; } } else{ //用户信息异常 rootObj.insert("code","2"); rootObj.insert("return","False"); emit return_LoginVerifyUserResult(id,rootObj); return -1; } }}/* 查找用户好友信息 * friendjson:接收好友信息的json对象 number:用户账号*/int SqlThread::selete_UserinFreindinfo(QJsonObject &friendjson, const QString &number){ int len = 0; //记录好友个数 QString seleteFriend = QStringLiteral("SELECT * FROM user WHERE number IN (" "SELECT user_id FROM friend WHERE friend_id = '%1');") .arg(number); //查找好友 sql_Code->exec(seleteFriend); while (sql_Code->next()) { QJsonObject Obj; //初始化Json对象 Obj.insert("name",sql_Code->value(0).toString()); Obj.insert("sign",sql_Code->value(4).toString()); Obj.insert("state",sql_Code->value(7).toString()); Obj.insert("number",sql_Code->value(1).toString()); Obj.insert("headimg",sql_Code->value(5).toString()); len+=1; //好友个数+1 QString friendref = QStringLiteral("friend%1").arg(len); //好友编号 friendjson.insert(friendref,Obj); } friendjson.insert("friendLen",len); return 1;}/* 查找用户群聊信息 * groupjson:接收群聊数据的json对象 number:用户账号*/int SqlThread::selete_UserinGroupinfo(QJsonObject &groupjson, const QString &number){ int len = 0; //记录群聊个数 //查找用户群聊 QString seleteGroup = QStringLiteral("SELECT * FROM groupinfo WHERE group_id IN (" "SELECT group_id FROM groupuserinfo WHERE user_id = '%1');").arg(number); sql_Code->exec(seleteGroup); while (sql_Code->next()) { QJsonObject Obj; //初始化Json对象 Obj.insert("id",sql_Code->value(0).toString()); Obj.insert("name",sql_Code->value(1).toString()); Obj.insert("headimg",sql_Code->value(2).toString()); len+=1; //群聊个数+1 QString groupref = QStringLiteral("group%1").arg(len); //群聊编号 groupjson.insert(groupref,Obj); } groupjson.insert("groupLen",len); return 1;}////---------------------------------------添加好友模块函数----------------------------------------------------------/* 处理查询好友信息操作 * id:线程Id sqlcode:执行的Sql语句*/int SqlThread::handle_SeleteFriendInfo(const QString &id, const QString &sqlcode){ QJsonObject rootObj,data; //返回值的Json数据 rootObj.insert("type","selectFriend"); if(handle_FriendInfoPackageAsJSON(data, sqlcode)){ //存在该用户 rootObj.insert("data",data); rootObj.insert("code","61"); rootObj.insert("return","True"); emit return_SeleteinFriendResult(id,rootObj); //请求返回查询到的好友信息 return 1; }else{ //不存在该群聊 rootObj.insert("code","62"); rootObj.insert("return","False"); emit return_SeleteinFriendResult(id,rootObj); return 0; }}/* 处理申请好友验证操作 * id:线程Id sqlcode:执行的Sql语句*/int SqlThread::handle_AddFriendOperator(const QString &id, const QString &sqlcode){ QJsonObject rootObj,data; //返回值的Json数据 if(handle_FriendInfoPackageAsJSON(data, sqlcode)){ rootObj.insert("data",data); rootObj.insert("code","68"); rootObj.insert("return","True"); rootObj.insert("type","friendVerify"); emit return_ApplyForFriendVerifyResult(id,rootObj); //请求好友验证 return 1; } return 0;}/* 处理申请好友验证操作 * id:线程Id friendnumber:好友账号*/int SqlThread::handle_AddFriendLinkData(const QString &id, const QString &friendnumber){ QJsonObject data1,data2,rootObj; //返回值的Json数据 rootObj.insert("type","return_AddFriendLinkResult"); QString Sql_Code1 = " ",Sql_Code2 = " ";//初始化执行的SQL语句 Sql_Code1 = QStringLiteral("INSERT INTO friend (friend_id, user_id) VALUES" "('%1','%2')," "('%3','%4');").arg(id).arg(friendnumber).arg(friendnumber).arg(id); if(sql_Code->exec(Sql_Code1)){ //添加成功 Sql_Code1 = QStringLiteral("SELECT * FROM user WHERE number = '%1'").arg(id); Sql_Code2 = QStringLiteral("SELECT * FROM user WHERE number = '%1'").arg(friendnumber); if(handle_FriendInfoPackageAsJSON(data1,Sql_Code1) && handle_FriendInfoPackageAsJSON(data2,Sql_Code2)){ rootObj.insert("code","65"); //插入链接的用户信息 rootObj.insert("data1",data1); rootObj.insert("data2",data2); }else{ rootObj.insert("code","62"); } rootObj.insert("return","True"); } else{ //添加失败 rootObj.insert("code","67"); rootObj.insert("return","False"); emit return_AddFriendLinkDataResult(friendnumber,rootObj); return 0; } rootObj.insert("type","return_AddFriendLinkResult"); emit return_AddFriendLinkDataResult(id,rootObj); emit return_AddFriendLinkDataResult(friendnumber,rootObj); return 1;}/* 处理申请好友验证操作 * data:打包的Json对象 sqlcode:执行的SQL语句*/int SqlThread::handle_FriendInfoPackageAsJSON(QJsonObject& data, const QString &sqlcode){ if(sql_Code->exec(sqlcode)){ sql_Code->next(); if(sql_Code->value("number").toString().isEmpty()){ return 0; }else{ data.insert("friendsex",sql_Code->value("sex").toString()); data.insert("friendsign",sql_Code->value("sign").toString()); data.insert("friendname",sql_Code->value("name").toString()); data.insert("friendstate",sql_Code->value("state").toString()); data.insert("friendnumber",sql_Code->value("number").toString()); data.insert("friendheadimg",sql_Code->value("headimg_Path").toString()); } return 1; } return 0;}////---------------------------------------添加群聊模块函数----------------------------------------------------------/* 处理查询群聊信息操作 * id:线程Id sqlcode:执行的Sql语句*/int SqlThread::handle_SeleteGroupInfo(const QString &id, const QString &sqlcode){ QJsonObject rootObj,data; //返回值的Json数据 rootObj.insert("type","selectGroup"); if(handle_GroupInfoPackageAsJSON(data, sqlcode)){ //存在该群聊 rootObj.insert("data",data); rootObj.insert("code","91"); rootObj.insert("return","True"); emit return_SeleteinGroupResult(id,rootObj); //请求返回查询到的好友信息 return 1; }else{ //不存在该群聊 rootObj.insert("code","92"); rootObj.insert("return","False"); emit return_SeleteinFriendResult(id,rootObj); return 0; }}/* 将群聊信息打包为Json * rootObj:打包的Json对象 sqlcode:执行的SQL语句 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int SqlThread::handle_GroupInfoPackageAsJSON(QJsonObject& data, const QString &sqlcode){ if(sql_Code->exec(sqlcode)){ sql_Code->next(); if(sql_Code->value("group_id").toString().isEmpty()){ return 0; }else{ data.insert("groupname",sql_Code->value("group_name").toString()); data.insert("groupnumber",sql_Code->value("group_id").toString()); data.insert("groupheadimg",sql_Code->value("group_headimg").toString()); return 1; } }}/* 处理申请群聊验证操作 * id:线程Id number:添加的群聊号码 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int SqlThread::handle_AddGroupLinkData(const QString &id, const QString &number){ QString Sql_Code = QStringLiteral("SELECT * FROM groupuserinfo WHERE group_id = '%1' AND user_id = '%1';") .arg(number).arg(id); if(sql_Code->exec(Sql_Code)){ sql_Code->next(); if(sql_Code->value("user_id").toString().isEmpty()){ Sql_Code = QStringLiteral("INSERT INTO groupuserinfo (group_id, user_id) VALUES" "('%1','%2');").arg(number).arg(id); if(sql_Code->exec(Sql_Code)){ handle_GroupLinkDataPackageAsJSON("93",id,number); return 1; } } } handle_GroupLinkDataPackageAsJSON("94",id,number); return 0;}/* 将链接群聊信息打包为Json * code:信息码 id:用户ID number:群聊号码 * 返回值:int(错误码,-1为异常,0为错误,1为无误)*/int SqlThread::handle_GroupLinkDataPackageAsJSON(const QString &code, const QString &id, const QString &number){ QJsonObject rootObj,data; //返回的Json数据 rootObj.insert("type","return_AddGroupLinkResult"); QString Sql_Code = QStringLiteral("SELECT * FROM groupinfo WHERE group_id = '%1';").arg(number); if(sql_Code->exec(Sql_Code)){ sql_Code->next(); data.insert("groupname",sql_Code->value("group_name").toString()); data.insert("groupnumber",sql_Code->value("group_id").toString()); data.insert("groupheadimg",sql_Code->value("group_headimg").toString()); } rootObj.insert("code",code); rootObj.insert("data",data); emit return_GroupLinkResult(id,rootObj);}展示代码中的数据库凭据已打码,实际运行请使用本地配置。