Tcp群聊

Client
//修改群聊的接口,主要增加了客户端给服务端发送群聊数据,服务端直接给每个客户端转发,客户端接收后判断自己是不是在群里,在群里就显示数据



typedef enum {
    Unknow,
    Register            = 0x10,     // 用户注册
    Login,                          // 用户登录
    Logout,                         // 用户注销
    LoginRepeat,                    // 重复登录

    UserOnLine          = 0x15,     // 用户上线通知
    UserOffLine,                    // 用户下线通知
    UpdateHeadPic,                  // 用户更新头像

    AddFriend           = 0x20,     // 添加好友
    AddGroup,                       // 添加群组

    AddFriendRequist,               // 添加好友确认通知
    AddGroupRequist,                // 添加群组确认通知

    CreateGroup         = 0x25,     // 创建群组

    GetMyFriends        = 0x30,     // 上线获取我的好友的状态
    GetMyGroups,                    // 获取我的群组信息

    RefreshFriends      = 0x35,     // 刷新好友状态
    RefreshGroups,                  // 刷新群组成员状态

    SendMsg             = 0x40,     // 发送消息
    SendGroupMsg,                   // 发送群组消息
    SendFile,                       // 发送文件
    SendPicture,                    // 发送图片
    SendFace,                       // 发送表情
    SendPulicMsg,                   //大厅消息

    ChangePasswd        = 0x50,     // 修改密码

    DeleteFriend        = 0x55,     // 删除好友
    DeleteGroup,                    // 退出群组
    RemoveGroupUser,                // 踢人

    SendFileOk          = 0x60,     // 文件发送完成状态

    GetFile             = 0x65,     // 获取文件(到服务器下载文件)
    GetPicture,                     // 图片下载

} E_MSG_TYPE;


void QQListWidget::removeGroupByName(QString Name)
{

    for (QQCell *group : cells)
    {
        if (!group->groupName.compare("我的群组"))
        {
            //group->childs.removeOne(cell);

            // 创建一个迭代器用于遍历 childs 列表
            for (QList<QQCell *>::iterator it = group->childs.begin(); it != group->childs.end();) {
                QQCell *cell = *it;

                // 在这里进行某些条件判断,确定是否要删除当前子项
                if (cell->name == Name) {
                    // 删除当前子项
                    delete cell;
                    // 从 childs 列表中移除当前子项
                    it = group->childs.erase(it);
                } else {
                    // 如果不删除当前子项,则继续迭代
                    ++it;
                }
            }


            break;
        }
    }
    upload();
}

bool DataBaseMagr::DeleteMyGroup(const QString &groupname, const int &userId)
{
    // 删除符合条件的记录
    QString strDelete = "DELETE FROM MYGROUP ";
    strDelete.append("WHERE name='");
    strDelete.append(groupname);
    strDelete.append("'");
    //strDelete.append(" AND userId=");
    //strDelete.append(QString::number(userId));

    // 执行删除操作
    QSqlQuery deleteQuery(strDelete, userdb);

    // 检查是否删除成功
    if (deleteQuery.exec())
    {
        //发给服务器通知解散各个群



        return true; // 删除成功
    }
    else
    {
        qDebug() << "Error executing delete operation:" << deleteQuery.lastError().text();
        return false; //
    }
}

//大厅聊天按钮
void MainWindow::on_pushButton_clicked()
{
    //发送大厅消息
    QString text = ui->lineEdit->text();
    // 把最后一个回车换行符删掉
    while (text.endsWith("\n")) {
        text.remove(text.length() - 2, 2);
    }

    // 判断消息是否为空
    if (text.isEmpty()) {
        return;
    }

    // 构建json数据
    QJsonObject json;
    json.insert("id", MyApp::m_nId);
    json.insert("to", "public");
    json.insert("msg", text);
    json.insert("type", Text);


    QString strText = text;
    QString strName = MyApp::m_strUserName;
    QString str = "[" + DATE_TIME + "] " + strName + ":" + strName + "\n";
    ui->plainTextEdit->appendPlainText(str);

    // 发送消息
    m_tcpSocket->SltSendMessage(SendPulicMsg, json);
    // 清除输入框
    ui->lineEdit->clear();
}

