zhuizhu 6 сар өмнө
parent
commit
aa7c93038e

+ 2 - 4
LearningSmartClient.pro

@@ -53,8 +53,7 @@ SOURCES += \
     widgets/maskoverlay.cpp \
     widgets/meetingselectionwidget.cpp \
     widgets/recorderwidget.cpp \
-    widgets/statswidget.cpp \
-    widgets/userprofilewidget.cpp  \
+widgets/userprofilewidget.cpp \
     widgets/windowpreviewwidget.cpp
 
 HEADERS += \
@@ -99,8 +98,7 @@ HEADERS += \
     widgets/maskoverlay.h \
     widgets/meetingselectionwidget.h \
     widgets/recorderwidget.h \
-    widgets/statswidget.h \
-    widgets/userprofilewidget.h  \
+widgets/userprofilewidget.h \
     widgets/windowpreviewwidget.h
 
 msvc {

+ 5 - 2
MainPanel.cpp

@@ -38,7 +38,6 @@
 #include "widgets/functionbutton.h"
 #include "widgets/maskoverlay.h"
 #include "widgets/recorderwidget.h"
-#include "widgets/statswidget.h"
 #include "widgets/userprofilewidget.h"
 #include <util/jsonmapper.h>
 
@@ -260,12 +259,16 @@ void MainPanel::connectSignals()
 
     // 连接WebSocket相关信号
     // 已移除与 UserProfileWidget 相关的在线状态更新
-    // connect(webSocketClient, &WebSocketClient::statsUpdate, statsWidget, &StatsWidget::updateStats); // 暂时移除统计在主面板的更新
+    // StatsWidget 已移除,统计功能已迁移到 OnlineUsersWidget
     
     // 连接用户列表更新信号到在线用户widget
     connect(webSocketClient, &WebSocketClient::userListUpdate, 
             m_onlineUsersWidget, &OnlineUsersWidget::onUserListUpdate);
     
+    // 连接统计更新信号到在线用户widget
+    connect(webSocketClient, &WebSocketClient::statsUpdate,
+            m_onlineUsersWidget, &OnlineUsersWidget::updateStats);
+    
     connect(webSocketClient, &WebSocketClient::liveStatus, this, [this](const QString &msg) {
         // 这里可以处理 liveStatus 相关逻辑
         QJsonParseError err;

+ 0 - 2
MainPanel.h

@@ -35,7 +35,6 @@ class TMainWindow;    // 新增:用于无边框自定义标题窗口承载弹
 class QComboBox;
 
 class WebSocketClient;
-class StatsWidget;
 class AudioDeviceSelectorIcon;
 class AudioDeviceSelectorIconDecoupled;
 
@@ -218,7 +217,6 @@ private:
     QRect m_savedWindowGeometry;              // 窗口几何缓存
     
     // ========== 其他组件 ==========
-    StatsWidget *statsWidget = nullptr;
     ADS::DockManager *m_dockManager = nullptr;
     
 private:

+ 2 - 34
widgets/meetingselectionwidget.cpp

@@ -1,6 +1,5 @@
 #include "meetingselectionwidget.h"
 #include "userprofilewidget.h"
-#include "statswidget.h"
 #include "../appevent.h"
 #include "network/websocketclient.h"
 #include <QApplication>
@@ -70,21 +69,8 @@ void MeetingSelectionWidget::setupUI()
     m_userProfile->setObjectName("userProfileCard");
     userCardLayout->addWidget(m_userProfile);
 
-    // 创建统计信息卡片容器
-    QFrame *statsCardFrame = new QFrame(this);
-    statsCardFrame->setObjectName("statsCardFrame");
-    QVBoxLayout *statsCardLayout = new QVBoxLayout(statsCardFrame);
-    statsCardLayout->setContentsMargins(30, 25, 30, 25);
-    statsCardLayout->setSpacing(0);
-
-    // 消息统计(临时迁移到此)
-    m_statsWidget = new StatsWidget(this);
-    m_statsWidget->setObjectName("statsWidgetCard");
-    statsCardLayout->addWidget(m_statsWidget);
-
     // 将卡片添加到水平布局
     cardsLayout->addWidget(userCardFrame);
-    cardsLayout->addWidget(statsCardFrame);
 
     // 按钮容器
     m_buttonFrame = new QFrame(this);
@@ -127,9 +113,8 @@ void MeetingSelectionWidget::setupUI()
     
     // 设置容器的固定宽度
     userCardFrame->setFixedWidth(280);
-    statsCardFrame->setFixedWidth(280);
     m_buttonFrame->setFixedWidth(380);
-    cardsContainer->setFixedWidth(580);
+    cardsContainer->setFixedWidth(300);
 }
 
 void MeetingSelectionWidget::setUserRoles(const QStringList &roles)
@@ -165,20 +150,8 @@ void MeetingSelectionWidget::setUserInfo(const QString &username, const QString
 
 void MeetingSelectionWidget::setWebSocketClient(WebSocketClient *client)
 {
-    if (m_wsClient == client) return;
-
-    // 断开旧连接
-    if (m_wsClient && m_statsWidget) {
-        QObject::disconnect(m_wsClient, nullptr, m_statsWidget, nullptr);
-    }
-
     m_wsClient = client;
-
-    // 建立新连接
-    if (m_wsClient && m_statsWidget) {
-        connect(m_wsClient, &WebSocketClient::statsUpdate,
-                m_statsWidget, &StatsWidget::updateStats);
-    }
+    // StatsWidget 已移除,统计功能已迁移到 OnlineUsersWidget
 }
 
 void MeetingSelectionWidget::updateButtonsVisibility()
@@ -230,11 +203,6 @@ void MeetingSelectionWidget::applyStyles()
                   "    border: none;"
                   "}"
 
-                  "#statsWidgetCard {"
-                  "    background-color: transparent;"
-                  "    border: none;"
-                  "}"
-
                   "#buttonFrame {"
                   "    background-color: white;"
                   "    border: none;"

+ 0 - 2
widgets/meetingselectionwidget.h

@@ -10,7 +10,6 @@
 #include <QStringList>
 
 class UserProfileWidget; // 前置声明:复用已有的用户资料组件
-class StatsWidget;       // 前置声明:消息统计组件
 class WebSocketClient;   // 前置声明:消息源
 
 class MeetingSelectionWidget : public QWidget
@@ -56,7 +55,6 @@ private:
     QLabel *m_titleLabel;
     QLabel *m_welcomeLabel;
     UserProfileWidget *m_userProfile; // 使用已有的用户资料组件
-    StatsWidget *m_statsWidget;       // 新增:消息统计组件
     QFrame *m_buttonFrame;
     QVBoxLayout *m_buttonLayout;
     QPushButton *m_joinMeetingBtn;

+ 114 - 9
widgets/onlineuserswidget.cpp

@@ -24,7 +24,13 @@ OnlineUsersWidget::OnlineUsersWidget(QWidget *parent)
     , m_privateMessageAction(nullptr)
     , m_viewProfileAction(nullptr)
     , m_kickUserAction(nullptr)
+    , m_totalCount(0)
 {
+    // 初始化统计数据
+    for (int i = 0; i < 7; ++i) {
+        m_globalStats[i] = 0;
+    }
+    
     setupUI();
     setupTable();
     setupContextMenu();
@@ -93,8 +99,8 @@ void OnlineUsersWidget::setupUI()
 
 void OnlineUsersWidget::setupTable()
 {
-    // 设置表格列 - 原有3列 + 新增6列
-    m_usersTable->setColumnCount(9);
+    // 设置表格列 - 原有3列 + 新增7列 (0-6)
+    m_usersTable->setColumnCount(10);
     QStringList headers;
     headers << "状态" << "用户名" << "最后活动" << "0" << "1" << "2" << "3" << "4" << "5" << "6";
     m_usersTable->setHorizontalHeaderLabels(headers);
@@ -112,7 +118,7 @@ void OnlineUsersWidget::setupTable()
     header->resizeSection(0, 60);  // 状态列
     header->resizeSection(1, 120); // 用户名列
     header->resizeSection(2, 80);  // 最后活动列
-    // 设置新增的1-6列宽度
+    // 设置新增的0-6列宽度
     for (int i = 3; i < 10; ++i) {
         header->resizeSection(i, 40);
     }
@@ -459,12 +465,12 @@ void OnlineUsersWidget::updateTableRow(int row, const OnlineUser &user)
     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);
+    // 添加0-6列的统计数据
+    for (int i = 0; i < 7; ++i) {
+        QTableWidgetItem *statsItem = new QTableWidgetItem(QString::number(user.messageStats[i]));
+        statsItem->setFlags(statsItem->flags() & ~Qt::ItemIsEditable);
+        statsItem->setTextAlignment(Qt::AlignCenter);
+        m_usersTable->setItem(row, i + 3, statsItem);
     }
 }
 
@@ -513,6 +519,12 @@ void OnlineUsersWidget::updateEmptyState()
 
 void OnlineUsersWidget::updateUserListFromRoomUsers(const QList<RoomUserInfo> &roomUsers)
 {
+    // 保存现有用户的统计数据
+    QHash<QString, OnlineUser> existingUsers;
+    for (const auto &user : m_users) {
+        existingUsers[user.userId] = user;
+    }
+    
     clearUsers();
 
     for (const auto &roomUser : roomUsers) {
@@ -523,6 +535,15 @@ void OnlineUsersWidget::updateUserListFromRoomUsers(const QList<RoomUserInfo> &r
         user.lastSeen = QDateTime::currentDateTime();
         user.isAdmin = false; // 可以根据需要设置管理员状态
 
+        // 如果用户之前存在,恢复其统计数据
+        if (existingUsers.contains(user.userId)) {
+            const OnlineUser &existingUser = existingUsers[user.userId];
+            for (int i = 0; i < 7; ++i) {
+                user.messageStats[i] = existingUser.messageStats[i];
+            }
+            user.isAdmin = existingUser.isAdmin; // 保持管理员状态
+        }
+
         addUser(user);
     }
 }
@@ -614,3 +635,87 @@ void OnlineUsersWidget::onUserListUpdate(const QString &roomId, const QJsonArray
     // 更新用户列表显示
     updateUserListFromRoomUsers(roomUsers);
 }
+
+// 统计功能方法 (从 StatsWidget 迁移)
+void OnlineUsersWidget::updateStats(const QJsonObject& statsData)
+{
+    qDebug() << "[OnlineUsersWidget] 收到统计更新:" << statsData;
+    
+    // 解析data数组并更新用户统计数据
+    if (statsData.contains("data") && statsData["data"].isArray()) {
+        QJsonArray dataArray = statsData["data"].toArray();
+        
+        // 重置全局累计数据
+        m_totalCount = 0;
+        for (int i = 0; i < 7; ++i) {
+            m_globalStats[i] = 0;
+        }
+        QDateTime latestUpdate;
+        
+        // 遍历所有用户数据进行更新
+        for (const QJsonValue& value : dataArray) {
+            if (value.isObject()) {
+                QJsonObject userStats = value.toObject();
+                QString userId = userStats["userId"].toString();
+                
+                // 更新单个用户的统计数据
+                updateUserStats(userId, userStats);
+                
+                // 累加到全局统计
+                m_totalCount += userStats["totalCount"].toInt();
+                for (int i = 0; i < 7; ++i) {
+                    QString typeKey = QString("type%1Count").arg(i);
+                    m_globalStats[i] += userStats[typeKey].toInt();
+                }
+                
+                // 找到最新的更新时间
+                QString lastUpdateStr = userStats["lastUpdate"].toString();
+                QDateTime userUpdate = QDateTime::fromString(lastUpdateStr, Qt::ISODate);
+                if (userUpdate.isValid() && (!latestUpdate.isValid() || userUpdate > latestUpdate)) {
+                    latestUpdate = userUpdate;
+                }
+            }
+        }
+        
+        m_lastStatsUpdate = latestUpdate;
+        
+        qDebug() << "[OnlineUsersWidget] 全局统计信息已更新 - 总数:" << m_totalCount 
+                 << "类型0-6:" << m_globalStats[0] << m_globalStats[1] << m_globalStats[2] 
+                 << m_globalStats[3] << m_globalStats[4] << m_globalStats[5] << m_globalStats[6]
+                 << "用户数:" << dataArray.size();
+    }
+}
+
+void OnlineUsersWidget::updateUserStats(const QString &userId, const QJsonObject& userStats)
+{
+    // 查找用户
+    int userIndex = -1;
+    for (int i = 0; i < m_users.size(); ++i) {
+        if (m_users[i].userId == userId) {
+            userIndex = i;
+            break;
+        }
+    }
+    
+    if (userIndex >= 0) {
+        // 更新用户的统计数据
+        for (int i = 0; i < 7; ++i) {
+            QString typeKey = QString("type%1Count").arg(i);
+            m_users[userIndex].messageStats[i] = userStats[typeKey].toInt();
+        }
+        
+        // 更新表格显示
+        int row = findUserRow(userId);
+        if (row >= 0) {
+            updateTableRow(row, m_users[userIndex]);
+        }
+        
+        qDebug() << "[OnlineUsersWidget] 用户统计已更新:" << userId 
+                 << "统计数据:" << m_users[userIndex].messageStats[0] 
+                 << m_users[userIndex].messageStats[1] << m_users[userIndex].messageStats[2]
+                 << m_users[userIndex].messageStats[3] << m_users[userIndex].messageStats[4]
+                 << m_users[userIndex].messageStats[5] << m_users[userIndex].messageStats[6];
+    } else {
+        qDebug() << "[OnlineUsersWidget] 未找到用户:" << userId;
+    }
+}

+ 24 - 2
widgets/onlineuserswidget.h

@@ -25,9 +25,22 @@ struct OnlineUser {
     QString avatar;        // 头像URL或路径
     bool isAdmin;
     
-    OnlineUser() : isAdmin(false) {}
+    // 消息统计数据 (对应0-6类型)
+    int messageStats[7];   // 索引0-6对应消息类型0-6的统计
+    
+    OnlineUser() : isAdmin(false) {
+        // 初始化统计数据
+        for (int i = 0; i < 7; ++i) {
+            messageStats[i] = 0;
+        }
+    }
     OnlineUser(const QString &id, const QString &name, const QString &stat = "在线")
-        : userId(id), username(name), status(stat), isAdmin(false), lastSeen(QDateTime::currentDateTime()) {}
+        : userId(id), username(name), status(stat), isAdmin(false), lastSeen(QDateTime::currentDateTime()) {
+        // 初始化统计数据
+        for (int i = 0; i < 7; ++i) {
+            messageStats[i] = 0;
+        }
+    }
 };
 
 class OnlineUsersWidget : public QWidget
@@ -58,6 +71,10 @@ public:
     // 搜索功能
     void setSearchVisible(bool visible);
     void filterUsers(const QString &keyword);
+    
+    // 统计功能 (从 StatsWidget 迁移)
+    void updateStats(const QJsonObject& statsData);
+    void updateUserStats(const QString &userId, const QJsonObject& userStats);
 
 signals:
     // 用户交互信号
@@ -105,6 +122,11 @@ private:
     QList<OnlineUser> m_users;
     QString m_currentFilter;
     QString m_currentRoomId;
+    
+    // 统计数据 (从 StatsWidget 迁移)
+    int m_totalCount;
+    int m_globalStats[7];  // 全局统计数据 (对应0-6类型)
+    QDateTime m_lastStatsUpdate;
 
     // 当前选中的用户
     QString m_selectedUserId;

+ 0 - 162
widgets/statswidget.cpp

@@ -1,162 +0,0 @@
-#include "statswidget.h"
-#include <QDebug>
-
-StatsWidget::StatsWidget(QWidget *parent)
-    : QWidget(parent)
-    , m_statsGroup(nullptr)
-    , m_totalCountLabel(nullptr)
-    , m_type0CountLabel(nullptr)
-    , m_type1CountLabel(nullptr)
-    , m_type2CountLabel(nullptr)
-    , m_lastUpdateLabel(nullptr)
-    , m_totalCount(0)
-    , m_type0Count(0)
-    , m_type1Count(0)
-    , m_type2Count(0)
-{
-    setupUI();
-    applyStyles();
-}
-
-StatsWidget::~StatsWidget()
-{
-}
-
-void StatsWidget::setupUI()
-{
-    // 创建主布局
-    QVBoxLayout *mainLayout = new QVBoxLayout(this);
-    mainLayout->setContentsMargins(5, 5, 5, 5);
-    mainLayout->setSpacing(5);
-
-    // 创建统计信息组
-    m_statsGroup = new QGroupBox("消息统计", this);
-    QVBoxLayout *statsLayout = new QVBoxLayout(m_statsGroup);
-    statsLayout->setContentsMargins(10, 10, 10, 10);
-    statsLayout->setSpacing(8);
-
-    // 总消息数
-    m_totalCountLabel = new QLabel("总消息数: 0", this);
-    m_totalCountLabel->setObjectName("totalCountLabel");
-    statsLayout->addWidget(m_totalCountLabel);
-
-    // 创建消息类型统计的水平布局
-    QHBoxLayout *typeLayout = new QHBoxLayout();
-    typeLayout->setSpacing(15);
-
-    // 类型0消息数
-    m_type0CountLabel = new QLabel("类型0: 0", this);
-    m_type0CountLabel->setObjectName("type0CountLabel");
-    typeLayout->addWidget(m_type0CountLabel);
-
-    // 类型1消息数
-    m_type1CountLabel = new QLabel("类型1: 0", this);
-    m_type1CountLabel->setObjectName("type1CountLabel");
-    typeLayout->addWidget(m_type1CountLabel);
-
-    // 类型2消息数
-    m_type2CountLabel = new QLabel("类型2: 0", this);
-    m_type2CountLabel->setObjectName("type2CountLabel");
-    typeLayout->addWidget(m_type2CountLabel);
-
-    statsLayout->addLayout(typeLayout);
-
-    // 最后更新时间
-    m_lastUpdateLabel = new QLabel("最后更新: --", this);
-    m_lastUpdateLabel->setObjectName("lastUpdateLabel");
-    statsLayout->addWidget(m_lastUpdateLabel);
-
-    // 添加到主布局
-    mainLayout->addWidget(m_statsGroup);
-    mainLayout->addStretch();
-
-    setLayout(mainLayout);
-    setMaximumHeight(150);
-}
-
-void StatsWidget::applyStyles()
-{
-    setStyleSheet(
-        "QGroupBox {"
-        "    font-weight: bold;"
-        "    border: 2px solid #cccccc;"
-        "    border-radius: 5px;"
-        "    margin-top: 1ex;"
-        "    padding-top: 5px;"
-        "}"
-        "QGroupBox::title {"
-        "    subcontrol-origin: margin;"
-        "    left: 10px;"
-        "    padding: 0 5px 0 5px;"
-        "}"
-        "#totalCountLabel {"
-        "    font-weight: bold;"
-        "    color: #2c3e50;"
-        "    font-size: 14px;"
-        "}"
-        "#type0CountLabel, #type1CountLabel, #type2CountLabel {"
-        "    color: #34495e;"
-        "    font-size: 12px;"
-        "}"
-        "#lastUpdateLabel {"
-        "    color: #7f8c8d;"
-        "    font-size: 11px;"
-        "}"
-    );
-}
-
-void StatsWidget::updateStats(const QJsonObject& statsData)
-{
-    qDebug() << "[StatsWidget] 收到统计更新:" << statsData;
-    
-    // 解析data数组并累加所有用户的统计数据
-    if (statsData.contains("data") && statsData["data"].isArray()) {
-        QJsonArray dataArray = statsData["data"].toArray();
-        
-        // 重置累计数据
-        m_totalCount = 0;
-        m_type0Count = 0;
-        m_type1Count = 0;
-        m_type2Count = 0;
-        QDateTime latestUpdate;
-        
-        // 遍历所有用户数据进行累加
-        for (const QJsonValue& value : dataArray) {
-            if (value.isObject()) {
-                QJsonObject userStats = value.toObject();
-                
-                // 累加各类型消息数
-                m_totalCount += userStats["totalCount"].toInt();
-                m_type0Count += userStats["type0Count"].toInt();
-                m_type1Count += userStats["type1Count"].toInt();
-                m_type2Count += userStats["type2Count"].toInt();
-                
-                // 找到最新的更新时间
-                QString lastUpdateStr = userStats["lastUpdate"].toString();
-                QDateTime userUpdate = QDateTime::fromString(lastUpdateStr, Qt::ISODate);
-                if (userUpdate.isValid() && (!latestUpdate.isValid() || userUpdate > latestUpdate)) {
-                    latestUpdate = userUpdate;
-                }
-            }
-        }
-        
-        m_lastUpdate = latestUpdate;
-        
-        // 更新UI显示
-        m_totalCountLabel->setText(QString("总消息数: %1").arg(m_totalCount));
-        m_type0CountLabel->setText(QString("类型0: %1").arg(m_type0Count));
-        m_type1CountLabel->setText(QString("类型1: %1").arg(m_type1Count));
-        m_type2CountLabel->setText(QString("类型2: %1").arg(m_type2Count));
-        
-        if (m_lastUpdate.isValid()) {
-            m_lastUpdateLabel->setText(QString("最后更新: %1")
-                .arg(m_lastUpdate.toString("yyyy-MM-dd hh:mm:ss")));
-        } else {
-            m_lastUpdateLabel->setText("最后更新: --");
-        }
-        
-        qDebug() << "[StatsWidget] 全局统计信息已更新 - 总数:" << m_totalCount 
-                 << "类型0:" << m_type0Count << "类型1:" << m_type1Count 
-                 << "类型2:" << m_type2Count << "用户数:" << dataArray.size();
-    }
-}

+ 0 - 44
widgets/statswidget.h

@@ -1,44 +0,0 @@
-#ifndef STATSWIDGET_H
-#define STATSWIDGET_H
-
-#include <QWidget>
-#include <QLabel>
-#include <QVBoxLayout>
-#include <QHBoxLayout>
-#include <QGroupBox>
-#include <QJsonObject>
-#include <QJsonArray>
-#include <QDateTime>
-
-class StatsWidget : public QWidget
-{
-    Q_OBJECT
-
-public:
-    explicit StatsWidget(QWidget *parent = nullptr);
-    ~StatsWidget();
-
-    // 更新统计信息
-    void updateStats(const QJsonObject& statsData);
-
-private:
-    void setupUI();
-    void applyStyles();
-    
-    // UI组件
-    QGroupBox *m_statsGroup;
-    QLabel *m_totalCountLabel;
-    QLabel *m_type0CountLabel;
-    QLabel *m_type1CountLabel;
-    QLabel *m_type2CountLabel;
-    QLabel *m_lastUpdateLabel;
-    
-    // 数据
-    int m_totalCount;
-    int m_type0Count;
-    int m_type1Count;
-    int m_type2Count;
-    QDateTime m_lastUpdate;
-};
-
-#endif // STATSWIDGET_H