聊天室四(增加好友申请功能)

在昨天基础上新增好友申请的功能:

ChatServer服务端:

1.在dbcmd.h中添加处理好友申请的函数声明:

/**
     * @brief 获取用户的id
     * @param username 用户名
     * @param id 获取到的id
     * @return 获取的结果
     */
    bool getUserId(QString username, int &id);
    /**
     * @brief 查找用户
     * @param username 自己的用户名,防止把自己找出来
     * @param name
     * @param list
     * @return
     */
    bool findUser(QString username, QString name, QJsonArray &list);

    // 检查用户是否存在
    bool checkUserExists(const QString &username);
    // 添加好友申请
    bool addFriendRequest(const QString &fromUser,
                          const QString &toUser, const QString &msg);

2.在dbcmd.cpp中实现:

bool DBCmd::getUserId(QString username, int &id)
{
    QSqlQuery query(*db);
    QString cmd;
    cmd = QString("SELECT id FROM `chat_user` "
                  "WHERE username = '%1';")
              .arg(username);
    bool ok = query.exec(cmd);
    if(!ok) return false;
    if(!query.next()) return false;
    id = query.value("id").toInt();
    return true;
}

bool DBCmd::findUser(QString username, QString name, QJsonArray &list)
{
    QSqlQuery query(*db);
    QString cmd;
    cmd = QString("SELECT cu.username, cu_info.name "
                  "FROM `chat_user` AS cu "
                  "JOIN `chat_user_info` AS cu_info "
                  "ON cu.id = cu_info.user_id "
                  "WHERE (cu_info.name LIKE '%%1%' "
                  "OR cu.username LIKE '%%1%') "
                  "AND cu.username != '%2';")
              .arg(name)
              .arg(username);
    bool ok = query.exec(cmd);
    if(!ok) return false;
    while(query.next()){
        QJsonObject obj;
        obj.insert("username", query.value("username").toString());
        obj.insert("name", query.value("name").toString());
        list.append(obj);
    }
    return true;
}

bool DBCmd::checkUserExists(const QString &username)
{
    QSqlQuery query(*db);
    QString cmd = QString("SELECT id FROM `chat_user` WHERE username = '%1';")
                      .arg(username);

    if (!query.exec(cmd)) {
        return false;
    }

    return query.next(); // 如果有结果,返回true
}

bool DBCmd::addFriendRequest(const QString &fromUser, const QString &toUser, const QString &msg)
{
    QSqlQuery query(*db);
    QString date = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");

    // 获取用户ID
    int fromUserId = -1;
    int toUserId = -1;

    // 查询发送者ID
    QString cmd = QString("SELECT id FROM `chat_user` WHERE username = '%1';").arg(fromUser);
    if (!query.exec(cmd) || !query.next()) {
        return false;
    }
    fromUserId = query.value("id").toInt();

    // 查询接收者ID
    cmd = QString("SELECT id FROM `chat_user` WHERE username = '%1';").arg(toUser);
    if (!query.exec(cmd) || !query.next()) {
        return false;
    }
    toUserId = query.value("id").toInt();

    // 插入好友申请
    cmd = QString("INSERT INTO `friend_request` "
                  "(from_user_id, to_user_id, request_msg, create_time, status) "
                  "VALUES(%1, %2, '%3', '%4', 0);")
              .arg(fromUserId)
              .arg(toUserId)
              .arg(msg)
              .arg(date);

    db->transaction();
    bool ok = query.exec(cmd);
    if (!ok || query.numRowsAffected() <= 0) {
        db->rollback();
        return false;
    }

    db->commit();
    return true;
}

3.在mytcpsocket.h中添加处理好友申请的函数声明:

// 在class MyTcpSocket的protected部分添加
void handleFindUser(const QJsonObject &obj);
void handleAddFriend(const QJsonObject &obj);

4.在mytcpsocket.cpp中实现:

// 在handleFrame函数的switch语句中添加
case 2101:
        handleFindUser(obj);
        break;
case 2102:
    handleAddFriend(obj);
    break;



void MyTcpSocket::handleFindUser(const QJsonObject &obj)
{
    QString name = obj.value("name").toString();
    QJsonArray list;
    DBCmd *cmd = DBExec::getObject()->getCmd();
    bool ok = cmd->findUser(
        username, name, list);
    DBExec::getObject()->releaseCmd(cmd);
    QJsonObject reObj;
    reObj.insert("type", 2101);
    reObj.insert("list", list);
    write(QJsonDocument(reObj).toJson());
}