void MainWindow::SltTcpReply(const quint8 &type, const QJsonValue &dataVal)
{
    switch (type) {
    case UserOnLine:
    {
        UpdateFriendStatus(OnLine, dataVal);
    }
        break;
    case UserOffLine:
    {
        UpdateFriendStatus(OffLine, dataVal);
    }
        break;
    case UpdateHeadPic:
    {
        // 你的好友更新了头像
        ParseUpFriendHead(dataVal);
    }
        break;
    case AddFriend:
    {
        ParseAddFriendReply(dataVal);
    }
        break;
    case AddGroup:
    {
        ParseAddGroupReply(dataVal);
    }
        break;

    case AddFriendRequist:
    {
        ParseAddFriendRequest(dataVal);
    }
        break;
    case AddGroupRequist:
    {
        ParseAddGroupRequest(dataVal);
    }
        break;

    case CreateGroup:
    {
        ParseCreateGroupReply(dataVal);
    }
        break;
    case DeleteGroup:
    {
        ParseDeleteGroupReply(dataVal);
    }
        break;
    case GetMyFriends:
    {
        ParseGetFriendsReply(dataVal);
    }
        break;
    case GetMyGroups:
    {
        ParseGetGroupFriendsReply(dataVal);
    }
        break;
    case RefreshFriends:
    {
        ParseRefreshFriendsReply(dataVal);
    }
        break;
    case RefreshGroups:
    {
        ParseRefreshGroupFriendsReply(dataVal);
    }
        break;
    case SendMsg:
    {
        ParseFriendMessageReply(dataVal);
    }
        break;
    case SendGroupMsg:
    {
        ParseGroupMessageReply(dataVal);
    }
        break;
    case SendFile:
    {
        ParseFriendMessageReply(dataVal);
    }
        break;
    case SendPicture:
    {
        ParseFriendMessageReply(dataVal);
    }
        break;
    case SendPulicMsg:
    {
        ParsePublicMessageReply(dataVal);
    }
        break;
    default:
        break;
    }
}


void MainWindow::ParsePublicMessageReply(const QJsonValue &json)
{
    // 消息格式为object对象
    if (json.isObject())
    {
        QJsonObject dataObj = json.toObject();
        //int type = dataObj.value("type").toInt();
        QString strText = dataObj.value("msg").toString();
        QString strName = dataObj.value("name").toString();
        QString str = "[" + DATE_TIME + "] " + strName + ":" + strName + "\n";
        ui->plainTextEdit->appendPlainText(str);

    }
}

void MainWindow::ParseDeleteGroupReply(const QJsonValue &dataVal)
{
    if (dataVal.isObject())
    {
        QJsonObject dataObj = dataVal.toObject();

        int nId = dataObj.value("id").toInt();
//        // 未查询到该用户
//        if (-1 == nId) {
//            CMessageBox::Infomation(this, "该群组已经添加!");
//            return;
//        }

        QString strName = dataObj.value("name").toString();//组名
        bool bOk = DataBaseMagr::Instance()->DeleteMyGroup(strName, MyApp::m_nId);
        if(bOk)
        {
            ui->groupListWidget->removeGroupByName(strName);
        }


    }
}

void MainWindow::ParseGroupMessageReply(const QJsonValue &dataVal)
{
    bool breceive = false;
    QList<QQCell *> groups_ = ui->groupListWidget->getCells();
    foreach (QQCell *cell_, groups_.at(0)->childs)
    {
        if (dataVal.isObject())
        {
            QJsonObject dataObj = dataVal.toObject();
            QString nId_ = dataObj.value("group").toString();
            if(cell_->name == nId_)
            {
                breceive = true;
                break;
            }
        }
    }

    if(!breceive)
        return;


    // 消息格式为object对象
    if (dataVal.isObject()) {
        QJsonObject dataObj = dataVal.toObject();
        QString nId = dataObj.value("group").toString();
        // 播放系统提示音
        myHelper::PlaySound("msg");

        // 如果收到消息时有聊天窗口存在,直接添加到聊天记录,并弹出窗口
        foreach (ChatWindow *window, m_chatGroupWindows) {
            if (window->GetGroupName() == nId) {
                window->AddMessage(dataVal);
                window->show();
                return;
            }
        }

        // 没有检索到聊天窗口,直接弹出新窗口
        QList<QQCell *> groups = ui->groupListWidget->getCells();
        foreach (QQCell *cell, groups.at(0)->childs) {
            // 有列表的才创建
            if (cell->name == nId) {
                ChatWindow *chatWindow = new ChatWindow();
                connect(chatWindow, SIGNAL(signalSendMessage(quint8,QJsonValue)), m_tcpSocket, SLOT(SltSendMessage(quint8,QJsonValue)));
                connect(chatWindow, SIGNAL(signalClose()), this, SLOT(SltGroupChatWindowClose()));

                // 构建 Json 对象
                QJsonObject json;
                json.insert("id", cell->id);
                json.insert("name", cell->name);

                m_tcpSocket->SltSendMessage(GetMyGroups, json);


                chatWindow->SetCell(cell, 1);
                chatWindow->AddMessage(dataVal);
                chatWindow->show();
                // 添加到当前聊天框
                m_chatGroupWindows.append(chatWindow);
                return;
            }
        }
    }
}




