Prechádzať zdrojové kódy

添加: 角色切换不同界面

zhuizhu 9 mesiacov pred
rodič
commit
1fc7731e1c

+ 2 - 4
AvPlayer2/AvPlayer2.pri

@@ -1,6 +1,7 @@
 
 
 HEADERS += \
+    $$PWD/PlayWidget.h \
     $$PWD/app_settings.h \
     $$PWD/audio_decode_thread.h \
     $$PWD/audio_effect_gl.h \
@@ -27,6 +28,7 @@ HEADERS += \
     $$PWD/video_state.h
 
 SOURCES += \
+    $$PWD/PlayWidget.cpp \
     $$PWD/app_settings.cpp \
     $$PWD/audio_decode_thread.cpp \
     $$PWD/audio_effect_gl.cpp \
@@ -58,8 +60,4 @@ FORMS += \
     $$PWD/network_url_dlg.ui \
     $$PWD/playlist_window.ui
 
-DISTFILES += \
-    $$PWD/VideoPlayer_en_001.qm
 
-TRANSLATIONS += \
-    $$PWD/VideoPlayer_en_001.ts

+ 139 - 0
AvPlayer2/PlayWidget.cpp

@@ -0,0 +1,139 @@
+#include "PlayWidget.h"
+#include <QDebug>
+#include <QTimer>
+
+#include "playercontroller.h"
+
+#include "AvRecorder/ui/opengl_video_widget.h"
+#include "audio_effect_gl.h"
+
+PlayWidget::PlayWidget(QWidget* parent)
+    : QWidget(parent)
+{
+    setupUi();
+    setupConnections();
+
+    setPlayerController(new PlayerController);
+}
+
+void PlayWidget::setupUi()
+{
+    m_videoWidget = std::make_unique<OpenGLVideoWidget>(this);
+    m_sliderProgress = new QSlider(Qt::Horizontal, this);
+    m_labelTime = new QLabel("00:00/00:00", this);
+    m_btnPlayPause = new QPushButton("播放", this);
+    m_comboSpeed = new QComboBox(this);
+    m_comboSpeed->addItems({"0.5x", "1.0x", "1.5x", "2.0x"});
+    m_sliderVolume = new QSlider(Qt::Horizontal, this);
+    m_sliderVolume->setRange(0, 100);
+    m_labelVolume = new QLabel("音量", this);
+    QHBoxLayout* controlLayout = new QHBoxLayout;
+    controlLayout->addWidget(m_btnPlayPause);
+    controlLayout->addWidget(new QLabel("倍速:"));
+    controlLayout->addWidget(m_comboSpeed);
+    controlLayout->addWidget(m_labelVolume);
+    controlLayout->addWidget(m_sliderVolume);
+    m_audioEffect = std::make_unique<AudioEffectGL>(this);
+    QVBoxLayout* mainLayout = new QVBoxLayout(this);
+    mainLayout->addWidget(m_videoWidget.get(), 5);
+    QHBoxLayout* progressLayout = new QHBoxLayout;
+    progressLayout->addWidget(m_sliderProgress, 8);
+    progressLayout->addWidget(m_labelTime, 2);
+    mainLayout->addLayout(progressLayout);
+    mainLayout->addLayout(controlLayout);
+    mainLayout->addWidget(m_audioEffect.get(), 2);
+    setLayout(mainLayout);
+}
+
+void PlayWidget::setupConnections()
+{
+    connect(m_btnPlayPause, &QPushButton::clicked, this, &PlayWidget::onPlayPauseClicked);
+    // connect(m_sliderProgress, &QSlider::sliderReleased, this, [this]() {
+    //     if (!m_playerController) return;
+    //     int value = m_sliderProgress->value();
+    //     int max = m_sliderProgress->maximum();
+    //     if (max > 0) {
+    //         double seek_time = value * m_totalTime / max;
+    //         m_playerController->videoSeek(seek_time);
+    //     }
+    // });
+    connect(m_comboSpeed, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &PlayWidget::onSpeedChanged);
+    connect(m_sliderVolume, &QSlider::valueChanged, this, &PlayWidget::onVolumeChanged);
+}
+
+void PlayWidget::setPlayerController(PlayerController* controller)
+{
+    m_playerController = controller;
+    if (!m_playerController) return;
+    // 视频帧信号
+    connect(m_playerController, &PlayerController::frameReady, this, [this](AVFrame* frame) {
+        if (m_videoWidget) m_videoWidget->Render(frame);
+    });
+    // 音频可视化信号
+    connect(m_playerController, &PlayerController::audioData, this, [this](const AudioData& data) {
+        if (m_audioEffect) m_audioEffect->paint_data(data);
+    });
+    // 进度/时间信号
+    // connect(m_playerController, &PlayerController::updatePlayTime, this, [this]() {
+    //     if (!m_playerController) return;
+    //     auto state = m_playerController->state();
+    //     if (!state) return;
+    //     double cur = state->audio_clock;
+    //     double total = 0;
+    //     if (state->ic) total = state->ic->duration / 1000000.0;
+    //     m_totalTime = total;
+    //     int max = 1000;
+    //     m_sliderProgress->setMaximum(max);
+    //     m_sliderProgress->setValue(total > 0 ? int(cur * max / total) : 0);
+    //     QTime curT(0,0); curT = curT.addSecs(int(cur));
+    //     QTime totT(0,0); totT = totT.addSecs(int(total));
+    //     m_labelTime->setText(curT.toString("mm:ss") + "/" + totT.toString("mm:ss"));
+    // });
+    // 音量信号
+    connect(m_playerController, &PlayerController::updatePlayControlVolume, this, [this]() {
+        if (!m_playerController) return;
+        float vol = m_playerController->deviceVolume();
+        m_sliderVolume->setValue(int(vol * 100));
+    });
+    // 播放/暂停状态信号
+    connect(m_playerController, &PlayerController::updatePlayControlStatus, this, [this]() {
+        if (!m_playerController) return;
+        auto state = m_playerController->state();
+        if (state && state->paused)
+            m_btnPlayPause->setText("播放");
+        else
+            m_btnPlayPause->setText("暂停");
+    });
+
+    controller->startToPlay("C:/Users/zhuizhu/Videos/1.mp4");
+}
+
+void PlayWidget::onPlayPauseClicked()
+{
+    if (m_playerController) m_playerController->pausePlay();
+}
+
+void PlayWidget::onProgressChanged(int value)
+{
+    // 进度条拖动时可选预览实现
+}
+
+void PlayWidget::onSpeedChanged(int index)
+{
+    if (!m_playerController) return;
+    double speed = 1.0;
+    switch(index) {
+        case 0: speed = 0.5; break;
+        case 1: speed = 1.0; break;
+        case 2: speed = 1.5; break;
+        case 3: speed = 2.0; break;
+        default: speed = 1.0; break;
+    }
+    m_playerController->setPlaySpeed(speed);
+}
+
+void PlayWidget::onVolumeChanged(int value)
+{
+    if (!m_playerController) return;
+    m_playerController->setDeviceVolume(value / 100.0f);
+}

+ 40 - 0
AvPlayer2/PlayWidget.h

@@ -0,0 +1,40 @@
+#pragma once
+#include <QComboBox>
+#include <QHBoxLayout>
+#include <QLabel>
+#include <QPushButton>
+#include <QSlider>
+#include <QVBoxLayout>
+#include <QWidget>
+
+class PlayerController;
+class AudioEffectGL;
+class OpenGLVideoWidget;
+
+class PlayWidget : public QWidget
+{
+    Q_OBJECT
+public:
+    explicit PlayWidget(QWidget* parent = nullptr);
+
+private:
+    std::unique_ptr<OpenGLVideoWidget> m_videoWidget;
+    QSlider* m_sliderProgress;
+    QLabel* m_labelTime;
+    QPushButton* m_btnPlayPause;
+    QComboBox* m_comboSpeed;
+    QSlider* m_sliderVolume;
+    QLabel* m_labelVolume;
+    std::unique_ptr<AudioEffectGL> m_audioEffect;
+    PlayerController* m_playerController = nullptr;
+
+    void setupUi();
+    void setupConnections();
+    void setPlayerController(PlayerController* controller);
+
+private slots:
+    void onPlayPauseClicked();
+    void onProgressChanged(int value);
+    void onSpeedChanged(int index);
+    void onVolumeChanged(int value);
+};

+ 5 - 4
AvRecorder/ui/av_recorder.cpp

