#ifndef NMNUMERICALSAVESESSION_H #define NMNUMERICALSAVESESSION_H #include "nmData_global.h" #include "nmNumericalResultPersistence.h" #include #include #include class nmDataAnalyzeManager; /** @brief 根清单中的一个数值分析窗口条目。 */ struct NM_DATA_EXPORT nmNumericalSavedWindow { /** @brief 成果业务标识。 */ QString m_sResultId; /** @brief 数值分析窗口的稳定标识。 */ QString m_sWindowId; /** @brief 相对于成果根目录的窗口主 JSON 引用。 */ nmNumericalFileReference m_oMainJson; }; /** * @brief 跨窗口 v3 保存会话,负责新代次、根清单发布和失败中止。 * * 一个实例一次只能处理一个代次。析构时若尚未成功提交,会自动中止, * 防止下一轮保存复用未完成状态。 */ class NM_DATA_EXPORT nmNumericalSaveSession { public: /** @brief 创建尚未开始的保存会话。 */ nmNumericalSaveSession(); /** @brief 未提交的会话在析构时自动删除本代次临时目录。 */ ~nmNumericalSaveSession(); /** * @brief 开始一个全窗口保存代次。 * @param bPreserveExistingWindows 单窗口兼容保存时保留旧清单其他窗口。 */ bool begin(const QString& sResultRootDirectory, const QString& sResultId, bool bPreserveExistingWindows = false, QString* pError = NULL); /** @brief 将一个 Manager 的完整 v3 载荷写入当前代次。 */ bool saveWindowGeneration(const QString& sWindowId, nmDataAnalyzeManager* pDataManager, QString* pError = NULL); /** @brief 校验全部窗口后原子发布根清单并清理未引用旧代次。 */ bool commit(QString* pError = NULL); /** @brief 中止当前会话并删除尚未发布的本代次目录。 */ void abort(); /** @brief 返回会话是否已经开始且尚未结束。 */ bool isActive() const; /** @brief 返回本次保存生成的唯一代次标识。 */ QString generationId() const; /** @brief 返回成果根目录。 */ QString resultRootDirectory() const; /** @brief 从已发布根清单解析并校验指定窗口的主 JSON。 */ static bool resolveWindowMainJson( const QString& sResultRootDirectory, const QString& sWindowId, QString& sWindowDirectory, QString& sMainJsonPath, nmNumericalFileReference* pMainReference = NULL, QString* pError = NULL); /** * @brief 校验已发布根清单,并查询清单是否明确引用指定窗口。 * @param bContainsWindow 返回窗口是否存在;不存在不是成果损坏。 */ static bool containsPublishedWindow( const QString& sResultRootDirectory, const QString& sWindowId, bool& bContainsWindow, QString* pError = NULL); /** @brief 只校验根清单结构、窗口唯一性和全部主 JSON 哈希。 */ static bool validatePublishedManifest( const QString& sResultRootDirectory, QString* pError = NULL); private: /** @brief 禁止复制保存会话。 */ nmNumericalSaveSession(const nmNumericalSaveSession&); /** @brief 禁止赋值保存会话。 */ nmNumericalSaveSession& operator=(const nmNumericalSaveSession&); private: /** @brief 会话是否已开始。 */ bool m_bActive; /** @brief 根清单是否已经成功发布。 */ bool m_bCommitted; /** @brief 回滚清单失败时保留新代次,避免根清单形成悬空引用。 */ bool m_bKeepGenerationOnAbort; /** @brief 成果业务标识。 */ QString m_sResultId; /** @brief 成果根目录。 */ QString m_sResultRootDirectory; /** @brief 当前保存代次 UUID。 */ QString m_sGenerationId; /** @brief 当前代次的绝对目录。 */ QString m_sGenerationDirectory; /** @brief 按窗口标识保存的新旧主 JSON 引用。 */ QMap m_mapWindows; /** @brief 本轮已经写入并完成全引用链校验的窗口标识。 */ QSet m_setValidatedWindowIds; }; #endif // NMNUMERICALSAVESESSION_H