AIChatProject

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

作者
WildPointer
更新
2025-08-12
类型
自有项目
仓库
1 stars / 0 forks(抓取快照)
AIChatProject 项目演示
项目 README 演示动图

AIChatProject - By Wild_Pointer

AIChatProject是一套基于Qt框架的开源智能即时聊天室系统,在经过多次反复优化迭代下成长为多功能的交友应用。

源码可自由下载使用,更多信息参考个人博客:

在使用AiChatProject进行二次开发(策略、模块等)的过程中有任何疑问,可通过QQ邮箱或者谷歌邮箱,也欢迎在分享你的使用心得或者使用中产生的bug,方便作者后续更新迭代!

AIChatProject介绍

智能即时聊天室系统(AIChatProject)是一个高效、灵活的即时通讯解决方案。它融合了百度的开源大型语言模型——文心一言,通过API接口实现深度集成。系统专为聊天和文件传输等核心功能设计,以便快速搭建定制化的即时通讯应用。采用客户端/服务器(C/S)架构,确保了应用的稳定性和扩展性。数据存储依托于MySQL数据库,保障了数据的安全性和高效管理。客户端之间的信息交换通过JSON格式实现,简洁而高效。此外,系统利用TCP协议进行数据传输,确保了通信的可靠性和稳定性。

  1. 项目技术栈:

    • 数据库

      • 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文件导入以下模块:

text
sql
text
network
text
websockets

注意:源码中的Pro文件以及列举了Qt6所需的所有模块,其中Qt6不支持MySQL数据库驱动,需要手动配置

代码示例

AIChatProject采用了统一的命名和注释格式,具体可参考以下代码:

C++
/*  处理保存加密请求返回的信息 *  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
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
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
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
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
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
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
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
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);}

展示代码中的数据库凭据已打码,实际运行请使用本地配置。

WildPointer

专注系统编程、工程实践与底层技术,记录 C++、Qt、OpenCV 与 VTK 的学习和实践。