@@ -27,14 +27,15 @@ AvRecorder::AvRecorder(QWidget* parent)
     hLayout->addLayout(initListUi(), 2);
     hLayout->addLayout(initOtherUi(), 1);
 
-    layout->addWidget(m_glWidget, 4);
-    layout->addLayout(hLayout, 1);
-    setLayout(layout);
-
     initStatusBarUi();
     updateCaptureList();
 
     initConnect();
+
+    layout->addWidget(m_glWidget, 4);
+    layout->addLayout(hLayout, 1);
+    layout->addWidget(m_statusBar, 0);
+    setLayout(layout);
 }
 
 void AvRecorder::initConnect()

+ 3 - 8
LearningSmartClient.pro

@@ -5,7 +5,7 @@ CONFIG += console
 CONFIG += c++17
 LIBS += -lshell32
 QT += opengl
-
+ QT += concurrent
 # You can make your code fail to compile if it uses deprecated APIs.
 # In order to do so, uncomment the following line.
 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0
@@ -18,9 +18,7 @@ SOURCES += \
     appevent.cpp \
     main.cpp \
     mainwindow.cpp \
-    models/permission.cpp \
-    models/role.cpp \
-    models/user.cpp \
+    models/chatmodels.cpp \
     network/networkaccessmanager.cpp \
     network/request.cpp \
     network/websocketclient.cpp \
@@ -48,9 +46,7 @@ HEADERS += \
     api/userapi.h \
     appevent.h \
     mainwindow.h \
-    models/permission.h \
-    models/role.h \
-    models/user.h \
+    models/chatmodels.h \
     network/networkaccessmanager.h \
     network/request.h \
     network/websocketclient.h \
@@ -81,7 +77,6 @@ msvc {
 
 DEFINES += _SILENCE_CLANG_COROUTINE_MESSAGE
 include($$PWD/AvRecorder/AvRecorder.pri)
-include($$PWD/AvPlayer/AvPlayer.pri)
 include($$PWD/AvPlayer2/AvPlayer2.pri)
 
 include($$PWD/qwindowkit/qwindowkit.pri)

+ 3 - 3
api/chatapi.cpp

@@ -19,7 +19,7 @@ QFuture<HttpResponse> createRoom(const QString& roomName, const QString& descrip
     jsonData["maxUsers"] = maxUsers;
     QJsonDocument doc(jsonData);
 
-    return TC::RequestClient::requestClient()->postAsync("/api/rooms", doc);
+    return TC::RequestClient::globalInstance()->postAsync("/api/rooms", doc);
 }
 
 QFuture<HttpResponse> getRoomList(int page, int pageSize)
@@ -28,7 +28,7 @@ QFuture<HttpResponse> getRoomList(int page, int pageSize)
     params["page"] = page;
     params["pageSize"] = pageSize;
 
-    return TC::RequestClient::requestClient()->getAsync("/api/rooms", params);
+    return TC::RequestClient::globalInstance()->getAsync("/api/rooms", params);
 }
 
-} // namespace ChatApi
+} // namespace ChatApi

+ 4 - 4
api/loginapi.cpp

@@ -14,7 +14,7 @@ QFuture<HttpResponse> loginApi(const LoginParams& data)
 
     QJsonDocument doc(jsonData);
 
-    return TC::RequestClient::requestClient()->postAsync("/user/login", doc);
+    return TC::RequestClient::globalInstance()->postAsync("/user/login", doc);
 }
 
 QFuture<HttpResponse> refreshTokenApi()
@@ -23,7 +23,7 @@ QFuture<HttpResponse> refreshTokenApi()
     config["withCredentials"] = true;
     QJsonDocument doc(config);
 
-    return TC::RequestClient::baseRequestClient()->postAsync("/auth/refresh", doc);
+    return TC::RequestClient::globalInstance()->postAsync("/auth/refresh", doc);
 }
 
 QFuture<HttpResponse> logoutApi()
@@ -32,12 +32,12 @@ QFuture<HttpResponse> logoutApi()
     config["withCredentials"] = true;
     QJsonDocument doc(config);
 
-    return TC::RequestClient::baseRequestClient()->postAsync("/user/logout", doc);
+    return TC::RequestClient::globalInstance()->postAsync("/user/logout", doc);
 }
 
 QFuture<HttpResponse> getAccessCodesApi()
 {
-    return TC::RequestClient::requestClient()->getAsync("/user/perm");
+    return TC::RequestClient::globalInstance()->getAsync("/user/perm");
 }
 
 } // namespace AuthApi

+ 1 - 1
api/userapi.cpp

@@ -2,5 +2,5 @@
 
 QFuture<HttpResponse> getUserInfoApi()
 {
-    return TC::RequestClient::requestClient()->getAsync("/user/info");
+    return TC::RequestClient::globalInstance()->getAsync("/user/info");
 }

+ 2 - 2
api/userapi.h

@@ -12,14 +12,14 @@ class UserInfo
     Q_GADGET
     Q_PROPERTY(QString id MEMBER id)
     Q_PROPERTY(QString username MEMBER username)
-    Q_PROPERTY(QStringList role MEMBER roles)
+    Q_PROPERTY(QStringList roleName MEMBER roleName)
 
 public:
     UserInfo() = default;
 
     QString id;
     QString username;
-    QStringList roles;
+    QStringList roleName;
 };
 Q_DECLARE_METATYPE(UserInfo)
 

+ 17 - 0
appevent.cpp

@@ -54,6 +54,8 @@ public:
     QString locale;
 
     bool enableRefreshToken;
+
+    QStringList roles;
 };
 
 AppEvent::AppEvent(QObject *parent)
@@ -232,6 +234,21 @@ void AppEvent::setEnableRefreshToken(bool enable)
     }
 }
 