void MyTcpSocket::handleAddFriend(const QJsonObject &obj)
{
    QString targetUsername = obj.value("username").toString();
    QString requestMsg = obj.value("request_msg").toString();

    // 验证目标用户是否存在
    DBCmd *cmd = DBExec::getObject()->getCmd();
    bool userExists = cmd->checkUserExists(targetUsername);

    bool ok = false;
    if (userExists) {
        // 发送好友申请(保存到数据库)
        ok = cmd->addFriendRequest(username, targetUsername, requestMsg);
    }

    DBExec::getObject()->releaseCmd(cmd);

    // 构建反馈消息
    QJsonObject reObj;
    reObj.insert("type", 2102);
    reObj.insert("re", ok);
    write(QJsonDocument(reObj).toJson());
}

二、ChatClient客户端

1.在netexec.h中添加发送好友申请的函数声明和反馈信号:

// 在Net/netexec.h的public部分添加
/**
     * @brief findUser 查找用户
     * @param name
     */
    void findUser(QString name);
/**
 * @brief 发送好友申请
 * @param username 目标用户名
 * @param requestMsg 申请信息
 */
void sendFriendRequest(QString username, QString requestMsg);



// 在signals部分添加
void findUserReveived(QJsonArray list);
// 好友申请反馈信号
void friendRequestStatus(bool re);

//在protected部分添加
void handleFindUserRe(const QJsonObject &obj);
void handleFriendRequestRe(const QJsonObject &obj);

2.在netexec.cpp中实现查找好友,发送好友申请的函数和处理反馈的逻辑:

void NetExec::findUser(QString name)
{
    QJsonObject obj;
    obj.insert("type", 2101);
    obj.insert("key", key);
    obj.insert("name", name);
    m_client->write(QJsonDocument(obj).toJson());
}

void NetExec::sendFriendRequest(QString username, QString requestMsg)
{
    QJsonObject obj;
    obj.insert("type", 2102);  // 协议规定的类型
    obj.insert("key", key);    // 当前用户的密钥
    obj.insert("username", username);  // 目标好友用户名
    obj.insert("request_msg", requestMsg);  // 申请信息
    m_client->write(QJsonDocument(obj).toJson());
}

// 在handleFrame函数的switch-case中添加对2102类型反馈的处理
    case 2101:
        handleFindUserRe(obj);
        break;
    case 2102:
        handleFriendRequestRe(obj);
        break;



void NetExec::handleFindUserRe(const QJsonObject &obj)
{
    QJsonArray list = obj.value("list").toArray();
    emit findUserReveived(list);
}

void NetExec::handleFriendRequestRe(const QJsonObject &obj)
{
    bool re = obj.value("re").toBool();
    emit friendRequestStatus(re);
}

3.在addfriendpage.h中添加处理好友申请反馈的槽函数声明:

// 在private slots部分添加
void onFriendRequestStatus(bool re);

4.在addfriendpage.cpp中完善双击列表项发送好友申请的功能:

// 包含QInputDialog头文件
#include <QInputDialog>
#include <QMessageBox>



// 在构造函数中添加信号连接
AddFriendPage::AddFriendPage(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::AddFriendPage)
{
    ui->setupUi(this);
    connect(NetExec::getObject(), &NetExec::findUserReveived,
            this, &AddFriendPage::findUserReveivedSlot);
    // 连接好友申请反馈信号
    connect(NetExec::getObject(), &NetExec::friendRequestStatus,
            this, &AddFriendPage::onFriendRequestStatus);
}



void AddFriendPage::onFriendRequestStatus(bool re)
{
    if (re) {
        QMessageBox::information(this, tr("提示"), tr("好友申请已发送!"));
    } else {
        QMessageBox::warning(this, tr("提示"), tr("好友申请发送失败!"));
    }
}


void AddFriendPage::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
{
    QString text = item->text();
    QString username = text.split('-').at(0);
    //QInputDialog 输入申请信息
    bool ok;
    QString requestMsg = QInputDialog::getText(
        this,
        tr("添加好友"),
        tr("请输入申请信息:"),
        QLineEdit::Normal,
        tr("我想加你为好友"),
        &ok
        );

    if (ok && !requestMsg.isEmpty()) {
        // 发送好友申请
        NetExec::getObject()->sendFriendRequest(username, requestMsg);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值