From 2c2815d433f3327d2cf22ef7f8619e88741bf442 Mon Sep 17 00:00:00 2001 From: zhaominyong Date: Tue, 9 Nov 2021 15:44:26 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B6=E6=AE=B5=E6=80=A7=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backup-daemon/mybackupmanager.cpp | 4 +- backup-daemon/systembackupproxy.cpp | 2 +- kybackup/module/systembackup.cpp | 301 ++++++++++++++++++++++++++-- kybackup/module/systembackup.h | 17 +- 4 files changed, 308 insertions(+), 16 deletions(-) diff --git a/backup-daemon/mybackupmanager.cpp b/backup-daemon/mybackupmanager.cpp index 3eabe81..4581539 100755 --- a/backup-daemon/mybackupmanager.cpp +++ b/backup-daemon/mybackupmanager.cpp @@ -214,8 +214,8 @@ QString MyBackupManager::getBackupCommentForSystemUpdate(QString& state) */ int MyBackupManager::getBackupState(bool& isActive) { - Q_UNUSED(isActive) - return 0; + isActive = m_isActive; + return int(m_backupState); } /** diff --git a/backup-daemon/systembackupproxy.cpp b/backup-daemon/systembackupproxy.cpp index cd4194a..328589b 100755 --- a/backup-daemon/systembackupproxy.cpp +++ b/backup-daemon/systembackupproxy.cpp @@ -310,7 +310,7 @@ bool SystemBackupProxy::doPrepare() QString excludeUserFile = Utils::getSysRootPath() + BACKUP_SNAPSHOTS_PATH + "/" + m_curUuid + "/" + EXCLUDE_PATHS_USER_FILE; excludeUserFile.replace("//", "/"); if (!Utils::writeFileByLines(excludeUserFile, m_backupWrapper.m_backupExcludePaths)) { - emit checkResult(int(BackupResult::WRITE_EXCLUDE_BACKUP_PATHS_TO_USER_FAILED)); + emit checkResult(int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED)); qCritical() << QString("create file %1 failed !").arg(excludeUserFile) ; return false; } diff --git a/kybackup/module/systembackup.cpp b/kybackup/module/systembackup.cpp index 887b484..361642d 100644 --- a/kybackup/module/systembackup.cpp +++ b/kybackup/module/systembackup.cpp @@ -28,6 +28,7 @@ SystemBackup::SystemBackup(QWidget *parent /*= nullptr*/) : initThirdWidget(); initForthWidget(); initFifthWidget(); + initLastWidget(); } SystemBackup::~SystemBackup() @@ -206,13 +207,6 @@ void SystemBackup::initSecondWidget() } }); m_udector->getStorageInfo(); - // 判断是否本地备份 - connect(comboSelect, QOverload::of(&QComboBox::currentIndexChanged), this, [=](int index) { - // 第一个选项是本地系统备份 - this->m_isLocal = GlobelBackupInfo::inst().hasBackupPartition() && (index == 0); - // emit this->backupPathChanged(index); - this->m_prefixDestPath = this->m_udiskPaths.at(index); - }); // 上一步按钮 MyPushButton *preStep = new MyPushButton(second); @@ -229,6 +223,11 @@ void SystemBackup::initSecondWidget() nextStep->setEnabled(true); nextStep->setAutoRepeat(true); connect(nextStep, &MyPushButton::clicked, this, [=](bool checked) { + // 备份路径选择索引 + int index = comboSelect->currentIndex(); + // 第一个选项是本地系统备份 + this->m_isLocal = GlobelBackupInfo::inst().hasBackupPartition() && (index == 0); + this->m_prefixDestPath = this->m_udiskPaths.at(index); this->on_next_clicked(checked); emit this->startCheckEnv(); }); @@ -320,7 +319,6 @@ void SystemBackup::initThirdWidget() recheck->setEnabled(true); recheck->setAutoRepeat(true); connect(recheck, &MyPushButton::clicked, this, [=](bool checked) { - Q_UNUSED(checked) // 为测试下一步骤,这里暂时先改为下一步 // emit this->startCheckEnv(); this->on_next_clicked(checked); @@ -418,10 +416,21 @@ void SystemBackup::on_checkEnv_start() m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this); connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemBackup::on_checkEnv_end); + // 是否已存在备份、还原等操作 + bool isActive = false; + if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){ + on_checkEnv_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING)); + + return; + } + BackupWrapper backupWrapper; backupWrapper.m_type = BackupType::BACKUP_SYSTEM; backupWrapper.m_iPosition = m_isLocal ? BackupPosition::LOCAL : BackupPosition::UDISK; - backupWrapper.m_backupPaths << "/"; + QString backupPath = Utils::getSysRootPath(); + backupPath += "/"; + backupPath.replace("//", "/"); + backupWrapper.m_backupPaths << backupPath; backupWrapper.m_prefixDestPath = m_prefixDestPath; backupWrapper.m_frontUid = getuid(); backupWrapper.m_gid = getgid(); @@ -462,12 +471,18 @@ void SystemBackup::on_checkEnv_end(int result) // 建议释放空间后重试 errTip = tr("Retry after release space"); break; + case int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING): + // 其它备份还原等操作正在执行 + errMsg = tr("Other backup or restore task is being performed"); + // 请稍后重试 + errTip = tr("Please try again later"); + break; default: bRst = true; break; } - checkEnvResult(bRst, errMsg, errTip); + emit checkEnvResult(bRst, errMsg, errTip); GlobelBackupInfo::inst().setIsBusy(false); disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemBackup::on_checkEnv_end); m_pInterface->deleteLater(); @@ -559,6 +574,7 @@ void SystemBackup::initForthWidget() this->m_backupName = editBackupName->placeholderText(); } this->on_next_clicked(checked); + emit this->startBackup(); } }); @@ -610,7 +626,7 @@ bool SystemBackup::isExistsBackupName(const QString & backupName) } // type==8为删除备份点操作 - if (8 == wraper.m_type) + if (BackupType::DELETE_BACKUP == wraper.m_type) setName.remove(wraper.m_backupName); else setName.insert(wraper.m_backupName); @@ -656,7 +672,6 @@ void SystemBackup::initFifthWidget() // 进度条 RingsProgressbar *progressBar = new RingsProgressbar(fifth); progressBar->setGeometry(301, 151, 100, 100); - progressBar->setPersent(20); // 提醒 MyLabel *labelTip = new MyLabel(fifth); @@ -664,6 +679,268 @@ void SystemBackup::initFifthWidget() labelTip->setAlignment(Qt::AlignCenter); labelTip->setDeplayText(tr("Do not use computers in case of data loss")); + // 取消按钮 + MyPushButton *cancel = new MyPushButton(fifth); + cancel->setGeometry(310, 330, 97, 36); + cancel->setText(tr("cancel")); + cancel->setEnabled(true); + cancel->setAutoRepeat(true); + + // 开始备份 + connect(this, &SystemBackup::startBackup, this, [=] { + progressBar->setPersent(0); + + // 开始备份 + this->on_backup_start(); + }); + + // 进度 + connect(this, &SystemBackup::progress, this, [=](int state, int rate) { + Q_UNUSED(state) + progressBar->setPersent(rate); + }); + + // 取消备份 + connect(cancel, &MyPushButton::clicked, this, [=](bool checked) { + Q_UNUSED(checked) + // TODO + }); + addWidget(fifth); } +/** + * @brief 开始进行系统备份 + */ +void SystemBackup::on_backup_start() +{ + GlobelBackupInfo::inst().setIsBusy(true); + m_pInterface = new ComKylinBackupManagerInterface("com.kylin.backup", "/", QDBusConnection::systemBus(), this); + connect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemBackup::on_checkBackup_end); + connect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &SystemBackup::progress); + connect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &SystemBackup::on_backup_end); + + // 是否已存在备份、还原等操作 + bool isActive = false; + if(int(BackupState::BACKUP_STATE_INIT) != m_pInterface->getBackupState(isActive)){ + on_checkEnv_end(int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING)); + + return; + } + + BackupWrapper backupWrapper; + backupWrapper.m_type = BackupType::BACKUP_SYSTEM; + backupWrapper.m_iPosition = m_isLocal ? BackupPosition::LOCAL : BackupPosition::UDISK; + QString backupPath = Utils::getSysRootPath(); + backupPath += "/"; + backupPath.replace("//", "/"); + backupWrapper.m_backupPaths << backupPath; + backupWrapper.m_prefixDestPath = m_prefixDestPath; + backupWrapper.m_frontUid = getuid(); + backupWrapper.m_gid = getgid(); + m_pInterface->goBackup(backupWrapper); +} + +/** + * @brief 系统备份校验结果处理 + * @param result + */ +void SystemBackup::on_checkBackup_end(int result) +{ + m_systemBackupState = SystemBackupState::IDEL; + bool bRst = false; + QString errMsg, errTip; + switch (result) { + case int(BackupResult::LOCK_PROGRAM_FAIL): + // 程序锁定失败,请重试 + errMsg = tr("Program lock failed, please retry"); + // 可能有其它备份/还原等任务在执行 + errTip = tr("There may be other backups or restores being performed"); + break; + case int(BackupResult::NO_FOUND_DEALCLASS): + // 不支持的任务类型 + errMsg = tr("Unsupported task type"); + // 没有找到相应的处理逻辑 + errTip = tr("No processing logic was found in the service"); + break; + case int(BackupResult::BACKUP_PARTITION_MOUNT_FAIL): + // 备份分区挂载失败 + errMsg = tr("Failed to mount the backup partition"); + // 检查是否有备份分区 + errTip = tr("Check whether there is a backup partition"); + break; + case int(BackupResult::BACKUP_CAPACITY_IS_NOT_ENOUGH): + // 备份空间不足 + errMsg = tr("The storage for backup is not enough."); + // 建议释放空间后重试 + errTip = tr("Retry after release space"); + break; + case int(BackupResult::OTHER_BACKUP_OR_RESTORE_RUNNING): + // 其它备份还原等操作正在执行 + errMsg = tr("Other backup or restore task is being performed"); + // 请稍后重试 + errTip = tr("Please try again later"); + break; + case int(BackupResult::WRITE_BACKUP_PATHS_TO_USER_FAILED): + case int(BackupResult::WRITE_STORAGEINFO_ADD_ITEM_FAIL): + case int(BackupResult::WRITE_STORAGEINFO_UPDATE_ITEM_FAIL): + // 创建备份点目录失败 + errMsg = tr("Failed to create the backup point directory."); + // 请检查备份目录是否有写权限 + errTip = tr("Please check backup partition permissions"); + break; + default: + bRst = true; + break; + } + + this->on_next_clicked(true); + emit checkEnvResult(bRst, errMsg, errTip); + GlobelBackupInfo::inst().setIsBusy(false); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemBackup::on_checkEnv_end); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::progress, this, &SystemBackup::progress); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &SystemBackup::on_backup_end); + m_pInterface->deleteLater(); +} + +/** + * @brief 系统备份结束 + * @param result-false 失败; true 成功 + */ +void SystemBackup::on_backup_end(bool result) +{ + m_systemBackupState = SystemBackupState::IDEL; + + this->on_next_clicked(true); + if (result) { + emit checkEnvResult(result); + } else { + // 备份过程中出现错误 + QString errMsg = tr("An error occurred during backup"); + // 错误信息参考日志文件:/var/log/backup.log + QString errTip = tr("Error messages refer to log file : /var/log/backup.log"); + emit checkEnvResult(result, errMsg, errTip); + } + + GlobelBackupInfo::inst().setIsBusy(false); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::sendEnvCheckResult, this, &SystemBackup::on_checkEnv_end); + disconnect(m_pInterface, &ComKylinBackupManagerInterface::backupFinished, this, &SystemBackup::on_backup_end); + m_pInterface->deleteLater(); +} + +/** + * @brief 最后备份结果界面 + */ +void SystemBackup::initLastWidget() +{ + QWidget *last = new QWidget; + + // 流程进度提示栏 + CircleLable *one = new CircleLable("1", last, 24, QColor(COLOR_BLUE)); + one->move(QPoint(81, 41)); + LineLabel *line1 = new LineLabel(last, QColor(COLOR_BLUE)); + line1->move(QPoint(108, 41)); + CircleLable *two = new CircleLable("2", last, 24, QColor(COLOR_BLUE)); + two->move(QPoint(261, 41)); + LineLabel *line2 = new LineLabel(last, QColor(COLOR_BLUE)); + line2->move(QPoint(288, 41)); + CircleLable *three = new CircleLable("3", last, 24, QColor(COLOR_BLUE)); + three->move(QPoint(441, 41)); + LineLabel *line3 = new LineLabel(last, QColor(COLOR_BLUE)); + line3->move(QPoint(468, 41)); + CircleLable *four = new CircleLable("4", last, 24, QColor(COLOR_BLUE)); + four->move(QPoint(621, 41)); + MyLabel *label1 = new MyLabel(tr("checking"), last); + label1->setFontColor(QColor(COLOR_BLUE)); + label1->setGeometry(11, 72, 164, 30); + MyLabel *label2 = new MyLabel(tr("preparing"), last); + label2->setFontColor(QColor(COLOR_BLUE)); + label2->setGeometry(191, 72, 164, 30); + MyLabel *label3 = new MyLabel(tr("backuping"), last); + label3->setFontColor(QColor(COLOR_BLUE)); + label3->setGeometry(371, 72, 164, 30); + MyLabel *label4 = new MyLabel(tr("finished"), last); + label4->setFontColor(QColor(COLOR_BLUE)); + label4->setGeometry(551, 72, 164, 30); + + // --------------失败界面-------------- + // 备份结果对错图标 + QLabel *resultLogo = new QLabel(last); + resultLogo->setGeometry(220, 180, 20, 20); + + // 备份结果大标题 + MyLabel *bigTitle = new MyLabel(last); + bigTitle->setFontSize(24); + bigTitle->setGeometry(251, 170, 500, 36); + + // 备份结果错误提示:黑点和文字 + CircleLable *dot1 = new CircleLable(QString(""), last, 6, Qt::black); + dot1->setGeometry(231, 235, 6, 6); + MyLabel *labelError1 = new MyLabel(last); + labelError1->setGeometry(251, 220, 300, 30); + + CircleLable *dot2 = new CircleLable(QString(""), last, 6, Qt::black); + dot2->setGeometry(231, 265, 6, 6); + MyLabel *labelError2 = new MyLabel(last); + labelError2->setGeometry(251, 250, 300, 30); + + // 再试一次 + MyPushButton *retry = new MyPushButton(last); + retry->setGeometry(310, 330, 97, 36); + retry->setText(tr("retry")); + retry->setEnabled(true); + retry->setAutoRepeat(true); + + // --------------成功界面-------------- + // 返回首页 + MyPushButton *homePage = new MyPushButton(last); + homePage->setGeometry(310, 330, 97, 36); + homePage->setText(tr("home page")); + homePage->setEnabled(true); + homePage->setAutoRepeat(true); + + // 备份检测结果 + connect(this, &SystemBackup::checkEnvResult, this, [=](bool result, const QString &errMsg, const QString &errTip) { + if (result) { + QIcon icon = QIcon::fromTheme("ukui-dialog-success", QIcon(":/symbos/ukui-dialog-success.png")); + resultLogo->setPixmap(icon.pixmap(QSize(20,20))); + resultLogo->setVisible(true); + // 备份成功 + bigTitle->setDeplayText(tr("The backup is successful")); + + dot1->setVisible(false); + dot2->setVisible(false); + labelError1->setVisible(false); + labelError2->setVisible(false); + retry->setVisible(false); + + homePage->setVisible(true); + } else { + QIcon icon = QIcon::fromTheme("dialog-error.png", QIcon(":/symbos/dialog-error.png")); + resultLogo->setPixmap(icon.pixmap(QSize(20,20))); + resultLogo->setVisible(true); + // 环境校验失败 + bigTitle->setDeplayText(tr("The backup is failed")); + labelError1->setDeplayText(errMsg); + labelError2->setDeplayText(errTip); + retry->setVisible(true); + + homePage->setVisible(false); + } + }); + + // 再试一次 + connect(retry, &MyPushButton::clicked, this, [=](bool checked) { + Q_UNUSED(checked) + this->setCurrentIndex(SystemBackupPage::NAME_BACKUP_PAGE); + }); + + // 返回首页 + connect(homePage, &MyPushButton::clicked, this, [=](bool checked) { + Q_UNUSED(checked) + this->setCurrentIndex(SystemBackupPage::HOME_PAGE); + }); + + addWidget(last); +} + diff --git a/kybackup/module/systembackup.h b/kybackup/module/systembackup.h index a950f7c..de060c6 100644 --- a/kybackup/module/systembackup.h +++ b/kybackup/module/systembackup.h @@ -16,6 +16,16 @@ public: CHECKING, // 环境校验中 BACKUPING // 备份中 }; + + enum SystemBackupPage + { + HOME_PAGE, // 首页 + SELECT_PATH_PAGE, // 选择备份路径页 + CHECK_ENV_PAGE, // 环境检测页 + NAME_BACKUP_PAGE, // 备份命名页 + BACKUP_PAGE, // 备份中页 + LAST_PAGE, // 结束页 + }; public: explicit SystemBackup(QWidget *parent = nullptr); ~SystemBackup(); @@ -26,6 +36,7 @@ private: void initThirdWidget(); void initForthWidget(); void initFifthWidget(); + void initLastWidget(); QList getBackupPointList(); bool isExistsBackupName(const QString & backupName); @@ -33,7 +44,8 @@ private: signals: void startCheckEnv(); void checkEnvResult(bool result, const QString &errMsg = "", const QString &errTip = ""); - void backupPathChanged(int index); + void startBackup(); + void progress(int state, int rate); public slots: void on_pre_clicked(bool checked = false); @@ -41,6 +53,9 @@ public slots: void on_systemBackupManage_clicked(); void on_checkEnv_start(); void on_checkEnv_end(int result); + void on_backup_start(); + void on_checkBackup_end(int result); + void on_backup_end(bool result); private: // U盘探测