#include "onlineuserswidget.h" #include #include #include #include OnlineUsersWidget::OnlineUsersWidget(QWidget *parent) : QWidget(parent) , m_mainLayout(nullptr) , m_headerLayout(nullptr) , m_titleLabel(nullptr) , m_countLabel(nullptr) , m_refreshButton(nullptr) , m_searchEdit(nullptr) , m_usersTable(nullptr) , m_contextMenu(nullptr) , m_privateMessageAction(nullptr) , m_viewProfileAction(nullptr) , m_kickUserAction(nullptr) { setupUI(); setupTable(); setupContextMenu(); applyStyles(); // 添加一些示例数据 addUser(OnlineUser("1", "管理员", "在线")); addUser(OnlineUser("2", "用户A", "在线")); addUser(OnlineUser("3", "用户B", "离开")); addUser(OnlineUser("4", "用户C", "忙碌")); } OnlineUsersWidget::~OnlineUsersWidget() { } void OnlineUsersWidget::setupUI() { m_mainLayout = new QVBoxLayout(this); m_mainLayout->setContentsMargins(8, 8, 8, 8); m_mainLayout->setSpacing(6); // 头部布局 m_headerLayout = new QHBoxLayout(); m_titleLabel = new QLabel("在线用户", this); m_titleLabel->setObjectName("titleLabel"); m_countLabel = new QLabel("(0)", this); m_countLabel->setObjectName("countLabel"); m_refreshButton = new QPushButton("刷新", this); m_refreshButton->setObjectName("refreshButton"); m_refreshButton->setMaximumWidth(60); m_headerLayout->addWidget(m_titleLabel); m_headerLayout->addWidget(m_countLabel); m_headerLayout->addStretch(); m_headerLayout->addWidget(m_refreshButton); // 搜索框 m_searchEdit = new QLineEdit(this); m_searchEdit->setPlaceholderText("搜索用户..."); m_searchEdit->setObjectName("searchEdit"); // 用户表格 m_usersTable = new QTableWidget(this); m_usersTable->setObjectName("usersTable"); // 添加到主布局 m_mainLayout->addLayout(m_headerLayout); m_mainLayout->addWidget(m_searchEdit); m_mainLayout->addWidget(m_usersTable); // 连接信号 connect(m_refreshButton, &QPushButton::clicked, this, &OnlineUsersWidget::onRefreshClicked); connect(m_searchEdit, &QLineEdit::textChanged, this, &OnlineUsersWidget::onSearchTextChanged); } void OnlineUsersWidget::setupTable() { // 设置表格列 - 原有3列 + 新增6列 m_usersTable->setColumnCount(9); QStringList headers; headers << "状态" << "用户名" << "最后活动" << "1" << "2" << "3" << "4" << "5" << "6"; m_usersTable->setHorizontalHeaderLabels(headers); // 设置表格属性 m_usersTable->setSelectionBehavior(QAbstractItemView::SelectRows); m_usersTable->setSelectionMode(QAbstractItemView::SingleSelection); m_usersTable->setAlternatingRowColors(true); m_usersTable->setShowGrid(false); m_usersTable->verticalHeader()->setVisible(false); // 设置列宽 QHeaderView *header = m_usersTable->horizontalHeader(); header->setStretchLastSection(false); header->resizeSection(0, 60); // 状态列 header->resizeSection(1, 120); // 用户名列 header->resizeSection(2, 80); // 最后活动列 // 设置新增的1-6列宽度 for (int i = 3; i < 9; ++i) { header->resizeSection(i, 40); } // 连接信号 connect(m_usersTable, &QTableWidget::itemDoubleClicked, [this](QTableWidgetItem *item) { if (item) { onTableDoubleClicked(item->row(), item->column()); } }); m_usersTable->setContextMenuPolicy(Qt::CustomContextMenu); connect(m_usersTable, &QTableWidget::customContextMenuRequested, this, &OnlineUsersWidget::onTableContextMenu); } void OnlineUsersWidget::setupContextMenu() { m_contextMenu = new QMenu(this); m_privateMessageAction = new QAction("发送私信", this); m_viewProfileAction = new QAction("查看资料", this); m_kickUserAction = new QAction("踢出用户", this); m_contextMenu->addAction(m_privateMessageAction); m_contextMenu->addAction(m_viewProfileAction); m_contextMenu->addSeparator(); m_contextMenu->addAction(m_kickUserAction); // 连接信号 connect(m_privateMessageAction, &QAction::triggered, [this]() { if (!m_selectedUserId.isEmpty()) { emit privateMessageRequested(m_selectedUserId, m_selectedUsername); } }); connect(m_viewProfileAction, &QAction::triggered, [this]() { if (!m_selectedUserId.isEmpty()) { emit userProfileRequested(m_selectedUserId, m_selectedUsername); } }); connect(m_kickUserAction, &QAction::triggered, [this]() { // TODO: 实现踢出用户功能 qDebug() << "踢出用户:" << m_selectedUsername; }); } void OnlineUsersWidget::applyStyles() { setStyleSheet( "#titleLabel {" " font-size: 14px;" " font-weight: bold;" " color: #2c3e50;" "}" "#countLabel {" " font-size: 12px;" " color: #7f8c8d;" " margin-left: 5px;" "}" "#refreshButton {" " padding: 4px 8px;" " border: 1px solid #bdc3c7;" " border-radius: 3px;" " background-color: #ecf0f1;" "}" "#refreshButton:hover {" " background-color: #d5dbdb;" "}" "#refreshButton:pressed {" " background-color: #bdc3c7;" "}" "#searchEdit {" " padding: 6px;" " border: 1px solid #bdc3c7;" " border-radius: 3px;" " font-size: 12px;" "}" "#usersTable {" " border: 1px solid #bdc3c7;" " border-radius: 3px;" " background-color: white;" " gridline-color: #ecf0f1;" "}" "#usersTable::item {" " padding: 8px;" " border-bottom: 1px solid #ecf0f1;" "}" "#usersTable::item:selected {" " background-color: #3498db;" " color: white;" "}" "#usersTable::item:hover {" " background-color: #ecf0f1;" "}" ); } void OnlineUsersWidget::addUser(const OnlineUser &user) { // 检查用户是否已存在 int existingRow = findUserRow(user.userId); if (existingRow >= 0) { // 更新现有用户 m_users[existingRow] = user; updateTableRow(existingRow, user); return; } // 添加新用户 m_users.append(user); // 如果当前有过滤条件,检查是否匹配 if (!m_currentFilter.isEmpty()) { if (!user.username.contains(m_currentFilter, Qt::CaseInsensitive)) { updateUserCountLabel(); return; } } // 添加到表格 int row = m_usersTable->rowCount(); m_usersTable->insertRow(row); updateTableRow(row, user); updateUserCountLabel(); } void OnlineUsersWidget::removeUser(const QString &userId) { int row = findUserRow(userId); if (row >= 0) { m_users.removeAt(row); m_usersTable->removeRow(row); updateUserCountLabel(); } } void OnlineUsersWidget::updateUserStatus(const QString &userId, const QString &status) { int userIndex = -1; for (int i = 0; i < m_users.size(); ++i) { if (m_users[i].userId == userId) { userIndex = i; break; } } if (userIndex >= 0) { m_users[userIndex].status = status; m_users[userIndex].lastSeen = QDateTime::currentDateTime(); // 更新表格中对应的行 int row = findUserRow(userId); if (row >= 0) { updateTableRow(row, m_users[userIndex]); } } } void OnlineUsersWidget::updateUserList(const QJsonArray &users) { clearUsers(); for (const auto &value : users) { if (value.isObject()) { QJsonObject userObj = value.toObject(); OnlineUser user; user.userId = userObj["id"].toString(); user.username = userObj["username"].toString(); user.status = userObj["status"].toString("在线"); user.isAdmin = userObj["isAdmin"].toBool(false); if (userObj.contains("lastSeen")) { user.lastSeen = QDateTime::fromString(userObj["lastSeen"].toString(), Qt::ISODate); } else { user.lastSeen = QDateTime::currentDateTime(); } addUser(user); } } } void OnlineUsersWidget::clearUsers() { m_users.clear(); m_usersTable->setRowCount(0); updateUserCountLabel(); } QList OnlineUsersWidget::getAllUsers() const { return m_users; } OnlineUser OnlineUsersWidget::getUser(const QString &userId) const { for (const auto &user : m_users) { if (user.userId == userId) { return user; } } return OnlineUser(); } int OnlineUsersWidget::getUserCount() const { return m_users.size(); } void OnlineUsersWidget::setSearchVisible(bool visible) { m_searchEdit->setVisible(visible); } void OnlineUsersWidget::filterUsers(const QString &keyword) { m_currentFilter = keyword; // 清空表格 m_usersTable->setRowCount(0); // 重新添加匹配的用户 for (const auto &user : m_users) { if (keyword.isEmpty() || user.username.contains(keyword, Qt::CaseInsensitive)) { int row = m_usersTable->rowCount(); m_usersTable->insertRow(row); updateTableRow(row, user); } } updateUserCountLabel(); } void OnlineUsersWidget::onTableDoubleClicked(int row, int column) { Q_UNUSED(column); if (row >= 0 && row < m_usersTable->rowCount()) { QTableWidgetItem *userItem = m_usersTable->item(row, 1); // 用户名列 if (userItem) { QString username = userItem->text(); // 从用户列表中找到对应的userId for (const auto &user : m_users) { if (user.username == username) { emit userDoubleClicked(user.userId, username); break; } } } } } void OnlineUsersWidget::onTableContextMenu(const QPoint &position) { QTableWidgetItem *item = m_usersTable->itemAt(position); if (!item) return; int row = item->row(); QTableWidgetItem *userItem = m_usersTable->item(row, 1); if (!userItem) return; QString username = userItem->text(); // 从用户列表中找到对应的userId for (const auto &user : m_users) { if (user.username == username) { m_selectedUserId = user.userId; m_selectedUsername = username; // 根据用户权限显示/隐藏菜单项 m_kickUserAction->setVisible(user.isAdmin); // 示例:只有管理员能踢人 QPoint globalPos = m_usersTable->mapToGlobal(position); emit userRightClicked(user.userId, username, globalPos); m_contextMenu->exec(globalPos); break; } } } void OnlineUsersWidget::onSearchTextChanged(const QString &text) { filterUsers(text); } void OnlineUsersWidget::onRefreshClicked() { // TODO: 发送刷新用户列表的请求 qDebug() << "刷新用户列表"; } void OnlineUsersWidget::updateUserCountLabel() { int totalUsers = m_users.size(); int displayedUsers = m_usersTable->rowCount(); if (m_currentFilter.isEmpty()) { m_countLabel->setText(QString("(%1)").arg(totalUsers)); } else { m_countLabel->setText(QString("(%1/%2)").arg(displayedUsers).arg(totalUsers)); } } void OnlineUsersWidget::updateTableRow(int row, const OnlineUser &user) { // 状态列 QTableWidgetItem *statusItem = new QTableWidgetItem(getStatusIcon(user.status) + " " + user.status); statusItem->setFlags(statusItem->flags() & ~Qt::ItemIsEditable); m_usersTable->setItem(row, 0, statusItem); // 用户名列 QTableWidgetItem *nameItem = new QTableWidgetItem(user.username); nameItem->setFlags(nameItem->flags() & ~Qt::ItemIsEditable); if (user.isAdmin) { nameItem->setText(user.username + " (管理员)"); nameItem->setForeground(QColor("#e74c3c")); } m_usersTable->setItem(row, 1, nameItem); // 最后活动时间列 QString timeText = user.lastSeen.toString("hh:mm"); QTableWidgetItem *timeItem = new QTableWidgetItem(timeText); timeItem->setFlags(timeItem->flags() & ~Qt::ItemIsEditable); m_usersTable->setItem(row, 2, timeItem); // 添加1-6列的内容 for (int i = 3; i < 9; ++i) { QTableWidgetItem *numberItem = new QTableWidgetItem(QString::number(i - 2)); numberItem->setFlags(numberItem->flags() & ~Qt::ItemIsEditable); numberItem->setTextAlignment(Qt::AlignCenter); m_usersTable->setItem(row, i, numberItem); } } int OnlineUsersWidget::findUserRow(const QString &userId) const { for (int i = 0; i < m_users.size(); ++i) { if (m_users[i].userId == userId) { // 在表格中查找对应行 for (int row = 0; row < m_usersTable->rowCount(); ++row) { QTableWidgetItem *nameItem = m_usersTable->item(row, 1); if (nameItem && nameItem->text().contains(m_users[i].username)) { return row; } } break; } } return -1; } QString OnlineUsersWidget::getStatusIcon(const QString &status) const { if (status == "在线") { return "🟢"; } else if (status == "离开") { return "🟡"; } else if (status == "忙碌") { return "🔴"; } else { return "⚪"; } }