个人信息修改昵称
个人信息修改昵称
前言
在上一集我们就把我们数据中心的个人信息的内容设置到了我们个人信息窗口上了.那么我们这一方面完成了,我们就应该对这里面的三大可修改要素进行修改处理.也就是我们要开始完成他们的修改功能.这一集就先完成修改个人昵称的内容.
需求分析
我们点击昵称修改按钮,就会进入输入框.输入框会回显我们的原本的label内容,我们可以重新输入心的昵称进行修改.
这就是我们之前完成的内容.
我们要修改完我们的内容之后,点击右侧的提交按钮,就能修改我们的昵称,我们就会把昵称修改的结果保存到我们的DataCenter中的myself里.
而且我们要修改完我们的昵称后,我们的会话中的消息也会同时进行修改!
那么我们的任务就是如此,我们先来看一眼我们的URL和请求响应的定义!
这就是我们的URL
这就是我们的请求和响应的定义!
客户端
我们还是老规矩,我们分为客户端和测试服务端两边开工!
我们能够修改这个昵称,就应该绑定我们的提交按钮,我们就需要给他创建信号槽内容
connect(nameSubmitBtn, &QPushButton::clicked, this, &SelfInfoWidget::clickNameSubmitBtn);
只要点击了我们的提交按钮就会开始运行我们的函数.
这个函数也是很简单,我们要先获取到我们的输入框的内容,如果输入框的内容是空的,我们就可以直接返回了,如果是有内容的,我们就去发送一个网络请求!
当然我们这里是调用重新设置界面的地方,我们在网络那边处理完成之后也是会发送一个信号到DataCenter的,我们届时就要调用一个函数来处理我们的修改,所以我们这里就要连接一个信号槽.
我们先来看一下我们的这个函数先
void SelfInfoWidget::clickNameSubmitBtn()
{
//先从输入框中获取到修改后的昵称
const QString& nickname = nameEdit->text();
if(nickname.isEmpty()){
return;
}
//发送网络请求
DataCenter* dataCenter = DataCenter::getInstance();
connect(dataCenter, &DataCenter::changeNicknameDone, this, &SelfInfoWidget::clickNameSubmitBtnDone, Qt::UniqueConnection);
dataCenter->changeNicknameAsync(nickname);
}
我们这里还是需要通过数据中心DataCenter传递我们的loginSessionId,还有传输我们的修改昵称的内容!
void DataCenter::changeNicknameAsync(const QString &nickname)
{
netClient.changeNickname(loginSessionId, nickname);
}
之后就是到了我们NetClient发送http请求和处理http响应的地方.
我们已经写过很多次这样的代码了,大家可以直接复制粘贴!这里我们处理完响应之后,我们就要把昵称信息保存到我们的数据中心的myself当中并发送一个信号给到我们的DataCenter.
void NetClient::changeNickname(const QString &loginSessionId, const QString &nickname)
{
//构造http请求body
bite_im::SetUserNicknameReq pbReq;
pbReq.setRequestId(makeRequestId());
pbReq.setSessionId(loginSessionId);
pbReq.setNickname(nickname);
QByteArray body = pbReq.serialize(&serializer);
LOG() << "[修改用户昵称] 发送请求 requestId=" << pbReq.requestId() << ", loginSessionId=" << pbReq.sessionId()
<<", nickname=" << pbReq.nickname();
//发送http请求
QNetworkReply* resp = this->sendHttpRequest("/service/user/set_nickname", body);
//处理响应
connect(resp, &QNetworkReply::finished, this, [=](){
bool ok = false;
QString reason;
auto pbResp = this->handleHttpResponse<bite_im::SetUserNicknameRsp>(resp, &ok, &reason);
//判定是否出错
if(!ok){
LOG() << "[修改用户昵称]出错!reason=" << reason;
return;
}
//设置数据到DataCenter
dataCenter->resetNickname(nickname);
//发送信号,通知调用
emit dataCenter->changeNicknameDone();
LOG() << "[修改用户昵称] 处理响应完毕! requestId=" << pbResp->requestId();
});
}
这里重新设置昵称的函数如下
void DataCenter::resetNickname(const QString &nickname)
{
if(myself == nullptr){
return;
}
myself->nickname = nickname;
}
我们要先去判断我们的myself是否为空指针,如果是空的,我们就直接返回即可.
发送了信号就会跳转到我们原来的那个位置
connect(dataCenter, &DataCenter::changeNicknameDone, this, &SelfInfoWidget::clickNameSubmitBtnDone, Qt::UniqueConnection);
我们这里还封装了一个函数.
这个函数就是处理我们界面的渲染问题,我们要先把输入框以及提交按钮给隐藏了,之后展示我们的label以及修改按钮.
最关键的是我们要把我们获取到的数据设置到我们的label上.
void SelfInfoWidget::clickNameSubmitBtnDone()
{
//界面控件进行切换
//同时label设置为输入框的内容
layout->removeWidget(nameEdit);
nameEdit->hide();
layout->addWidget(nameLabel,1,2);
nameLabel->show();
nameLabel->setText(nameEdit->text());
layout->removeWidget(nameSubmitBtn);
nameSubmitBtn->hide();
layout->addWidget(nameModifyBtn,1,3);
nameModifyBtn->show();
}
那么客户端这边的内容就完成了.
测试服务端
我们就要来到测试服务端这边.
第一步还是配置我们的路由
httpServer.route("/service/user/set_nickname", [=](const QHttpServerRequest& req){
return this->setNickname(req);
});
第二步也是最后一步,我们接收请求并构造响应返回响应.
QHttpServerResponse HttpServer::setNickname(const QHttpServerRequest &req)
{
//解析请求
bite_im::SetUserNicknameReq pbReq;
pbReq.deserialize(&serializer, req.body());
LOG() << "[REQ 修改用户昵称] requestId=" << pbReq.requestId() << ", loginSessionId=" << pbReq.sessionId()
<<", nickname=" << pbReq.nickname();
//构造响应
bite_im::SetUserNicknameRsp pbResp;
pbResp.setRequestId(pbReq.requestId());
pbResp.setSuccess(true);
pbResp.setErrmsg("");
QByteArray body = pbResp.serialize(&serializer);
//构造http响应
QHttpServerResponse resp(body, QHttpServerResponse::StatusCode::Ok);
resp.setHeader("Content-Type", "application/x-protobuf");
return resp;
}
反正构造请求和构造响应,我们只需要按照proto文件那里来就行,难度不高.
这样我们的这个功能的链路就可以跑通了.
但是我们还少了一个步骤,就是我们这里修改了昵称之后,我们的消息展示区的个人昵称是不会改变的.所以我们要在消息展示区给每一个messageItem也设置一个信号槽来接收我们上述的changeNicknameDone的信号!
当然我们仅仅只是修改了自己的昵称,我们是不会修改别人的昵称的,所以我们只给isLeft为false的messageItem添加这个信号槽.
if(!isLeft){
//用户修改了昵称,同步修改此处的用户名称(只针对自己的消息)
DataCenter* dataCenter = DataCenter::getInstance();
connect(dataCenter, &DataCenter::changeNicknameDone, messageItem, [=](){
nameLabel->setText(dataCenter->getMyself()->nickname + " | " + message.time);
});
}
这样,我们就可以实现修改了昵称之后,我们在消息展示区上的自己发送的消息上的昵称也会相应改变了!
那么这一集就先到这里.