综合平台编程器项目的远程存储
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

122 行
3.9 KiB

  1. #include "alarm_editor_service.h"
  2. #include "project_service.h"
  3. #include "domain/project_limits.h"
  4. #include <algorithm>
  5. namespace {
  6. // 创建统一的报警编辑失败结果
  7. AlarmEditorResult failure(AlarmEditorError error, const std::string &message)
  8. {
  9. return {false, error, message, {}};
  10. }
  11. } // namespace
  12. // 保存工程服务引用,后续编辑都通过该服务修改当前工程
  13. AlarmEditorService::AlarmEditorService(ProjectService &project_service)
  14. : project_service_(project_service)
  15. {
  16. }
  17. // 返回当前工程持有的报警定义列表
  18. const std::vector<AlarmDefinition> &AlarmEditorService::definitions() const
  19. {
  20. return project_service_.project().alarmDefinitions;
  21. }
  22. // 按稳定 ID 查找报警定义,找不到时返回空指针
  23. const AlarmDefinition *AlarmEditorService::findDefinition(
  24. const std::string &id) const
  25. {
  26. const auto &definitions = project_service_.project().alarmDefinitions;
  27. const auto definition = std::find_if(
  28. definitions.cbegin(), definitions.cend(),
  29. [&id](const AlarmDefinition &candidate) { return candidate.id == id; });
  30. return definition == definitions.cend() ? nullptr : &*definition;
  31. }
  32. // 校验数量和定义内容后添加一条带唯一 ID 的报警定义
  33. AlarmEditorResult AlarmEditorService::addDefinition(
  34. const AlarmDefinition &definition)
  35. {
  36. const std::size_t maximum =
  37. project_service_.projectLimits().maximumAlarmDefinitions;
  38. if (definitions().size() >= maximum)
  39. {
  40. return failure(
  41. AlarmEditorError::InvalidDefinition,
  42. "当前配置最多允许 " + std::to_string(maximum) + " 条报警定义");
  43. }
  44. AlarmDefinition candidate = definition;
  45. candidate.id = makeUniqueId();
  46. std::string error;
  47. if (!candidate.validate(&error))
  48. {
  49. return failure(AlarmEditorError::InvalidDefinition, error);
  50. }
  51. project_service_.editProject().alarmDefinitions.push_back(candidate);
  52. return {true, AlarmEditorError::None, {}, candidate.id};
  53. }
  54. // 校验候选定义后整体替换指定 ID 的报警定义
  55. AlarmEditorResult AlarmEditorService::updateDefinition(
  56. const std::string &id, const AlarmDefinition &definition)
  57. {
  58. if (findDefinition(id) == nullptr)
  59. {
  60. return failure(AlarmEditorError::NotFound, "未找到报警定义");
  61. }
  62. AlarmDefinition candidate = definition;
  63. candidate.id = id;
  64. std::string error;
  65. if (!candidate.validate(&error))
  66. {
  67. return failure(AlarmEditorError::InvalidDefinition, error);
  68. }
  69. Project &project = project_service_.editProject();
  70. auto editable = std::find_if(
  71. project.alarmDefinitions.begin(), project.alarmDefinitions.end(),
  72. [&id](const AlarmDefinition &item) { return item.id == id; });
  73. *editable = std::move(candidate);
  74. return {true, AlarmEditorError::None, {}, id};
  75. }
  76. // 删除指定 ID 的报警定义
  77. AlarmEditorResult AlarmEditorService::removeDefinition(const std::string &id)
  78. {
  79. if (findDefinition(id) == nullptr)
  80. {
  81. return failure(AlarmEditorError::NotFound, "未找到报警定义");
  82. }
  83. Project &project = project_service_.editProject();
  84. // remove_if 先把目标项移到逻辑末尾,再由 erase 真正缩短容器
  85. project.alarmDefinitions.erase(
  86. std::remove_if(
  87. project.alarmDefinitions.begin(), project.alarmDefinitions.end(),
  88. [&id](const AlarmDefinition &definition)
  89. {
  90. return definition.id == id;
  91. }),
  92. project.alarmDefinitions.end());
  93. return {true, AlarmEditorError::None, {}, id};
  94. }
  95. // 从 alarm-1 开始递增查找当前工程内可用的 ID
  96. std::string AlarmEditorService::makeUniqueId() const
  97. {
  98. int suffix = 1;
  99. while (true)
  100. {
  101. const std::string candidate = "alarm-" + std::to_string(suffix);
  102. if (findDefinition(candidate) == nullptr)
  103. {
  104. return candidate;
  105. }
  106. ++suffix;
  107. }
  108. }