+void AppEvent::setRoles(const QStringList &roles)
+{
+    d->roles = roles;
+}
+
+QStringList AppEvent::roles() const
+{
+    return d->roles;
+}
+
+bool AppEvent::hasRole(const QString &role)
+{
+    return d->roles.contains(role);
+}
+
 bool AppEvent::setConfigValue(const QString &key, const QVariant &value)
 {
     if (d->jsonConfig.contains(key)) {

+ 3 - 0
appevent.h

@@ -43,6 +43,9 @@ public:
     bool isEnableRefreshToken() const;
     void setEnableRefreshToken(bool enable);
 
+    void setRoles(const QStringList &roles);
+    QStringList roles() const;
+    bool hasRole(const QString &role);
     // 配置
     bool setConfigValue(const QString &key, const QVariant &value);
     QVariant configValue(const QString &key);

+ 4 - 4
main.cpp

@@ -72,8 +72,8 @@ docker run -itd  --name zlmediakit --restart=always
 -v /data/zlmediakit/media/conf:/opt/media/conf
 zlmediakit/zlmediakit:master
 */
-    // MainWindow w;
-    // w.show();
+    MainWindow w;
+    w.show();
 
     // ThemeSettingsWidget ThemeSettingsWidget;
     // ThemeSettingsWidget.show();
@@ -82,8 +82,8 @@ zlmediakit/zlmediakit:master
     // w.resize(960, 540);
     // w.show();
 
-    MainWindowA aa;
-    aa.show();
+    // MainWindowA aa;
+    // aa.show();
 
     // // 这里填你的流地址
     // // w.startPlay("http://vd3.bdstatic.com/mda-jennyc5ci1ugrxzi/mda-jennyc5ci1ugrxzi.mp4");

+ 115 - 36
mainwindow.cpp

@@ -35,11 +35,13 @@
 #include <qtpromise/qpromisefuture.h>
 #include <qtpromise/qpromisehelpers.h>
 
+#include "AvPlayer2/PlayWidget.h"
+
 class MainWidget : public QWidget
 {
 public:
-    explicit MainWidget(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags())
-        : QWidget(parent, f)
+    explicit MainWidget(QWidget *parent = nullptr)
+        : QWidget(parent)
         , userProfile(nullptr)
         , chatView(nullptr)
     {
@@ -56,51 +58,73 @@ public:
     }
     void setupUI()
     {
-        // 创建并显示 AvRecorder
-        AvRecorder *avRecorder = new AvRecorder(this);
-
-        //确保 AvRecorder 不会阻止鼠标事件传递
-        avRecorder->setAttribute(Qt::WA_TransparentForMouseEvents, false);
-
-        // 创建用户信息显示
+        // 只创建一次布局和静态控件
         userProfile = new UserProfileWidget(this);
         chatView = new ChatWindow();
         chatView->setMinimumWidth(400);
 
-        QWidget *widget = new QWidget;
-
-        QVBoxLayout *vbox = new QVBoxLayout(widget);
+        QWidget *rightWidget = new QWidget;
+        QVBoxLayout *vbox = new QVBoxLayout(rightWidget);
         vbox->setContentsMargins(0, 0, 0, 0);
         vbox->addWidget(userProfile, 0);
         vbox->addWidget(chatView, 1);
-        // chatView->setStyleSheet(" background-color: red");
 
-        // 创建水平分割器
-        QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
-        splitter->addWidget(avRecorder);
-        splitter->addWidget(widget);
+        splitter = new QSplitter(Qt::Horizontal, this);
+        // 先插入一个占位控件
+        playerContainer = new QWidget(this);
+        splitter->addWidget(playerContainer);
+        splitter->addWidget(rightWidget);
 
-        // 设置初始大小比例为4:1
         splitter->setStretchFactor(0, 70);
         splitter->setStretchFactor(1, 30);
 
-        // QHBoxLayout *hLayout = new QHBoxLayout();
-        // hLayout->addWidget(avRecorder, 4); // 权重为4
-        // hLayout->addWidget(chatView, 1);   // 权重为1
-        // hLayout->setContentsMargins(0, 0, 0, 0);
-        // hLayout->setSpacing(0);
-
-        QWidget *statusBar = avRecorder->statusBar();
-        //statusBar->setMaximumHeight(40); // 设置最大高度为20像素
-
-        // 创建垂直布局,用于放置水平布局和状态栏
         QVBoxLayout *mainLayout = new QVBoxLayout(this);
         mainLayout->addWidget(splitter, 1);
-        mainLayout->addWidget(statusBar, 0);
         mainLayout->setContentsMargins(0, 0, 0, 0);
         mainLayout->setSpacing(0);
 
         setLayout(mainLayout);
+
+        // QWidget *playerWidget = nullptr;
+        // if (currentRole == "role.admin") {
+        //     playerWidget = new AvRecorder(this);
+        // } else {
+        //     playerWidget = new PlayWidget(this);
+        // }
+
+        // // 其余代码不变
+        // userProfile = new UserProfileWidget(this);
+        // chatView = new ChatWindow();
+        // chatView->setMinimumWidth(400);
+
+        // QWidget *widget = new QWidget;
+        // QVBoxLayout *vbox = new QVBoxLayout(widget);
+        // vbox->setContentsMargins(0, 0, 0, 0);
+        // vbox->addWidget(userProfile, 0);
+        // vbox->addWidget(chatView, 1);
+
+        // QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
+        // splitter->addWidget(playerWidget);
+        // splitter->addWidget(widget);
+
+        // splitter->setStretchFactor(0, 70);
+        // splitter->setStretchFactor(1, 30);
+
+        // QWidget *statusBar = nullptr;
+        // if (auto av = qobject_cast<AvRecorder *>(playerWidget)) {
+        //     statusBar = av->statusBar();
+        // } else {
+        //     statusBar = new QWidget(this); // 或者 PlayWidget 也实现 statusBar
+        //     statusBar->setFixedHeight(1);
+        // }
+
+        // QVBoxLayout *mainLayout = new QVBoxLayout(this);
+        // mainLayout->addWidget(splitter, 1);
+        // mainLayout->addWidget(statusBar, 0);
+        // mainLayout->setContentsMargins(0, 0, 0, 0);
+        // mainLayout->setSpacing(0);
+
+        // setLayout(mainLayout);
     }
     void initConnect()
     {
@@ -114,9 +138,51 @@ public:
                 });
     }
 
-    UserProfileWidget *userProfile;
+    // 动态插入或替换播放器控件
+    void setPlayerWidget(QWidget *newPlayer)
+    {
+        if (playerWidget) {
+            playerWidget->setParent(nullptr);
+            playerWidget->deleteLater();
+        }
+        playerWidget = newPlayer;
+        playerWidget->setParent(playerContainer);
+
+        // 清空 playerContainer 的布局
+        QLayout *oldLayout = playerContainer->layout();
+        if (oldLayout) {
+            QLayoutItem *item;
+            while ((item = oldLayout->takeAt(0)) != nullptr) {
+                if (item->widget())
+                    item->widget()->setParent(nullptr);
+                delete item;
+            }
+            delete oldLayout;
+        }
+        QVBoxLayout *vbox = new QVBoxLayout(playerContainer);
+        vbox->setContentsMargins(0, 0, 0, 0);
+        vbox->addWidget(playerWidget);
+    }
+
+    // 角色切换时调用
+    void setRole(const QStringList &roleList)
+    {
+        QWidget *newPlayer = nullptr;
+        if (roleList.contains("role.admin")) {
+            newPlayer = new AvRecorder(this);
+        } else {
+            newPlayer = new PlayWidget(this);
+        }
+        setPlayerWidget(newPlayer);
+    }
+
+    QString currentRole;
 
-    ChatWindow *chatView;
+    QSplitter *splitter = nullptr;
+    QWidget *playerContainer = nullptr;
+    QWidget *playerWidget = nullptr;
+    UserProfileWidget *userProfile = nullptr;
+    ChatWindow *chatView = nullptr;
 };
 
 MainWindow::MainWindow(QWidget *parent)
@@ -136,15 +202,26 @@ MainWindow::MainWindow(QWidget *parent)
     loginWidget = new LoginWidget(this);
     stackedWidget->addWidget(loginWidget);
 
-    // 主窗口
-    mainWidget = new MainWidget(this);
-    stackedWidget->addWidget(mainWidget);
+    mainWidget = nullptr;
 
     connect(loginWidget, &LoginWidget::loginRequested, this, &MainWindow::onLoginSuccess);
     resize(1280, 600);
 
     // 显示登录页面
     stackedWidget->setCurrentWidget(loginWidget);
+}
+
+MainWindow::~MainWindow() {}
+
+void MainWindow::createMainWindow()
+{
+    if (mainWidget) {
+        delete mainWidget;
+        mainWidget = nullptr;
+    }
+    // 主窗口
+    mainWidget = new MainWidget(this);
+    stackedWidget->addWidget(mainWidget);
 
     // 退出处理
     connect(mainWidget->userProfile, &UserProfileWidget::logoutClicked, this, [this]() {
@@ -158,8 +235,6 @@ MainWindow::MainWindow(QWidget *parent)
     });
 }
 
-MainWindow::~MainWindow() {}
-
 void MainWindow::onLoginSuccess(const QString &username, const QString &password)
 {
     // 准备登录参数
@@ -252,10 +327,14 @@ void MainWindow::authLogin()
                 qDebug() << "所有请求成功完成";
                 // 这里可以添加后续处理逻辑
             }
+            qDebug() << "当前角色:" << user.roleName;
+            AppEvent::instance()->setRoles(user.roleName);
 
+            createMainWindow();
             // 创建主界面部件
             mainWidget->userProfile->setUsername(user.username);
             mainWidget->chatView->initWebsocket();
+            mainWidget->setRole(user.roleName);
 
             stackedWidget->addWidget(mainWidget);
             stackedWidget->setCurrentWidget(mainWidget);

+ 2 - 0
mainwindow.h

@@ -15,6 +15,8 @@ public:
     MainWindow(QWidget *parent = nullptr);
     ~MainWindow();
 
+    void createMainWindow();
+
 private:
     void onLoginSuccess(const QString &username, const QString &password);
 

+ 0 - 61
models/permission.cpp

@@ -1,61 +0,0 @@
-#include "permission.h"
-
-PermissionManager& PermissionManager::getInstance() {
-    static PermissionManager instance;
-    return instance;
-}
-
-void PermissionManager::addRole(const Role& role) {
-    m_roles[role.getName()] = role;
-    const QVector<QString>& permissions = role.getPermissions();
-    for (const QString& permission : permissions) {
-        m_allPermissions.insert(permission);
-    }
-}
-
-void PermissionManager::removeRole(const QString& roleName) {
-    if (m_roles.contains(roleName)) {
-        const Role& role = m_roles[roleName];
-        const QVector<QString>& permissions = role.getPermissions();
-        
-        // 检查是否有其他角色使用相同的权限
-        for (const QString& permission : permissions) {
-            bool permissionUsedByOthers = false;
-            for (const Role& otherRole : m_roles) {
-                if (otherRole.getName() != roleName && otherRole.hasPermission(permission)) {
-                    permissionUsedByOthers = true;
-                    break;
-                }
-            }
-            if (!permissionUsedByOthers) {
-                m_allPermissions.remove(permission);
-            }
-        }
-        
-        m_roles.remove(roleName);
-    }
-}
-
-Role* PermissionManager::getRole(const QString& roleName) {
-    if (m_roles.contains(roleName)) {
-        return &m_roles[roleName];
-    }
-    return nullptr;
-}
-
-bool PermissionManager::checkPermission(const User& user, const QString& permission) const {
-    const QVector<QString>& userRoles = user.getRoles();
-    for (const QString& roleName : userRoles) {
-        if (m_roles.contains(roleName)) {
-            const Role& role = m_roles[roleName];
-            if (role.hasPermission(permission)) {
-                return true;
-            }
-        }
-    }
-    return false;
-}
-
-QSet<QString> PermissionManager::getAllPermissions() const {
-    return m_allPermissions;
-}