void MainWindow::InitQQListMenu()
{
    //设置菜单
    //设置组菜单
    QMenu *addFriend = new QMenu(this);
    addFriend->addAction(tr("添加好友"));
    addFriend->addAction(tr("刷新"));
    addFriend->addSeparator();
    addFriend->addAction(tr("删除该组"));
    connect(addFriend, SIGNAL(triggered(QAction*)), this, SLOT(onAddFriendMenuDidSelected(QAction*)));
    ui->frindListWidget->setGroupPopMenu(addFriend);

    // 设置子菜单
    QMenu *childMenu = new QMenu(this);
    childMenu->addAction(tr("发送即时消息"));
    childMenu->addSeparator();
    //childMenu->addAction("移动至黑名单");
    childMenu->addAction("删除联系人");

    QMenu *groupListMenu = new QMenu(tr("移动联系人至"));
    //childMenu->addMenu(groupListMenu);

    // childMenu->addAction(tr("创建讨论组"));
    connect(childMenu, SIGNAL(triggered(QAction*)), this, SLOT(onChildPopMenuDidSelected(QAction*)));
    ui->frindListWidget->setChildPopMenu(childMenu);

    //添加默认项
    //好友列表
    QQCell *myFriend = new QQCell;
    myFriend->groupName = QString(tr("我的好友"));
    myFriend->isOpen = false;
    myFriend->type = QQCellType_Group;
    myFriend->name = QString(tr("我的好友"));
    myFriend->subTitle = QString("(0/0)");
    ui->frindListWidget->insertQQCell(myFriend);

    QQCell *blacklist = new QQCell;
    blacklist->groupName = QString(tr("黑名单"));
    blacklist->isOpen = false;
    blacklist->type = QQCellType_Group;
    blacklist->name = QString(tr("黑名单"));
    blacklist->subTitle = QString("(0/0)");
    //ui->frindListWidget->insertQQCell(blacklist);

    connect(ui->frindListWidget, SIGNAL(onChildDidDoubleClicked(QQCell*)), this, SLOT(SltFriendsClicked(QQCell*)));

    //组列表
    QMenu *myGroupMenu = new QMenu(this);
    myGroupMenu->addAction(tr("创建讨论组"));
    myGroupMenu->addAction(tr("加入讨论组"));
    myGroupMenu->addAction(tr("删除该组"));
    myGroupMenu->addSeparator();
    connect(myGroupMenu, SIGNAL(triggered(QAction*)), this, SLOT(onGroupPopMenuDidSelected(QAction*)));
    ui->groupListWidget->setGroupPopMenu(myGroupMenu);
    //设置子菜单
    QMenu *groupChildMen = new QMenu(this);
    groupChildMen->addAction(tr("解散该群"));
    groupChildMen->addAction(tr("退出该群"));
    connect(groupChildMen, SIGNAL(triggered(QAction*)), this, SLOT(onGroupPopMenuDeleGroup(QAction*)));
    ui->groupListWidget->setChildPopMenu(groupChildMen);

    //添加默认项
    QQCell *groupCell = new QQCell;
    groupCell->groupName = QString(tr("我的群组"));
    groupCell->isOpen = false;
    groupCell->type = QQCellType_GroupEx;
    groupCell->name = QString(tr("讨论组"));
    groupCell->subTitle = QString("(0/0)");
    ui->groupListWidget->insertQQCell(groupCell);

    connect(ui->groupListWidget, SIGNAL(onChildDidDoubleClicked(QQCell*)), this, SLOT(SltGroupsClicked(QQCell*)));
}

/**
 * @brief MainWindow::InitSysTrayIcon
 * 托盘菜单
 */
void MainWindow::InitSysTrayIcon()
{
    systemTrayIcon = new QSystemTrayIcon(this);
    systemTrayIcon->setIcon(QIcon(":/resource/background/app.png"));

    QMenu *m_trayMenu = new QMenu(this);
    //m_trayMenu->addAction("我在线上");
    //m_trayMenu->addAction("离线");
    //m_trayMenu->addSeparator();
    m_trayMenu->addAction("显示主面板");
    m_trayMenu->addSeparator();
    m_trayMenu->addAction("退出");

    systemTrayIcon->setContextMenu(m_trayMenu);
    systemTrayIcon->show();

    connect(systemTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this, SLOT(SltTrayIcoClicked(QSystemTrayIcon::ActivationReason)));
    connect(m_trayMenu, SIGNAL(triggered(QAction*)), this, SLOT(SltTrayIconMenuClicked(QAction*)));
}

void MainWindow::onGroupPopMenuDeleGroup(QAction *action)
{
    QQCell *cell = ui->groupListWidget->GetRightClickedCell();
    QString strgroupname = cell->name;
    if(cell)
    {
        if (!action->text().compare(tr("解散该群")))
        {
            qDebug() << "delete group" << cell->name;

            // 更新数据库
            bool bOk = DataBaseMagr::Instance()->DeleteMyGroup(cell->name, MyApp::m_nId);
            if(bOk)//服務器通知用戶解散
            {
                ui->groupListWidget->removeQQCell(cell);
                // 构建 Json 对象
                QJsonObject json;
                json.insert("id", MyApp::m_nId);
                json.insert("name", cell->name);

                m_tcpSocket->SltSendMessage(DeleteGroup, json);
            }
            CMessageBox::Infomation(this, bOk ? tr("解散成功!") : tr("解散失败!"));
        }
        else if(!action->text().compare(tr("退出该群")))
        {
            // 更新数据库
            bool bOk = DataBaseMagr::Instance()->DeleteMyGroup(cell->name, MyApp::m_nId);
            if(bOk)//服務器通知用戶解散
            {
                ui->groupListWidget->removeQQCell(cell);
            }
            CMessageBox::Infomation(this, bOk ? tr("退出成功!") : tr("退出失败!"));
        }

    }

}


