From 8bd95b77f027807c1aa47fc3297e4013f3adb9ca Mon Sep 17 00:00:00 2001 From: impressionyang Date: Fri, 12 Jun 2026 14:30:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=85=8D=E7=BD=AE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=95=B0=E6=8D=AE=E6=B8=85=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在界面底部增加"数据清理"区域,提供两个按钮: - 清除日志文件:删除日志目录下所有 .log 文件,显示清除数量和释放空间 - 清除录音文件:删除调试音频目录下所有 .wav 文件,显示清除数量和释放空间 清理结果通过 QMessageBox 提示,操作记录写入日志。 Co-Authored-By: Claude Opus 4.7 --- src/ui/settings_page.cpp | 101 +++++++++++++++++++++++++++++++++++++++ src/ui/settings_page.h | 12 +++++ 2 files changed, 113 insertions(+) diff --git a/src/ui/settings_page.cpp b/src/ui/settings_page.cpp index a799dc3..6d003ac 100644 --- a/src/ui/settings_page.cpp +++ b/src/ui/settings_page.cpp @@ -18,6 +18,9 @@ #include #include #include +#include +#include +#include static const char* const kTag = "SettingsPage"; @@ -216,6 +219,26 @@ void SettingsPage::setupUI() { scrollArea->setWidget(contentWidget); mainLayout->addWidget(scrollArea); + // ---- 数据清理(固定不滚动) ---- + auto* cleanGroup = new QGroupBox("数据清理", this); + cleanGroup->setStyleSheet("QGroupBox { margin-top: 4px; }"); + auto* cleanLayout = new QHBoxLayout(cleanGroup); + cleanLayout->setContentsMargins(10, 10, 10, 10); + + clearLogsBtn_ = new QPushButton("清除日志文件", cleanGroup); + clearLogsBtn_->setToolTip("删除日志目录下的所有 .log 文件"); + connect(clearLogsBtn_, &QPushButton::clicked, this, &SettingsPage::onClearLogs); + cleanLayout->addWidget(clearLogsBtn_); + + clearAudioBtn_ = new QPushButton("清除录音文件", cleanGroup); + clearAudioBtn_->setToolTip("删除调试音频目录下的所有 .wav 文件"); + connect(clearAudioBtn_, &QPushButton::clicked, this, &SettingsPage::onClearAudioFiles); + cleanLayout->addWidget(clearAudioBtn_); + + cleanLayout->addStretch(); + + mainLayout->addWidget(cleanGroup); + // ---- 底部操作按钮(固定不滚动) ---- auto* btnBar = new QWidget(this); auto* btnLayout = new QHBoxLayout(btnBar); @@ -387,4 +410,82 @@ void SettingsPage::onResetConfig() { } } +void SettingsPage::onClearLogs() { + QString logDir = configManager_->get("app.log_dir").toString(); + if (logDir.isEmpty()) { + logDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + } + + QDir dir(logDir); + if (!dir.exists()) { + QMessageBox::information(this, "清除日志", "日志目录不存在:" + logDir); + return; + } + + auto result = clearDirectoryFiles(logDir, {"*.log"}, "日志文件"); + if (result.deletedCount < 0) { + QMessageBox::warning(this, "清除日志", "清除失败,请检查目录权限"); + return; + } + if (result.deletedCount == 0) { + QMessageBox::information(this, "清除日志", "没有可清除的日志文件"); + return; + } + QMessageBox::information(this, "清除日志", + QString("已清除 %1 个日志文件,释放 %2 KB 空间") + .arg(result.deletedCount).arg(result.freedBytes / 1024)); + statusLabel_->setText("日志文件已清除"); +} + +void SettingsPage::onClearAudioFiles() { + QString audioDir = configManager_->get("audio.debug_dir").toString(); + if (audioDir.isEmpty()) { + audioDir = QDir::tempPath() + "/impress_audio_debug"; + } + + QDir dir(audioDir); + if (!dir.exists()) { + QMessageBox::information(this, "清除录音", "录音文件目录不存在:" + audioDir); + return; + } + + auto result = clearDirectoryFiles(audioDir, {"*.wav"}, "录音文件"); + if (result.deletedCount < 0) { + QMessageBox::warning(this, "清除录音", "清除失败,请检查目录权限"); + return; + } + if (result.deletedCount == 0) { + QMessageBox::information(this, "清除录音", "没有可清除的录音文件"); + return; + } + QMessageBox::information(this, "清除录音", + QString("已清除 %1 个录音文件,释放 %2 KB 空间") + .arg(result.deletedCount).arg(result.freedBytes / 1024)); + statusLabel_->setText("录音文件已清除"); +} + +SettingsPage::CleanupResult SettingsPage::clearDirectoryFiles( + const QString& dirPath, const QStringList& filters, const QString& desc) { + QDir dir(dirPath); + if (!dir.exists()) return {-1, 0}; + + QFileInfoList files = dir.entryInfoList(filters, QDir::Files | QDir::NoDotAndDotDot); + if (files.isEmpty()) return {0, 0}; + + qint64 totalSize = 0; + int deletedCount = 0; + + for (const auto& fi : files) { + totalSize += fi.size(); + if (dir.remove(fi.fileName())) { + deletedCount++; + } + } + + LOG_INFO(kTag, QString("已清除 %1/%2 个%3,释放 %4 KB") + .arg(deletedCount).arg(files.size()).arg(desc).arg(totalSize / 1024)); + + return {deletedCount, totalSize}; +} + } // namespace impress diff --git a/src/ui/settings_page.h b/src/ui/settings_page.h index 34b9216..abd1827 100644 --- a/src/ui/settings_page.h +++ b/src/ui/settings_page.h @@ -35,14 +35,22 @@ private slots: void onBrowseLogDir(); void onSaveConfig(); void onResetConfig(); + void onClearLogs(); + void onClearAudioFiles(); private: + struct CleanupResult { + int deletedCount; + qint64 freedBytes; + }; + void setupUI(); void loadFromConfig(); void saveToConfig(); void populateAudioDevices(); void selectAudioDevice(int deviceIndex); int getSelectedAudioDeviceIndex() const; + CleanupResult clearDirectoryFiles(const QString& dirPath, const QStringList& filters, const QString& desc); ConfigManager* configManager_; @@ -82,6 +90,10 @@ private: // 状态 QLabel* statusLabel_; + + // 数据清理 + QPushButton* clearLogsBtn_; + QPushButton* clearAudioBtn_; }; } // namespace impress