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); // 选择模式为单选