void ClientSocket::SltReadyRead()
{
    QByteArray reply = m_tcpSocket->readAll();
    m_buffer.append(reply);

    int openingBraces = 0;
    int closingBraces = 0;
    int currentIndex = 0;

    while (currentIndex < m_buffer.size())
    {
        char currentChar = m_buffer[currentIndex];

        if (currentChar == '{') {
            openingBraces++;
        } else if (currentChar == '}') {
            closingBraces++;
        }

        if (openingBraces == closingBraces)
        {
            // 形成了一个完整的JSON对象
            QByteArray jsonData = m_buffer.left(currentIndex + 1);
            m_buffer.remove(0, currentIndex + 1);

            QJsonParseError jsonError;
            QJsonDocument document = QJsonDocument::fromJson(jsonData, &jsonError);

            if (!document.isNull() && jsonError.error == QJsonParseError::NoError)
            {
                if (document.isObject())
                {
                    QJsonObject jsonObj = document.object();
                    int nType = jsonObj.value("type").toInt();
                    QJsonValue dataVal = jsonObj.value("data");

                    // 根据消息类型解析服务器消息
                    switch (nType)
                    {
                    case Register:
                    {
                        ParseReister(dataVal);
                    }
                        break;
                    case Login:
                    {
                        ParseLogin(dataVal);
                    }
                        break;
                    case UserOnLine:
                    {
                        qDebug() << "user is oline" << dataVal;
                        Q_EMIT signalMessage(UserOnLine, dataVal);
                    }
                        break;
                    case UserOffLine:
                    {
                        qDebug() << "user is offline" << dataVal;
                        Q_EMIT signalMessage(UserOffLine, dataVal);
                    }
                        break;
                    case Logout:
                    {
                        m_tcpSocket->abort();
                    }
                        break;
                    case UpdateHeadPic:
                    {
                        Q_EMIT signalMessage(UpdateHeadPic, dataVal);
                    }
                        break;
                    case AddFriend:
                    {
                        Q_EMIT signalMessage(AddFriend, dataVal);
                    }
                        break;
                    case AddGroup:
                    {
                        Q_EMIT signalMessage(AddGroup, dataVal);
                    }
                        break;
                    case AddFriendRequist:
                    {
                        Q_EMIT signalMessage(AddFriendRequist, dataVal);
                    }
                        break;
                    case AddGroupRequist:
                    {
                        Q_EMIT signalMessage(AddGroupRequist, dataVal);
                    }
                        break;
                    case CreateGroup:
                    {
                        Q_EMIT signalMessage(CreateGroup, dataVal);
                    }
                        break;
                    case DeleteGroup:
                    {
                        Q_EMIT signalMessage(DeleteGroup, dataVal);
                    }
                        break;
                    case RemoveGroupUser:
                    {
                        Q_EMIT signalMessage(RemoveGroupUser, dataVal);
                    }
                        break;

                    case GetMyFriends:
                    {
                        Q_EMIT signalMessage(GetMyFriends, dataVal);
                    }
                        break;
                    case GetMyGroups:
                    {
                        Q_EMIT signalMessage(GetMyGroups, dataVal);
                    }
                        break;
                    case RefreshFriends:
                    {
                        Q_EMIT signalMessage(RefreshFriends, dataVal);
                    }
                        break;
                    case RefreshGroups:
                    {
                        Q_EMIT signalMessage(RefreshGroups, dataVal);
                    }
                        break;
                    case SendMsg:
                    {
                        Q_EMIT signalMessage(SendMsg, dataVal);
                    }
                        break;
                    case SendGroupMsg:
                    {
                        Q_EMIT signalMessage(SendGroupMsg, dataVal);
                    }
                        break;
                    case SendFile:
                    {
                        Q_EMIT signalMessage(SendFile, dataVal);
                    }
                        break;
                    case SendPicture:
                    {
                        Q_EMIT signalMessage(SendPicture, dataVal);
                    }
                        break;
                    case SendPulicMsg:
                    {
                        Q_EMIT signalMessage(SendPulicMsg, dataVal);
                    }
                        break;
                    default:
                        break;
                    }
                }
            }

            // 重置计数器
            openingBraces = 0;
            closingBraces = 0;
            currentIndex = -1; // 重置索引
        }

        currentIndex++;
    }
}