+ 0 - 29
models/permission.h

@@ -1,29 +0,0 @@
-#ifndef PERMISSION_H
-#define PERMISSION_H
-
-#include <QString>
-#include <QMap>
-#include <QSet>
-#include "user.h"
-#include "role.h"
-
-class PermissionManager {
-public:
-    static PermissionManager& getInstance();
-
-    void addRole(const Role& role);
-    void removeRole(const QString& roleName);
-    Role* getRole(const QString& roleName);
-    bool checkPermission(const User& user, const QString& permission) const;
-    QSet<QString> getAllPermissions() const;
-
-private:
-    PermissionManager() = default;
-    PermissionManager(const PermissionManager&) = delete;
-    PermissionManager& operator=(const PermissionManager&) = delete;
-
-    QMap<QString, Role> m_roles;
-    QSet<QString> m_allPermissions;
-};
-
-#endif // PERMISSION_H

+ 0 - 36
models/role.cpp

@@ -1,36 +0,0 @@
-#include "role.h"
-
-Role::Role() {}
-
-Role::Role(const QString& name)
-    : m_name(name) {}
-
-QString Role::getName() const {
-    return m_name;
-}
-
-void Role::setName(const QString& name) {
-    m_name = name;
-}
-
-QVector<QString> Role::getPermissions() const {
-    return m_permissions;
-}
-
-void Role::setPermissions(const QVector<QString>& permissions) {
-    m_permissions = permissions;
-}
-
-void Role::addPermission(const QString& permission) {
-    if (!hasPermission(permission)) {
-        m_permissions.append(permission);
-    }
-}
-
-void Role::removePermission(const QString& permission) {
-    m_permissions.removeAll(permission);
-}
-
-bool Role::hasPermission(const QString& permission) const {
-    return m_permissions.contains(permission);
-}

+ 0 - 25
models/role.h

@@ -1,25 +0,0 @@
-#ifndef ROLE_H
-#define ROLE_H
-
-#include <QString>
-#include <QVector>
-
-class Role {
-public:
-    Role();
-    Role(const QString& name);
-
-    QString getName() const;
-    void setName(const QString& name);
-    QVector<QString> getPermissions() const;
-    void setPermissions(const QVector<QString>& permissions);
-    void addPermission(const QString& permission);
-    void removePermission(const QString& permission);
-    bool hasPermission(const QString& permission) const;
-
-private:
-    QString m_name;
-    QVector<QString> m_permissions;
-};
-
-#endif // ROLE_H

+ 0 - 44
models/user.cpp

@@ -1,44 +0,0 @@
-#include "user.h"
-
-User::User() {}
-
-User::User(const QString& username, const QString& password)
-    : m_username(username), m_password(password) {}
-
-QString User::getUsername() const {
-    return m_username;
-}
-
-void User::setUsername(const QString& username) {
-    m_username = username;
-}
-
-QString User::getPassword() const {
-    return m_password;
-}
-
-void User::setPassword(const QString& password) {
-    m_password = password;
-}
-
-QVector<QString> User::getRoles() const {
-    return m_roles;
-}
-
-void User::setRoles(const QVector<QString>& roles) {
-    m_roles = roles;
-}
-
-void User::addRole(const QString& role) {
-    if (!hasRole(role)) {
-        m_roles.append(role);
-    }
-}
-
-void User::removeRole(const QString& role) {
-    m_roles.removeAll(role);
-}
-
-bool User::hasRole(const QString& role) const {
-    return m_roles.contains(role);
-}

+ 0 - 28
models/user.h

@@ -1,28 +0,0 @@
-#ifndef USER_H
-#define USER_H
-
-#include <QString>
-#include <QVector>
-
-class User {
-public:
-    User();
-    User(const QString& username, const QString& password);
-
-    QString getUsername() const;
-    void setUsername(const QString& username);
-    QString getPassword() const;
-    void setPassword(const QString& password);
-    QVector<QString> getRoles() const;
-    void setRoles(const QVector<QString>& roles);
-    void addRole(const QString& role);
-    void removeRole(const QString& role);
-    bool hasRole(const QString& role) const;
-
-private:
-    QString m_username;
-    QString m_password;
-    QVector<QString> m_roles;
-};
-
-#endif // USER_H

+ 192 - 405
network/networkaccessmanager.cpp

@@ -1,5 +1,4 @@
 #include "networkaccessmanager.h"
-
 #include "appevent.h"
 
 #include <QBuffer>
@@ -9,12 +8,11 @@
 #include <QJsonDocument>
 #include <QJsonObject>
 #include <QUrlQuery>
+#include <QtConcurrent>
 
 // 基础URL配置
 static QString base_url("http://127.0.0.1:8200");
-
 static const QString messageVal = "msg";
-// static QString base_url("http://127.0.0.1:8888/api");
 
 static NetworkAccessManager* namInstance = nullptr;
 
