综合平台编程器项目的远程存储
Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 

182 righe
4.8 KiB

  1. #include "project_service.h"
  2. #include <algorithm>
  3. #include <chrono>
  4. #include <cctype>
  5. #include <random>
  6. #include <sstream>
  7. #include <utility>
  8. namespace integrated_platform::services {
  9. namespace {
  10. // 使用高精度时间戳和随机值生成工程标识
  11. std::string generateProjectId()
  12. {
  13. const auto timestamp = static_cast<unsigned long long>(
  14. std::chrono::high_resolution_clock::now().time_since_epoch().count());
  15. std::random_device random_device;
  16. const auto random_value = static_cast<unsigned long long>(random_device());
  17. std::ostringstream stream;
  18. stream << "project-" << std::hex << timestamp << '-' << random_value;
  19. return stream.str();
  20. }
  21. } // namespace
  22. ProjectService::ProjectService(domain::ProjectStorage &storage)
  23. : storage_(storage),
  24. project_(makeNewProject("Untitled"))
  25. {
  26. }
  27. const domain::Project &ProjectService::project() const
  28. {
  29. return project_;
  30. }
  31. domain::Project &ProjectService::editProject()
  32. {
  33. modified_ = true;
  34. return project_;
  35. }
  36. const std::string &ProjectService::currentFilePath() const
  37. {
  38. return current_file_path_;
  39. }
  40. bool ProjectService::hasCurrentFile() const
  41. {
  42. return !current_file_path_.empty();
  43. }
  44. bool ProjectService::isModified() const
  45. {
  46. return modified_;
  47. }
  48. ProjectOperationResult ProjectService::createNewProject(const std::string &name)
  49. {
  50. if (isBlank(name))
  51. {
  52. return {false,
  53. ProjectServiceError::InvalidProjectName,
  54. domain::ProjectStorageError::None,
  55. "project name must not be empty"};
  56. }
  57. // 新工程创建成功后清除原文件关联,并标记为待保存
  58. project_ = makeNewProject(name);
  59. current_file_path_.clear();
  60. modified_ = true;
  61. return {true, ProjectServiceError::None, domain::ProjectStorageError::None, {}};
  62. }
  63. ProjectOperationResult ProjectService::save()
  64. {
  65. if (!hasCurrentFile())
  66. {
  67. return {false,
  68. ProjectServiceError::FilePathRequired,
  69. domain::ProjectStorageError::None,
  70. "project file path is required"};
  71. }
  72. return saveAs(current_file_path_);
  73. }
  74. ProjectOperationResult ProjectService::saveAs(const std::string &file_path)
  75. {
  76. if (isBlank(file_path))
  77. {
  78. return {false,
  79. ProjectServiceError::FilePathRequired,
  80. domain::ProjectStorageError::None,
  81. "project file path is required"};
  82. }
  83. std::string validation_error;
  84. if (!project_.validate(&validation_error))
  85. {
  86. return {false,
  87. ProjectServiceError::InvalidProject,
  88. domain::ProjectStorageError::InvalidProject,
  89. validation_error};
  90. }
  91. // 先完成领域校验,避免将非法工程交给存储层
  92. const domain::ProjectSaveResult result = storage_.save(project_, file_path);
  93. if (!result.succeeded)
  94. {
  95. return storageFailure(result.error, result.message);
  96. }
  97. // 只有存储成功后才更新文件关联和未保存状态
  98. current_file_path_ = file_path;
  99. modified_ = false;
  100. return {true, ProjectServiceError::None, domain::ProjectStorageError::None, {}};
  101. }
  102. ProjectOperationResult ProjectService::load(const std::string &file_path)
  103. {
  104. if (isBlank(file_path))
  105. {
  106. return {false,
  107. ProjectServiceError::FilePathRequired,
  108. domain::ProjectStorageError::None,
  109. "project file path is required"};
  110. }
  111. domain::ProjectLoadResult result = storage_.load(file_path);
  112. if (!result.succeeded)
  113. {
  114. return storageFailure(result.error, result.message);
  115. }
  116. std::string validation_error;
  117. if (!result.project.validate(&validation_error))
  118. {
  119. return {false,
  120. ProjectServiceError::InvalidProject,
  121. domain::ProjectStorageError::InvalidProject,
  122. validation_error};
  123. }
  124. // 文件读取和领域校验均成功后,才替换当前工程状态
  125. project_ = std::move(result.project);
  126. current_file_path_ = file_path;
  127. modified_ = false;
  128. return {true, ProjectServiceError::None, domain::ProjectStorageError::None, {}};
  129. }
  130. domain::Project ProjectService::makeNewProject(const std::string &name)
  131. {
  132. domain::Project project;
  133. project.metadata.id = generateProjectId();
  134. project.metadata.name = name;
  135. project.metadata.formatVersion = "1.0";
  136. return project;
  137. }
  138. bool ProjectService::isBlank(const std::string &value)
  139. {
  140. return value.empty()
  141. || std::all_of(
  142. value.cbegin(),
  143. value.cend(),
  144. [](unsigned char character)
  145. {
  146. return std::isspace(character) != 0;
  147. });
  148. }
  149. ProjectOperationResult ProjectService::storageFailure(
  150. domain::ProjectStorageError error, const std::string &message)
  151. {
  152. return {false, ProjectServiceError::StorageFailure, error, message};
  153. }
  154. } // namespace integrated_platform::services