void ChatWindow::on_btnSendMsg_clicked()
{
    QString text = ui->textEditMsg->toPlainText();
    // 把最后一个回车换行符删掉
    while (text.endsWith("\n")) {
        text.remove(text.length() - 2, 2);
    }

    // 判断消息是否为空
    if (text.isEmpty()) {
        QPoint point = ui->widgetMsg->mapToGlobal(ui->btnSendMsg->pos());

        QToolTip::showText(point, tr("发送消息内容不能为空,请重新输入!"));
        return;
    }

    // 构建json数据
     QJsonObject json;
    if(0 == m_nChatType)
    {
        //QJsonObject json;
        json.insert("id", MyApp::m_nId);
        json.insert("to", m_cell->id);
        json.insert("msg", text);
        json.insert("type", Text);
    }
    else
    {   //mexiugai
        json.insert("id", MyApp::m_nId);
        json.insert("to", m_cell->name);
        json.insert("msg", text);
        json.insert("type", Text);
    }



    // 发送消息
    Q_EMIT signalSendMessage(0 == m_nChatType ? SendMsg : SendGroupMsg, json);

    // 构建气泡消息
    ItemInfo *itemInfo = new ItemInfo();
    itemInfo->SetName(MyApp::m_strUserName);
    itemInfo->SetDatetime(DATE_TIME);
    itemInfo->SetHeadPixmap(MyApp::m_strHeadFile);
    itemInfo->SetText(text);
    itemInfo->SetOrientation(Right);

    // 加入聊天界面
    ui->widgetBubble->addItem(itemInfo);
    // 清除输入框
    ui->textEditMsg->clear();

    // 群组消息不记录
    if (0 != m_nChatType) return;
    // 保存消息记录到数据库
    DataBaseMagr::Instance()->AddHistoryMsg(m_cell->id, itemInfo);
}
Server
typedef enum {
    Unknow,
    Register            = 0x10,     // 用户注册
    Login,                          // 用户登录
    Logout,                         // 用户注销
    LoginRepeat,                    // 重复登录

    UserOnLine          = 0x15,     // 用户上线通知
    UserOffLine,                    // 用户下线通知
    UpdateHeadPic,                  // 用户更新头像

    AddFriend           = 0x20,     // 添加好友
    AddGroup,                       // 添加群组

    AddFriendRequist,               // 添加好友确认通知
    AddGroupRequist,                // 添加群组确认通知

    CreateGroup         = 0x25,     // 创建群组

    GetMyFriends        = 0x30,     // 上线获取我的好友的状态
    GetMyGroups,                    // 获取我的群组信息

    RefreshFriends      = 0x35,     // 刷新好友状态
    RefreshGroups,                  // 刷新群组成员状态

    SendMsg             = 0x40,     // 发送消息
    SendGroupMsg,                   // 发送群组消息
    SendFile,                       // 发送文件
    SendPicture,                    // 发送图片
    SendFace,                       // 发送表情
    SendPulicMsg,                   //大厅消息

    ChangePasswd        = 0x50,     // 修改密码

    DeleteFriend        = 0x55,     // 删除好友
    DeleteGroup,                    // 退出群组
    RemoveGroupUser,                // 踢人

    SendFileOk          = 0x60,     // 文件发送完成状态

    GetFile             = 0x65,     // 获取文件(到服务器下载文件)
    GetPicture,                     // 图片下载

} E_MSG_TYPE;



//每当遇到一个 {,将 openingBraces 计数器加一;每当遇到一个 },将 closingBraces 计数器加一。
//如果在遍历过程中发现了相同数量的 { 和 },则表示找到了一个完整的JSON对象。
void ClientSocket::SltReadyRead()
{
    QByteArray reply = m_tcpSocket->readAll();
    m_buffer.append(reply);

    int openingBraces = 0;
    int closingBraces = 0;
    int currentIndex = 0;

    while (currentIndex < m_buffer.size())
    {
        char currentChar = m_buffer[currentIndex];

        if (currentChar == '{') {
            openingBraces++;
        } else if (currentChar == '}') {
            closingBraces++;
        }

        if (openingBraces == closingBraces)
        {
            // 形成了一个完整的JSON对象
            QByteArray jsonData = m_buffer.left(currentIndex + 1);
            m_buffer.remove(0, currentIndex + 1);

            QJsonParseError jsonError;
            QJsonDocument document = QJsonDocument::fromJson(jsonData, &jsonError);

            if (!document.isNull() && jsonError.error == QJsonParseError::NoError)
            {
                if (document.isObject())
                {
                    QJsonObject jsonObj = document.object();
                    int nType = jsonObj.value("type").toInt();
                    QJsonValue dataVal = jsonObj.value("data");

                    switch (nType) {
                    case Register:
                    {
                        ParseReister(dataVal);
                    }
                        break;
                    case Login:
                    {
                        ParseLogin(dataVal);
                    }
                        break;
                    case UserOnLine:
                    {
                        ParseUserOnline(dataVal);
                    }
                        break;
                    case Logout:
                    {
                        ParseLogout(dataVal);
                        Q_EMIT signalDisConnected();
                        m_tcpSocket->abort();
                    }
                        break;
                    case UpdateHeadPic:
                    {
                        ParseUpdateUserHead(dataVal);
                    }
                        break;
                    case AddFriend:
                    {
                        ParseAddFriend(dataVal);
                    }
                        break;
                    case AddGroup:
                    {
                        ParseAddGroup(dataVal);
                    }
                        break;
                    case CreateGroup:
                    {
                        ParseCreateGroup(dataVal);
                    }
                        break;
                    case DeleteGroup:
                    {
                        ParseDeleteGroup(dataVal);
                    }
                        break;
                    case GetMyFriends:
                    {
                        ParseGetMyFriend(dataVal);
                    }
                        break;
                    case GetMyGroups:
                    {
                        ParseGetMyGroups(dataVal);
                    }
                        break;

                    case RefreshFriends:
                    {
                        ParseRefreshFriend(dataVal);
                    }
                        break;
                    case RefreshGroups:
                    {
                        ParseRefreshGroups(dataVal);
                    }
                        break;

                    case SendMsg:
                    case SendFile:
                    case SendPicture:
                    {
                        ParseFriendMessages(jsonData);
                    }
                        break;
                    case SendGroupMsg:
                    {
                        ParseGroupMessages(jsonData);
                    }
                        break;
                    case SendFace:
                    {
                        ParseFaceMessages(jsonData);
                    }
                        break;
                    case SendFileOk:
                    {

                    }
                        break;
                    case SendPulicMsg:
                    {
                        ParseGroupMessages(jsonData);
                    }
                        break;
                    case GetFile:
                    {
                        Q_EMIT signalDownloadFile(dataVal);
                    }
                        break;
                    default:
                        break;
                    }
                }
            }

            // 重置计数器
            openingBraces = 0;
            closingBraces = 0;
            currentIndex = -1; // 重置索引
        }

        currentIndex++;
    }
}