@@ -121,453 +119,328 @@ QNetworkReply* NetworkAccessManager::createRequest(Operation op,
 }
 
 namespace TC {
-// 认证请求拦截器
-class AuthRequestInterceptor : public Interceptor
-{
-public:
-    void interceptRequest(QNetworkRequest& request) override;
-};
-
-// 认证响应拦截器
-class AuthResponseInterceptor : public Interceptor
-{
-public:
-    void interceptResponse(QNetworkReply* reply) override;
-
-private:
-    void doRefreshToken();
-    void doReAuthenticate();
-};
-// 错误响应拦截器
-class ErrorResponseInterceptor : public Interceptor
-{
-public:
-    void interceptResponse(QNetworkReply* reply) override;
-};
-
-// 请求客户端实现
 RequestClient::RequestClient(const RequestClientOptions& options)
     : m_baseUrl(options.baseURL)
+    , m_timeout(options.timeout)
+    , m_networkManager(NetworkAccessManager::instance())
 {
-    // 初始化默认拦截器
     if (options.enableDefaultInterceptors) {
         setupDefaultInterceptors();
     }
 }
 
-RequestClient* RequestClient::createClient(const QString& baseURL,
-                                           const RequestClientOptions& options)
+RequestClient::Ptr RequestClient::create(const QString& baseURL, const RequestClientOptions& options)
 {
     RequestClientOptions opts = options;
     opts.baseURL = baseURL;
-    return new RequestClient(opts);
+    return Ptr(new RequestClient(opts));
 }
 
-void RequestClient::setupDefaultInterceptors()
+RequestClient::Ptr RequestClient::globalInstance()
 {
-    // 添加认证拦截器
-    auto authRequestInterceptor = new AuthRequestInterceptor();
-    addInterceptor(authRequestInterceptor);
-
-    // 添加响应拦截器
-    auto authResponseInterceptor = new AuthResponseInterceptor();
-    addInterceptor(authResponseInterceptor);
-
-    // 添加错误处理拦截器
-    auto errorInterceptor = new ErrorResponseInterceptor();
-    addInterceptor(errorInterceptor);
+    static RequestClient::Ptr instance = create(base_url, {"", true});
+    return instance;
 }
 
-void RequestClient::addInterceptor(Interceptor* interceptor)
+RequestClient::Ptr RequestClient::baseGlobalInstance()
 {
-    if (!interceptors.contains(interceptor)) {
-        interceptors.append(interceptor);
-    }
+    static RequestClient::Ptr instance = create(base_url, {"", false});
+    return instance;
 }
 
-void RequestClient::removeInterceptor(Interceptor* interceptor)
+void RequestClient::setupDefaultInterceptors()
 {
-    interceptors.removeOne(interceptor);
-}
+    QMutexLocker locker(&m_interceptorMutex);
 
-void RequestClient::setBaseUrl(const QString& url)
-{
-    m_baseUrl = url;
+    // 添加认证拦截器
+    m_interceptors.push_back(std::make_shared<AuthRequestInterceptor>());
+
+    // 添加错误处理拦截器
+    m_interceptors.push_back(std::make_shared<ErrorResponseInterceptor>());
 }
 
-QString RequestClient::baseUrl() const
+void RequestClient::addInterceptor(std::shared_ptr<Interceptor> interceptor)
 {
-    if (m_baseUrl.isEmpty()) {
-        return base_url;
+    QMutexLocker locker(&m_interceptorMutex);
+    if (!m_interceptors.contains(interceptor)) {
+        m_interceptors.append(interceptor);
     }
-    return m_baseUrl;
 }
 
-void RequestClient::setTimeout(int timeout)
+void RequestClient::removeInterceptor(std::shared_ptr<Interceptor> interceptor)
 {
-    m_timeout = timeout;
+    QMutexLocker locker(&m_interceptorMutex);
+    m_interceptors.removeOne(interceptor);
 }
 
-int RequestClient::timeout() const
+void RequestClient::clearInterceptors()
 {
-    return m_timeout;
+    QMutexLocker locker(&m_interceptorMutex);
+    m_interceptors.clear();
 }
 
-QNetworkReply* RequestClient::getSync(const QString& url, const QVariantMap& params)
+HttpResponse RequestClient::get(const QString& url, const QVariantMap& params)
 {
-    QNetworkReply* reply = get(url, params);
+    QScopedPointer<QNetworkReply> reply(sendGetRequest(url, params));
 
-    // 同步等待
     QEventLoop loop;
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     loop.exec();
 
-    // 处理响应拦截器
-    processResponse(reply);
-
-    return reply;
+    return parseReplyData(reply.get());
 }
 
-QNetworkReply* RequestClient::postSync(const QString& url, const QJsonDocument& data)
+HttpResponse RequestClient::post(const QString& url, const QJsonDocument& data)
 {
-    QNetworkReply* reply = post(url, data);
+    QScopedPointer<QNetworkReply> reply(sendPostRequest(url, data));
 
-    // 同步等待
     QEventLoop loop;
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     loop.exec();
 
-    // 处理响应拦截器
-    processResponse(reply);
-
-    return reply;
+    return parseReplyData(reply.get());
 }
 
-QNetworkReply* RequestClient::putSync(const QString& url, const QJsonDocument& data)
+HttpResponse RequestClient::put(const QString& url, const QJsonDocument& data)
 {
-    QNetworkReply* reply = put(url, data);
+    QScopedPointer<QNetworkReply> reply(sendPutRequest(url, data));
 
-    // 同步等待
     QEventLoop loop;
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     loop.exec();
 
-    // 处理响应拦截器
-    processResponse(reply);
-
-    return reply;
+    return parseReplyData(reply.get());
 }
 
-QNetworkReply* RequestClient::deleteSync(const QString& url)
+HttpResponse RequestClient::deleteResource(const QString& url)
 {
-    QNetworkReply* reply = deleteResource(url);
+    QScopedPointer<QNetworkReply> reply(sendDeleteRequest(url));
 
-    // 同步等待
     QEventLoop loop;
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     loop.exec();
 
-    // 处理响应拦截器
-    processResponse(reply);
-
-    return reply;
+    return parseReplyData(reply.get());
 }
 
-QNetworkReply* RequestClient::uploadSync(const QString& url, QHttpMultiPart* multiPart)
+HttpResponse RequestClient::upload(const QString& url, QHttpMultiPart* multiPart)
 {
-    QNetworkReply* reply = upload(url, multiPart);
+    QScopedPointer<QNetworkReply> reply(sendUploadRequest(url, multiPart));
 
-    // 同步等待
     QEventLoop loop;
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
     loop.exec();
 
-    // 处理响应拦截器
-    processResponse(reply);
-
-    return reply;
+    return parseReplyData(reply.get());
 }
 
 QFuture<HttpResponse> RequestClient::getAsync(const QString& url, const QVariantMap& params)
 {
-    QFutureInterface<HttpResponse> interface;
-    interface.reportStarted();
-
-    QNetworkReply* reply = get(url, params);
-    setupAsyncConnections(reply, interface);
-
-    return interface.future();
+    return QtConcurrent::run([this, url, params] { return get(url, params); });
 }
 
 QFuture<HttpResponse> RequestClient::postAsync(const QString& url, const QJsonDocument& data)
 {
-    QFutureInterface<HttpResponse> interface;
-    interface.reportStarted();
-
-    QNetworkReply* reply = post(url, data);
-    setupAsyncConnections(reply, interface);
-
-    return interface.future();
+    return QtConcurrent::run([this, url, data] { return post(url, data); });
 }
 
 QFuture<HttpResponse> RequestClient::putAsync(const QString& url, const QJsonDocument& data)
 {
-    QFutureInterface<HttpResponse> interface;
-    interface.reportStarted();
-
-    QNetworkReply* reply = put(url, data);
-    setupAsyncConnections(reply, interface);
-
-    return interface.future();
+    return QtConcurrent::run([this, url, data] { return put(url, data); });
 }
 
 QFuture<HttpResponse> RequestClient::deleteAsync(const QString& url)
 {
-    QFutureInterface<HttpResponse> interface;
-    interface.reportStarted();
-
-    QNetworkReply* reply = deleteResource(url);
-    setupAsyncConnections(reply, interface);
-
-    return interface.future();
+    return QtConcurrent::run([this, url] { return deleteResource(url); });
 }
 
 QFuture<HttpResponse> RequestClient::uploadAsync(const QString& url, QHttpMultiPart* multiPart)
 {
-    QFutureInterface<HttpResponse> interface;
-    interface.reportStarted();
-
-    QNetworkReply* reply = upload(url, multiPart);
-    setupAsyncConnections(reply, interface);
-
-    return interface.future();
+    return QtConcurrent::run([this, url, multiPart] { return upload(url, multiPart); });
 }
 
-HttpResponse RequestClient::parseReplyData(QNetworkReply* reply)
+bool RequestClient::download(const QString& url, const QString& saveFilePath)
 {
-    HttpResponse response;
+    QScopedPointer<QNetworkReply> reply(sendGetRequest(url, {}));
 
-    if (reply->error() != QNetworkReply::NoError) {
-        response.code = reply->error();
-        response.message = reply->errorString();
-        return response;
+    QFile file(saveFilePath);
+    if (!file.open(QIODevice::WriteOnly)) {
+        return false;
     }
 
-    const QByteArray responseData = reply->readAll();
-    QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
-    qDebug() << responseData << jsonDoc;
-    if (jsonDoc.isObject()) {
-        const QJsonObject jsonObj = jsonDoc.object();
-        qDebug() << jsonObj;
-        if (jsonObj.contains("code")) {
-            response.code = jsonObj["code"].toInt();
-        }
-        if (jsonObj.contains(messageVal)) {
-            response.message = jsonObj[messageVal].toString();
-        }
-        if (jsonObj.contains("data")) {
-            QJsonValue dataValue = jsonObj["data"];
-            response.data = dataValue;
-        }
-    }
+    QEventLoop loop;
+    QObject::connect(reply.get(), &QNetworkReply::readyRead, [&]() {
+        file.write(reply->readAll());
+    });
 
-    return response;
-}
+    QObject::connect(reply.get(), &QNetworkReply::finished, &loop, &QEventLoop::quit);
+    loop.exec();
 
-void RequestClient::processRequest(QNetworkRequest& request)
-{
-    for (auto interceptor : interceptors) {
-        interceptor->interceptRequest(request);
-    }
+    file.close();
+    return reply->error() == QNetworkReply::NoError;
 }
 
-void RequestClient::processResponse(QNetworkReply* reply)
+QFuture<bool> RequestClient::downloadAsync(const QString& url, const QString& saveFilePath)
 {
-    for (auto interceptor : interceptors) {
-        interceptor->interceptResponse(reply);
-    }
+    return QtConcurrent::run([this, url, saveFilePath] { return download(url, saveFilePath); });
 }
 
-QNetworkReply* RequestClient::get(const QString& url, const QVariantMap& params)
+QNetworkReply* RequestClient::sendGetRequest(const QString& url, const QVariantMap& params)
 {
-    QNetworkAccessManager* manager = NetworkAccessManager::instance();
-    manager->setTransferTimeout(m_timeout);
-
-    QUrl fullUrl(m_baseUrl.isEmpty() ? QString(base_url).append(url) : m_baseUrl.append(url));
+    m_networkManager->setTransferTimeout(m_timeout);
 
-    QUrlQuery query;
-    for (auto it = params.constBegin(); it != params.constEnd(); ++it) {
-        query.addQueryItem(it.key(), it.value().toString());
-    }
+    QString base = m_baseUrl.isEmpty() ? base_url : m_baseUrl;
+    QUrl fullUrl(base + url);
 
     if (!params.isEmpty()) {
+        QUrlQuery query;
+        for (auto it = params.constBegin(); it != params.constEnd(); ++it) {
+            query.addQueryItem(it.key(), it.value().toString());
+        }
         fullUrl.setQuery(query);
     }
 
-    QNetworkRequest modifiedRequest(fullUrl);
-    modifiedRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-    processRequest(modifiedRequest);
-
-    QNetworkReply* reply = manager->get(modifiedRequest);
+    QNetworkRequest request(fullUrl);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+    processRequest(request);
 
-    return reply;
+    emit requestStarted(fullUrl);
+    return m_networkManager->get(request);
 }
 
-QNetworkReply* RequestClient::post(const QString& url, const QJsonDocument& data)
+QNetworkReply* RequestClient::sendPostRequest(const QString& url, const QJsonDocument& data)
 {
-    QNetworkAccessManager* manager = NetworkAccessManager::instance();
-    manager->setTransferTimeout(m_timeout);
+    m_networkManager->setTransferTimeout(m_timeout);
 
-    QUrl fullUrl(m_baseUrl.isEmpty() ? QString(base_url).append(url) : m_baseUrl.append(url));
+    QString base = m_baseUrl.isEmpty() ? base_url : m_baseUrl;
+    QUrl fullUrl(base + url);
 
     QBuffer* buffer = new QBuffer;
     buffer->setData(data.toJson());
     buffer->open(QIODevice::ReadOnly);
 
-    QNetworkRequest modifiedRequest(fullUrl);
-    modifiedRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
-    processRequest(modifiedRequest);
+    QNetworkRequest request(fullUrl);
+    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
+    processRequest(request);
 
-    QNetworkReply* reply = manager->post(modifiedRequest, buffer);
+    emit requestStarted(fullUrl);
+    QNetworkReply* reply = m_networkManager->post(request, buffer);
     buffer->setParent(reply);
 
     return reply;
 }
 
-QNetworkReply* RequestClient::put(const QString& url, const QJsonDocument& data)
+QNetworkReply* RequestClient::sendPutRequest(const QString& url, const QJsonDocument& data)
 {
-    QNetworkAccessManager* manager = NetworkAccessManager::instance();
-    manager->setTransferTimeout(m_timeout);
+    m_networkManager->setTransferTimeout(m_timeout);
 
-    QUrl fullUrl(m_baseUrl.isEmpty() ? QString(base_url).append(url) : m_baseUrl.append(url));
+    QString base = m_baseUrl.isEmpty() ? base_url : m_baseUrl;
+    QUrl fullUrl(base + url);
 
     QBuffer* buffer = new QBuffer;
     buffer->setData(data.toJson());
     buffer->open(QIODevice::ReadOnly);
 
-    QNetworkRequest modifiedRequest(fullUrl);
-    processRequest(modifiedRequest);
-    QNetworkReply* reply = manager->put(modifiedRequest, buffer);
+    QNetworkRequest request(fullUrl);
+    processRequest(request);
+
+    emit requestStarted(fullUrl);
+    QNetworkReply* reply = m_networkManager->put(request, buffer);
     buffer->setParent(reply);
 
     return reply;
 }
 
-QNetworkReply* RequestClient::deleteResource(const QString& url)
+QNetworkReply* RequestClient::sendDeleteRequest(const QString& url)
 {
-    QNetworkAccessManager* manager = NetworkAccessManager::instance();
-    manager->setTransferTimeout(m_timeout);
+    m_networkManager->setTransferTimeout(m_timeout);
 
-    QUrl fullUrl(m_baseUrl.isEmpty() ? QString(base_url).append(url) : m_baseUrl.append(url));
+    QString base = m_baseUrl.isEmpty() ? base_url : m_baseUrl;
+    QUrl fullUrl(base + url);
 
-    QNetworkRequest modifiedRequest(fullUrl);
-    processRequest(modifiedRequest);
-    QNetworkReply* reply = manager->deleteResource(modifiedRequest);
+    QNetworkRequest request(fullUrl);
+    processRequest(request);
 
-    return reply;
+    emit requestStarted(fullUrl);
+    return m_networkManager->deleteResource(request);
 }
 
-QNetworkReply* RequestClient::upload(const QString& url, QHttpMultiPart* multiPart)
+QNetworkReply* RequestClient::sendUploadRequest(const QString& url, QHttpMultiPart* multiPart)
 {
-    QNetworkAccessManager* manager = NetworkAccessManager::instance();
-    manager->setTransferTimeout(m_timeout);
+    m_networkManager->setTransferTimeout(m_timeout);
 
-    QUrl fullUrl(m_baseUrl.isEmpty() ? QString(base_url).append(url) : m_baseUrl.append(url));
+    QString base = m_baseUrl.isEmpty() ? base_url : m_baseUrl;
+    QUrl fullUrl(base + url);
 
-    QNetworkRequest modifiedRequest(fullUrl);
+    QNetworkRequest request(fullUrl);
+    processRequest(request);
 
-    QNetworkReply* reply = manager->post(modifiedRequest, multiPart);
-
-    return reply;
+    emit requestStarted(fullUrl);
+    return m_networkManager->post(request, multiPart);
 }
 
-bool RequestClient::download(const QString& url, const QString& saveFilePath)
+HttpResponse RequestClient::parseReplyData(QNetworkReply* reply)
 {
-    QNetworkReply* reply = get(url);
-
-    QEventLoop loop;
-    QFile file(saveFilePath);
+    HttpResponse response;
 
-    if (!file.open(QIODevice::WriteOnly)) {
-        return false;
+    if (reply->error() != QNetworkReply::NoError) {
+        response.code = reply->error();
+        response.message = reply->errorString();
+        emit requestFailed(reply->url(), response.message);
+        return response;
     }
 
-    QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
-    QObject::connect(reply, &QNetworkReply::readyRead, [&]() { file.write(reply->readAll()); });
+    const QByteArray responseData = readReplyData(reply);
+    response.rawData = responseData;
 
-    loop.exec();
+    QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
+    if (jsonDoc.isObject()) {
+        const QJsonObject jsonObj = jsonDoc.object();
+        if (jsonObj.contains("code")) {
+            response.code = jsonObj["code"].toInt();
+        }
+        if (jsonObj.contains(messageVal)) {
+            response.message = jsonObj[messageVal].toString();
+        }
+        if (jsonObj.contains("data")) {
+            response.data = jsonObj["data"];
+        }
+    }
 
-    file.close();
+    emit requestFinished(reply->url(), response);
+    return response;
+}
 
-    return reply->error() == QNetworkReply::NoError;
+void RequestClient::processRequest(QNetworkRequest& request)
+{
+    QMutexLocker locker(&m_interceptorMutex);
+    for (auto& interceptor : m_interceptors) {
+        interceptor->interceptRequest(request);
+    }
 }
 
-void RequestClient::setupAsyncConnections(QNetworkReply* reply,
-                                          QFutureInterface<HttpResponse>& _interface)
-{ // 处理网络错误信号
-    QObject::connect(reply,
-                     &QNetworkReply::errorOccurred,
-                     [this, reply, _interface](QNetworkReply::NetworkError error) mutable {
-                         // 避免重复处理
-                         if (reply->property("handled").toBool()) {
-                             return;
-                         }
-
-                         reply->setProperty("handled", true);
-                         this->processResponse(reply);
-
-                         HttpResponse errorResponse;
-                         errorResponse.code = error;
-                         errorResponse.message = reply->errorString();
-
-                         // 特殊处理网络错误类型
-                         if (error == QNetworkReply::OperationCanceledError) {
-                             errorResponse.message = "请求被取消";
-                         } else if (error == QNetworkReply::TimeoutError) {
-                             errorResponse.message = "请求超时";
-                         } else if (error == QNetworkReply::ConnectionRefusedError) {
-                             errorResponse.message = "连接被拒绝";
-                         } else if (error == QNetworkReply::HostNotFoundError) {
-                             errorResponse.message = "找不到主机";
-                         }
-
-                         _interface.reportResult(errorResponse);
-                         _interface.reportFinished();
-                     });
-
-    // 处理完成信号
-    QObject::connect(reply, &QNetworkReply::finished, [this, reply, _interface]() mutable {
-        // 避免重复处理
-        if (reply->property("handled").toBool()) {
-            reply->deleteLater();
-            return;
-        }
+void RequestClient::processResponse(QNetworkReply* reply)
+{
+    QMutexLocker locker(&m_interceptorMutex);
+    for (auto& interceptor : m_interceptors) {
+        interceptor->interceptResponse(reply);
+    }
+}
 
-        reply->setProperty("handled", true);
-        processResponse(reply);
+QByteArray RequestClient::readReplyData(QNetworkReply* reply)
+{
+    if (reply->property("cachedData").isValid()) {
+        return reply->property("cachedData").toByteArray();
+    }
 
-        try {
-            // 即使在 finished 信号中,也需要检查是否有错误
-            if (reply->error() != QNetworkReply::NoError) {
-                HttpResponse errorResponse;
-                errorResponse.code = reply->error();
-                errorResponse.message = reply->errorString();
-                _interface.reportResult(errorResponse);
-            } else {
-                HttpResponse response = parseReplyData(reply);
-                _interface.reportResult(response);
-            }
-            _interface.reportFinished();
-        } catch (const std::exception& e) {
-            HttpResponse errorResponse;
-            errorResponse.code = -1;
-            errorResponse.message = QString::fromUtf8(e.what());
-            _interface.reportResult(errorResponse);
-            _interface.reportFinished();
-        }
+    QByteArray data = reply->readAll();
+    cacheReplyData(reply, data);
+    return data;
+}
 
-        reply->deleteLater();
-    });
+void RequestClient::cacheReplyData(QNetworkReply* reply, const QByteArray& data)
+{
+    reply->setProperty("cachedData", data);
 }
 
 // 拦截器实现
@@ -582,145 +455,59 @@ void AuthRequestInterceptor::interceptRequest(QNetworkRequest& request)
     request.setRawHeader("Accept-Language", AppEvent::instance()->locale().toUtf8());
 }
 
-void AuthResponseInterceptor::interceptResponse(QNetworkReply* reply)
+void AuthRequestInterceptor::interceptResponse(QNetworkReply* reply)
 {
-    // 检查是否需要刷新token
     if (reply->error() == QNetworkReply::AuthenticationRequiredError) {
         // 触发token刷新
         emit AppEvent::instance()->refreshTokenNeeded();
 
-        // 如果启用了自动刷新token,可以在这里实现
         if (AppEvent::instance()->isEnableRefreshToken()) {
-            doRefreshToken();
-        } else {
-            doReAuthenticate();
-        }
-    }
-}
-
-void AuthResponseInterceptor::doRefreshToken()
-{
-    // 实现刷新token的逻辑
-    RequestClient refreshClient;
-    QJsonObject emptyData;
-    QJsonDocument jsonDoc(emptyData);
+            // 刷新token逻辑
+            auto client = RequestClient::baseGlobalInstance();
+            QJsonObject emptyData;
+            QJsonDocument jsonDoc(emptyData);
 
-    QNetworkReply* reply = refreshClient.postSync("/api/auth/refresh-token", jsonDoc);
+            HttpResponse response = client->post("/api/auth/refresh-token", jsonDoc);
 
-    if (reply->error() == QNetworkReply::NoError) {
-        QByteArray responseData = reply->readAll();
-        QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData);
-        QJsonObject jsonObject = jsonResponse.object();
-
-        if (jsonObject.contains("data")) {
-            QString newToken = jsonObject["data"].toString();
-            AppEvent::instance()->setJwtToken(newToken);
+            if (response.code == 0) {
+                QString newToken = response.data.toString();
+                AppEvent::instance()->setJwtToken(newToken);
+            } else {
+                // 刷新失败,需要重新登录
+                AppEvent::instance()->setJwtToken("");
+                emit AppEvent::instance()->loginExpired(true);
+            }
+        } else {
+            // 直接重新认证
+            AppEvent::instance()->setJwtToken("");
+            emit AppEvent::instance()->loginExpired(true);
         }
-    } else {
-        // 刷新失败,需要重新登录
-        doReAuthenticate();
     }
-
-    reply->deleteLater();
-}
-
-void AuthResponseInterceptor::doReAuthenticate()
-{
-    // 实现重新认证的逻辑
-    AppEvent::instance()->setJwtToken("");
-    emit AppEvent::instance()->loginExpired(true);
 }
 
 void ErrorResponseInterceptor::interceptResponse(QNetworkReply* reply)
 {
     if (reply->error() != QNetworkReply::NoError) {
-        // 解析错误信息
-        QByteArray responseData = reply->readAll();
+        QByteArray responseData = reply->property("cachedData").toByteArray();
         QString errorMessage;
 
-        try {
+        if (!responseData.isEmpty()) {
             QJsonDocument jsonResponse = QJsonDocument::fromJson(responseData);
-            QJsonObject jsonObject = jsonResponse.object();
-
-            if (jsonObject.contains("error")) {
-                errorMessage = jsonObject["error"].toString();
-            } else if (jsonObject.contains(messageVal)) {
-                errorMessage = jsonObject[messageVal].toString();
+            if (jsonResponse.isObject()) {
+                QJsonObject jsonObject = jsonResponse.object();
+                if (jsonObject.contains("error")) {
+                    errorMessage = jsonObject["error"].toString();
+                } else if (jsonObject.contains(messageVal)) {
+                    errorMessage = jsonObject[messageVal].toString();
+                }
             }
-        } catch (...) {
-            // 解析失败,使用默认错误信息
         }
 
         if (errorMessage.isEmpty()) {
             errorMessage = reply->errorString();
         }
 
-        // 发送错误信息
         emit AppEvent::instance()->errorMessage(errorMessage);
-
-        // 可以根据不同的错误类型进行不同的处理
-        switch (reply->error()) {
-        case QNetworkReply::ConnectionRefusedError:
-            qDebug() << "连接被拒绝" << errorMessage;
-            break;
-        case QNetworkReply::RemoteHostClosedError:
-            qDebug() << "远程主机关闭连接" << errorMessage;
-            break;
-        case QNetworkReply::HostNotFoundError:
-            qDebug() << "主机未找到" << errorMessage;
-            break;
-        case QNetworkReply::TimeoutError:
-            qDebug() << "连接超时" << errorMessage;
-            break;
-        case QNetworkReply::OperationCanceledError:
-            qDebug() << "操作被取消" << errorMessage;
-            break;
-        case QNetworkReply::SslHandshakeFailedError:
-            qDebug() << "SSL握手失败" << errorMessage;
-            break;
-        case QNetworkReply::TemporaryNetworkFailureError:
-            qDebug() << "临时网络故障" << errorMessage;
-            break;
-        case QNetworkReply::NetworkSessionFailedError:
-            qDebug() << "网络会话失败" << errorMessage;
-            break;
-        case QNetworkReply::BackgroundRequestNotAllowedError:
-            qDebug() << "不允许后台请求" << errorMessage;
-            break;
-        case QNetworkReply::ContentReSendError:
-            qDebug() << "内容重发错误" << errorMessage;
-            break;
-        default:
-            qDebug() << "其他网络错误" << errorMessage;
-            break;
-        }
     }
 }
-
-// 创建全局客户端实例
-static RequestClient* requestClientInstance = nullptr;
-static RequestClient* baseRequestClientInstance = nullptr;
-
-RequestClient* RequestClient::requestClient(const RequestClientOptions& defaultOptions)
-{
-    if (!requestClientInstance) {
-        RequestClientOptions options = defaultOptions;
-        options.enableDefaultInterceptors = true;
-        options.responseReturn = "data";
-        requestClientInstance = createClient(options.baseURL, options);
-    }
-    return requestClientInstance;
-}
-
-RequestClient* RequestClient::baseRequestClient(const RequestClientOptions& defaultOptions)
-{
-    if (!baseRequestClientInstance) {
-        RequestClientOptions options = defaultOptions;
-        options.enableDefaultInterceptors = false;
-        options.responseReturn = "data";
-        baseRequestClientInstance = createClient(options.baseURL, options);
-    }
-    return baseRequestClientInstance;
-}
-
 } // namespace TC

+ 76 - 52
network/networkaccessmanager.h

@@ -2,17 +2,16 @@
 #define NETWORKACCESSMANAGER_H
 
 #include <QFuture>
-#include <QFutureInterface>
 #include <QHttpMultiPart>
-#include <QJsonArray>
 #include <QJsonDocument>
-#include <QJsonObject>
-#include <QJsonValue>
-#include <QList>
+#include <QMutex>
+#include <QMutexLocker>
 #include <QNetworkAccessManager>
 #include <QNetworkReply>
 #include <QNetworkRequest>
+#include <QSharedPointer>
 #include <functional>
+#include <memory>
 
 class NetworkAccessManager : public QNetworkAccessManager
 {
@@ -27,108 +26,133 @@ protected:
                                  const QNetworkRequest& request,
                                  QIODevice* outgoingData = nullptr) override;
 };
-// HTTP 响应结构
+
 struct HttpResponse
 {
     int code = 0;
     QJsonValue data;
     QString message;
+    QByteArray rawData;
 };
 
 namespace TC {
-// 拦截器接口
 class Interceptor
 {
 public:
-    virtual ~Interceptor() {}
-    virtual void interceptRequest(QNetworkRequest& /*request*/) {}
-    virtual void interceptResponse(QNetworkReply* /*reply*/) {}
+    virtual ~Interceptor() = default;
+    virtual void interceptRequest(QNetworkRequest& request) = 0;
+    virtual void interceptResponse(QNetworkReply* reply) = 0;
 };
 
-// 请求客户端选项
 struct RequestClientOptions
 {
     QString baseURL;
     bool enableDefaultInterceptors = true;
-    QString responseReturn = ""; // 可以是 "data" 或空
-
     int timeout = 10000; // 默认超时时间为10秒
 };
 
-// 请求客户端
 class RequestClient : public QObject
 {
     Q_OBJECT
 public:
+    using Ptr = QSharedPointer<RequestClient>;
+
     explicit RequestClient(const RequestClientOptions& options = RequestClientOptions());
+    virtual ~RequestClient() = default;
+
+    // 禁用拷贝和赋值
+    RequestClient(const RequestClient&) = delete;
+    RequestClient& operator=(const RequestClient&) = delete;
 
     // 创建客户端实例
-    static RequestClient* createClient(const QString& baseURL,
-                                       const RequestClientOptions& options = RequestClientOptions());
+    static Ptr create(const QString& baseURL = "",
+                      const RequestClientOptions& options = RequestClientOptions());
 
     // 获取全局实例
-    static RequestClient* requestClient(const RequestClientOptions& options = RequestClientOptions());
-    static RequestClient* baseRequestClient(
-        const RequestClientOptions& options = RequestClientOptions());
+    static Ptr globalInstance();
+    static Ptr baseGlobalInstance();
 
     // 拦截器管理
-    void addInterceptor(Interceptor* interceptor);
-    void removeInterceptor(Interceptor* interceptor);
+    void addInterceptor(std::shared_ptr<Interceptor> interceptor);
+    void removeInterceptor(std::shared_ptr<Interceptor> interceptor);
+    void clearInterceptors();
 
     // 基础URL设置
-    void setBaseUrl(const QString& url);
-    QString baseUrl() const;
+    void setBaseUrl(const QString& url) { m_baseUrl = url; }
+    QString baseUrl() const { return m_baseUrl; }
 
-    void setTimeout(int timeout);
-    int timeout() const;
+    void setTimeout(int timeout) { m_timeout = timeout; }
+    int timeout() const { return m_timeout; }
 
     // 同步请求
-    QNetworkReply* getSync(const QString& url, const QVariantMap& params = QVariantMap());
-    QNetworkReply* postSync(const QString& url, const QJsonDocument& data = QJsonDocument());
-    QNetworkReply* putSync(const QString& url, const QJsonDocument& data = QJsonDocument());
-    QNetworkReply* deleteSync(const QString& url);
-    QNetworkReply* uploadSync(const QString& url, QHttpMultiPart* multiPart);
+    HttpResponse get(const QString& url, const QVariantMap& params = {});
+    HttpResponse post(const QString& url, const QJsonDocument& data = {});
+    HttpResponse put(const QString& url, const QJsonDocument& data = {});
+    HttpResponse deleteResource(const QString& url);
+    HttpResponse upload(const QString& url, QHttpMultiPart* multiPart);
 
     // 异步请求
-    QFuture<HttpResponse> getAsync(const QString& url, const QVariantMap& params = QVariantMap());
-    QFuture<HttpResponse> postAsync(const QString& url, const QJsonDocument& data = QJsonDocument());
-    QFuture<HttpResponse> putAsync(const QString& url, const QJsonDocument& data = QJsonDocument());
+    QFuture<HttpResponse> getAsync(const QString& url, const QVariantMap& params = {});
+    QFuture<HttpResponse> postAsync(const QString& url, const QJsonDocument& data = {});
+    QFuture<HttpResponse> putAsync(const QString& url, const QJsonDocument& data = {});
     QFuture<HttpResponse> deleteAsync(const QString& url);
     QFuture<HttpResponse> uploadAsync(const QString& url, QHttpMultiPart* multiPart);
 
-    QFuture<bool> downloadAsync(const QString& url, const QString& saveFilePath);
-
+    // 文件下载
     bool download(const QString& url, const QString& saveFilePath);
+    QFuture<bool> downloadAsync(const QString& url, const QString& saveFilePath);
 
-    // Token 刷新相关
-    bool isRefreshing() const { return m_isRefreshing; }
-    void setRefreshing(bool refreshing) { m_isRefreshing = refreshing; }
-    QList<std::function<void(const QString&)>>& refreshTokenQueue() { return m_refreshTokenQueue; }
-
-    void setupAsyncConnections(QNetworkReply* reply, QFutureInterface<HttpResponse>& _interface);
+signals:
+    void requestStarted(const QUrl& url);
+    void requestFinished(const QUrl& url, const HttpResponse& response);
+    void requestFailed(const QUrl& url, const QString& error);
 
 private:
-    // 原始请求方法
-    QNetworkReply* get(const QString& url, const QVariantMap& params = QVariantMap());
-    QNetworkReply* post(const QString& url, const QJsonDocument& data = QJsonDocument());
-    QNetworkReply* put(const QString& url, const QJsonDocument& data = QJsonDocument());
-    QNetworkReply* deleteResource(const QString& url);
-    QNetworkReply* upload(const QString& url, QHttpMultiPart* multiPart);
+    struct RequestContext
+    {
+        QNetworkReply* reply = nullptr;
+        QByteArray responseData;
+        bool handled = false;
+    };
+
+    // 内部实现方法
+    QNetworkReply* sendGetRequest(const QString& url, const QVariantMap& params);
+    QNetworkReply* sendPostRequest(const QString& url, const QJsonDocument& data);
+    QNetworkReply* sendPutRequest(const QString& url, const QJsonDocument& data);
+    QNetworkReply* sendDeleteRequest(const QString& url);
+    QNetworkReply* sendUploadRequest(const QString& url, QHttpMultiPart* multiPart);
 
-    void setupDefaultInterceptors();
     void processRequest(QNetworkRequest& request);
     void processResponse(QNetworkReply* reply);
-
     HttpResponse parseReplyData(QNetworkReply* reply);
 
+    QByteArray readReplyData(QNetworkReply* reply);
+    void cacheReplyData(QNetworkReply* reply, const QByteArray& data);
+
+    void setupDefaultInterceptors();
+
     QString m_baseUrl;
     int m_timeout = 10000;
+    QSharedPointer<NetworkAccessManager> m_networkManager;
+    QList<std::shared_ptr<Interceptor>> m_interceptors;
+    QMutex m_interceptorMutex;
+};
 
-    QList<Interceptor*> interceptors;
-    bool m_isRefreshing = false;
-    QList<std::function<void(const QString&)>> m_refreshTokenQueue;
+// 认证请求拦截器
+class AuthRequestInterceptor : public Interceptor
+{
+public:
+    void interceptRequest(QNetworkRequest& request) override;
+    void interceptResponse(QNetworkReply* reply) override;
 };
 
+// 错误响应拦截器
+class ErrorResponseInterceptor : public Interceptor
+{
+public:
+    void interceptRequest(QNetworkRequest& request) override {}
+    void interceptResponse(QNetworkReply* reply) override;
+};
 } // namespace TC
 
 #endif // NETWORKACCESSMANAGER_H

+ 1 - 1
network/websocketclient.cpp

@@ -209,7 +209,7 @@ void WebSocketClient::sendPing()
 QUrl WebSocketClient::buildWebSocketUrl(const QString& roomId)
 {
     // 从HTTP URL构建WebSocket URL
-    QString baseUrl = TC::RequestClient::requestClient()->baseUrl();
+    QString baseUrl = TC::RequestClient::globalInstance()->baseUrl();
 
     // 将http(s)://替换为ws(s)://
     QString wsUrl = baseUrl;