#ifndef UPDATERDIALOG_H #define UPDATERDIALOG_H #include #include #include #include "downloader.h" extern QString APPVERSION; extern QString ORIGIN_URL; extern QString APPNAME; extern QString CHECK_URL; extern QString APPDATE; extern QString MODIFYCNT; namespace Ui { class UpdaterDialog; } class UpdaterDialog : public QDialog { Q_OBJECT public: /** * @brief 构造更新对话框。 * @param parent Qt 父窗口;Downloader/QNetworkAccessManager 随本窗口释放。 * * 设计意图:界面层负责版本检测、用户确认、补丁解压和启动新程序; * 下载细节委托 Downloader,避免 UI 逻辑和网络落盘逻辑混在一起。 */ explicit UpdaterDialog(QWidget *parent = nullptr); /** * @brief 析构更新对话框。 * * Qt 父子对象会释放 Downloader、网络管理器等 QObject;手动 new 且无 parent 的进程对象会在析构中释放。 */ ~UpdaterDialog(); /** * @brief 追加显示状态文本。 * @param message 输入的人类可读状态信息,允许为空但不会清空已有日志。 */ void showStatus(const QString &); /** * @brief 计算并显示下载字节量。 * @param received 已接收字节数。 * @param total 总字节数;小于等于 0 表示未知长度。 */ void calculateSizes(qint64 received, qint64 total); /** * @brief 计算并显示下载速度和剩余时间。 * @param received 已接收字节数。 * @param total 总字节数;未知长度时不计算剩余时间。 */ void calculateTimeRemaining(qint64 received, qint64 total); /** * @brief 判断远程版本是否高于本地版本。 * @param _localVersion 本地版本号,支持 x.y.z 形式。 * @param _remoteVersion 远程版本号,支持 x.y.z 形式。 * @return true 表示需要更新;false 表示本地已经是最新或远程版本无效。 * * 边界条件:版本段数量不一致时按缺失段为 0 比较,避免旧实现访问越界。 */ bool checkVersion(const QString & _localVersion, const QString & _remoteVersion); private slots: /** @brief “check” 按钮槽函数,发起远程 updates.json 检测请求。 */ void on_btn_check_clicked(); /** @brief 版本检测响应处理槽函数,解析 JSON 并刷新可更新状态。 */ void onCheckReply(QNetworkReply *); /** @brief “update-full” 按钮槽函数,下载完整安装包或当前推荐包。 */ void on_btn_update_clicked(); /** @brief “cancel” 按钮槽函数,重新启动原程序并退出更新器。 */ void on_btn_cancel_clicked(); /** @brief 下载完成槽函数,按用户确认执行补丁解压或启动完整包。 */ void onDownloadFinished(); /** @brief “update-patch” 按钮槽函数,强制下载增量补丁包。 */ void on_btn_update_patch_clicked(); private: /** * @brief 设置下载按钮状态。 * @param enabled true 表示允许用户开始下载。 */ void setUpdateButtonsEnabled(bool enabled); /** * @brief 构建下载文件名和 URL。 * * 输入来自 updates.json 和 APPNAME,全量包/补丁包统一在这里拼接,避免多处分支产生不一致文件名。 */ void rebuildDownloadInfo(); /** * @brief 格式化字节数。 * @param bytes 字节数。 * @return 自动选择 B/KB/MB 的显示字符串。 */ QString formatBytes(qint64 bytes) const; /** * @brief 启动当前应用程序。 * * Windows 下启动 APPNAME.exe,Linux 下启动 ./APPNAME;启动失败会显示错误并保留更新器。 */ bool restartApplication(); /** @brief UI 指针,由 setupUi 创建,析构时手动 delete。 */ Ui::UpdaterDialog *ui; /** @brief 文件下载器,父对象为本窗口,信号在 UI 线程中更新界面。 */ Downloader * m_pDownloader = nullptr; /** @brief 本地版本号,用于和远程补丁/全量版本比较。 */ QString m_version; /** @brief 版本检测网络管理器,懒加载创建,避免未检测时占用网络资源。 */ QNetworkAccessManager *m_pManager{nullptr}; /** @brief 平台标识,当前保留字段;实际解析使用全局 PLATFORM。 */ QString m_platform; /** @brief 远程更新日志,用于展示给用户判断更新内容。 */ QString m_changelog; /** @brief 模块名保留字段,用于未来拆分多模块更新。 */ QString m_moduleName; /** @brief 增量补丁下载 URL。 */ QString m_patchUrl; /** @brief 增量补丁基础 URL,来自 updates.json,重复点击下载时用于重新生成完整地址。 */ QString m_patchBaseUrl; /** @brief 增量补丁版本号。 */ QString m_patchVersion; /** @brief 模块版本保留字段,用于未来按模块比较版本。 */ QString m_moduleVersion; /** @brief 完整安装包下载 URL。 */ QString m_fullUrl; /** @brief 完整安装包基础 URL,来自 updates.json,重复点击下载时用于重新生成完整地址。 */ QString m_fullBaseUrl; /** @brief 完整安装包版本号。 */ QString m_fullVersion; /** @brief 远程最后修改日期,通常为 yyyyMMdd 字符串。 */ QString m_lastChangeTime; /** @brief 远程当天修改计数,同版本同日期时用于判断是否仍需更新。 */ QString m_modifyCnt; /** @brief 当前下载目标文件名,不包含目录。 */ QString m_fileName = ""; /** @brief true 表示本次推荐下载完整包,false 表示推荐下载补丁包。 */ bool m_bDownloadFullExe = false; /** @brief 下载计时器,用于计算平均速度和剩余时间,避免系统时间变化造成负值。 */ QElapsedTimer m_downloadTimer; /** @brief 最近一次进度采样的计时毫秒,用于计算瞬时速度。 */ qint64 m_lastProgressMs = 0; /** @brief 最近一次进度采样的已收字节数,用于计算瞬时速度。 */ qint64 m_lastProgressBytes = 0; /** @brief 当前下载总字节数,未知时为 0。 */ quint64 m_totalSize; /** @brief 用于取消时重启原程序;无父对象时析构函数负责释放,避免进程对象泄漏。 */ QProcess *m_UpdateProc{nullptr}; }; #endif // UPDATERDIALOG_H