void ClientSocket::ParseGroupMessages(const QByteArray &reply)
{
    // 重新组装数据
    QJsonParseError jsonError;
    // 转化为 JSON 文档
    QJsonDocument doucment = QJsonDocument::fromJson(reply, &jsonError);
    // 解析未发生错误
    if (!doucment.isNull() && (jsonError.error == QJsonParseError::NoError)) {
        // JSON 文档为对象
        if (doucment.isObject()) {
            // 转化为对象
            QJsonObject jsonObj = doucment.object();
            int nType = jsonObj.value("type").toInt();
            QJsonValue dataVal = jsonObj.value("data");

            QJsonObject dataObj = dataVal.toObject();
            // 转发的群组id
            QString strGroupId = dataObj.value("to").toString();
            QString strMsg = dataObj.value("msg").toString();
            // 查询该群组下面的用户,一一转发消息
            QString name = DataBaseMagr::Instance()->GetUserName(m_nId);//谁发的群消息

            // 查询该群组里面的在线好友
            //QJsonArray jsonArr = DataBaseMagr::Instance()->GetGroupUsers(nGroupId);
            QJsonArray jsonArr = DataBaseMagr::Instance()->GetAllUsers();
            if (jsonArr.size() < 2) return;
            for (int i = 1; i < jsonArr.size(); i++) {
                QJsonObject json = jsonArr.at(i).toObject();
                int nStatus = json.value("status").toInt();
                int nUserId = json.value("id").toInt();

                // 只给在线的好友转发消息
                if (OnLine == nStatus && m_nId != nUserId) {
                    // 重组消息
                    QJsonObject jsonMsg;
                    jsonMsg.insert("group", strGroupId);//群名,用于用户是否接收
                    jsonMsg.insert("id", m_nId);
                    jsonMsg.insert("name", name);
                    jsonMsg.insert("to", nUserId);
                    jsonMsg.insert("msg", strMsg);
                    jsonMsg.insert("head", DataBaseMagr::Instance()->GetUserHead(m_nId));

                    Q_EMIT signalMsgToClient(nType, nUserId, jsonMsg);
                }
            }
        }
    }
}


void ClientSocket::ParseDeleteGroup(const QJsonValue &dataVal)
{
    // data 的 value 是对象
    if (dataVal.isObject())
    {
        QJsonObject dataObj = dataVal.toObject();
        int nId = dataObj.value("id").toInt();
        QString strName = dataObj.value("name").toString();
        bool issuccess = DataBaseMagr::Instance()->DeleteGroup(nId, strName);

        // 发送查询结果至所有客户端
        if(issuccess)
        {
            //SltSendMessage(DeleteGroup, dataVal);
            QJsonArray jsonArr = DataBaseMagr::Instance()->GetAllUsers();
            if (jsonArr.size() < 2) return;
            for (int i = 1; i < jsonArr.size(); i++)
            {
                QJsonObject json = jsonArr.at(i).toObject();
                int nUserId = json.value("id").toInt();
                Q_EMIT signalMsgToClient(DeleteGroup, nUserId, dataVal);

            }
        }

    }
}



QJsonObject DataBaseMagr::CreateGroup(const int &userId, const QString &name)
{
    //查询群组是否存在
    QString strQuery = "SELECT [id],[groupId],[head] FROM GROUPINFO ";
    strQuery.append("WHERE name='");
    strQuery.append(name);
    strQuery.append("' AND userId=");
    strQuery.append(QString::number(userId));

    int nIndex = -1;
    int nGroupId = -1;
    QString strHead = "1.bmp";

    QSqlQuery query(strQuery);
    // 查询用户是否在群组中
    if (query.next()) {
        nIndex   = query.value("id").toInt();
        nGroupId = query.value("groupId").toInt();
        strHead  = query.value("head").toString();
    }
    else {
        //GROUPINFO
        //1.
        //2.
        // 查询数据库
        query = QSqlQuery("SELECT [id] FROM GROUPINFO ORDER BY id DESC;");
        nIndex = 0;
        // 查询最高ID
        if (query.next()) {
            nIndex = query.value("id").toInt();
        }

        // 再查询该ID下面的群组
        nGroupId = 0;
        strQuery = QString("SELECT [groupId] FROM GROUPINFO WHERE userId=");
        strQuery.append(QString::number(userId));
        strQuery.append(" ORDER BY groupId DESC");
        query = QSqlQuery(strQuery);
        // 查询最高ID
        if (query.next()) {
            nGroupId = query.value("groupId").toInt();
        }

        nIndex   += 1;
        nGroupId += 1;

        // 根据新ID重新创建用户
        query.prepare("INSERT INTO GROUPINFO (id, groupId, name, head, userId, identity) "
                      "VALUES (?, ?, ?, ?, ?, ?);");
        query.bindValue(0, nIndex);
        query.bindValue(1, nGroupId);
        query.bindValue(2, name);
        query.bindValue(3, "1.bmp");
        query.bindValue(4, userId);
        query.bindValue(5, 1);

        query.exec();

        QVector<int> tmpuser;
        tmpuser.push_back(userId);
        m_GroupsMap[name] = tmpuser;

    }

    // 构建 Json 对象
    QJsonObject json;
    json.insert("id",  nGroupId);
    json.insert("name", name);
    json.insert("head", strHead);

    return json;
}

bool DataBaseMagr::DeleteGroup(const int &userId, const QString &name)
{
    QString strQuery = "SELECT [id],[groupId],[head] FROM GROUPINFO ";
    strQuery.append("WHERE name='");
    strQuery.append(name);
    strQuery.append("'");
//    strQuery.append("' AND userId=");
//    strQuery.append(QString::number(userId));
    QSqlQuery query(strQuery);//执行查询
    if(query.next())
    {
        // 删除符合条件的记录
        QString strDelete = "DELETE FROM GROUPINFO ";
        strDelete.append("WHERE name='");
        strDelete.append(name);
        strDelete.append("'");
//        strDelete.append(" AND userId=");

//        strDelete.append(QString::number(userId));
        // 执行删除操作
        QSqlQuery deleteQuery(strDelete, userdb);
        // 检查是否删除成功
        if (deleteQuery.exec())
        {
            // 查找该键对应的迭代器
            auto it = m_GroupsMap.find(name);
            if (it != m_GroupsMap.end())
            {
                // 找到了该键,使用迭代器删除条目
                m_GroupsMap.erase(it);
            } else {
                // 没有找到该键
                return false;
            }

            return true;
        }
        else
        {
            return false;
        }
    }

    return false;
}
QJsonObject DataBaseMagr::AddGroup(const int &userId, const QString &name)
{
#if 0
    QString strQuery = "SELECT [groupId] FROM GROUPINFO ";
    strQuery.append("WHERE name='");
    strQuery.append(name);
    strQuery.append("' AND userId=");
    strQuery.append(QString::number(userId));

    int nGroupId = -1;
    QString strHead = "1.bmp";

    QSqlQuery query(strQuery);

    // 查询到有该用户组
    if (query.next()) {
        nGroupId = query.value(0).toInt();
        strHead  = query.value(1).toString();
    }
    else {
        // 查询数据库
        query = QSqlQuery("SELECT [id] FROM GROUPINFO ORDER BY id DESC;");
        int nIndex = 0;
        // 查询最高ID
        if (query.next()) {
            nIndex = query.value(0).toInt();
        }

        nIndex   += 1;

        // 查询当前组是否存在
        strQuery = QString("SELECT [groupId] FROM GROUPINFO WHERE name='");
        strQuery.append(name);
        strQuery.append("'");

        query = QSqlQuery(strQuery);
        // 查询最高ID
        if (query.next()) {
            nGroupId = query.value(0).toInt();
            // 根据新ID重新创建用户
            query.prepare("INSERT INTO GROUPINFO (id, groupId, name, userId, identity) "
                          "VALUES (?, ?, ?, ?, ?);");
            query.bindValue(0, nIndex);
            query.bindValue(1, nGroupId);
            query.bindValue(2, name);
            query.bindValue(3, userId);
            query.bindValue(4, 1);
            // 执行插入
            query.exec();
        }
    }
#else
    // 先查询是否有该群组
    QString strQuery = "SELECT [groupId] FROM GROUPINFO ";
    strQuery.append("WHERE name='");
    strQuery.append(name);
    strQuery.append("';");

    int nGroupId = -1;
    int nCode    = -1;
    QString strHead = "5.bmp";

    QSqlQuery query(strQuery);

    // 查询到有该用户组
    if (query.next())
    {
        // 查询到有该群组,再判断该用户是否已经加入该群组
        nGroupId = query.value(0).toInt();
        strQuery = QString("SELECT [userId] FROM GROUPINFO WHERE groupId=");
        strQuery.append(QString::number(nGroupId));
        strQuery.append("");

        query = QSqlQuery(strQuery);
        // 查询到已经添加到该群组
        if (query.next()) {
            nCode = -2;
        }
        else
        {
            // 查询数据库
            query = QSqlQuery("SELECT [id] FROM GROUPINFO ORDER BY id DESC;");
            int nIndex = 0;
            // 查询最高ID
            if (query.next()) {
                nIndex = query.value(0).toInt();
            }

            nIndex   += 1;

            // 根据新ID重新创建用户
            query.prepare("INSERT INTO GROUPINFO (id, groupId, name, userId, identity) "
                          "VALUES (?, ?, ?, ?, ?);");
            query.bindValue(0, nIndex);
            query.bindValue(1, nGroupId);
            query.bindValue(2, name);
            query.bindValue(3, userId);
            query.bindValue(4, 3);
            // 执行插入
            query.exec();
        }
    }
#endif
    // 构建 Json 对象
    QJsonObject json;
    json.insert("id",  nGroupId);
    json.insert("name", name);
    json.insert("head", strHead);
    json.insert("code", nCode);

    QueryAll();


    // 如果该键不存在,先创建一个空的 QVector<int>
    if (!m_GroupsMap.contains(name)) {
        m_GroupsMap.insert(name, QVector<int>());
    }
    // 获取键对应的 QVector<int> 引用
    QVector<int> &values = m_GroupsMap[name];
    // 确保值是唯一的,然后再添加
    if (!values.contains(userId)) {
        values.append(userId);
    }


    return json;
}


void MainWindow::on_btnUserEdit_clicked()
{
    // 获取选中的行索引
    QModelIndexList selectedIndexes = ui->tableViewUsers->selectionModel()->selectedRows();

    // 遍历选中的行索引,获取对应的数据
    QVariant Id;
    QVariant nameData;
    QVariant pwData;
    QVariant statusData;
    for (const QModelIndex &index : selectedIndexes) {
        // 使用 QModelIndex 来访问数据,m_model 是你设置的模型
        Id = m_model->data(m_model->index(index.row(), 0)); // 第0列是na
        nameData = m_model->data(m_model->index(index.row(), 1)); // 第0列是na
        pwData = m_model->data(m_model->index(index.row(), 2)); // 第1列是pw
        statusData = m_model->data(m_model->index(index.row(), 3)); // 第1列是pw
        // 在这里处理获取到的数据,例如输出到调试窗口
        //qDebug() << "Selected data - Name:" << nameData.toString() << ", Age:" << ageData.toInt();
    }

    if(statusData == "在线")
    {
        // 判断
        CMessageBox::Infomation(this, tr("提示"), tr("当前用户处于在线状态,无法修改"));
        return;
    }




    QString strName = ui->lineEditAddUser->text();
    QString strPasswd = ui->lineEditAddPasswd->text();

    if (strName.isEmpty()) {
        CMessageBox::Infomation(this, tr("提示"), tr("用户名不能为空"));
        return;
    }

    strPasswd = strPasswd.isEmpty() ? "123456" : strPasswd;

    int nId = DataBaseMagr::Instance()->EditUser(strName, strPasswd,nameData.toString(),pwData.toString(),Id.toString());

    // 判断
    CMessageBox::Infomation(this, tr("提示"), -1 == nId ? tr("修改用户失败") : tr("修改用户成功!"));
    if (-1 != nId) {
        on_btnUserRefresh_clicked();
    }
}


int DataBaseMagr::EditUser(const QString &newName, const QString &newPassword, const QString &old_name, const QString &old_passwd,const QString &userId)
{
    // 构建更新语句,根据 ID 更新姓名和密码
    QString updateQuery = "UPDATE USERINFO SET name = :newName, passwd = :newPwd WHERE id = :userId";

    // 准备查询
    QSqlQuery query;
    query.prepare(updateQuery);
    query.bindValue(":newName", newName);
    query.bindValue(":newPwd", newPassword);
    query.bindValue(":userId", userId);

    // 执行更新操作
    if (query.exec()) {
        qDebug() << "Update successful!";
        return 1;
    } else {
        //qDebug() << "Update failed:" << query.lastError().text();
        return -1;
    }
}

//构造函数里
  ui->tableViewUsers->setModel(m_model);
    // 设置表格只能选择一行
    ui->tableViewUsers->setSelectionBehavior(QAbstractItemView::SelectRows); // 选择行为为整行
    ui->tableViewUsers->setSelectionMode(QAbstractItemView::SingleSelection); // 选择模式为单选

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值