feat/object-selection-panels #4
|
|
@ -8,6 +8,7 @@
|
|||
#include <functional>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
namespace geopro::data::dto {
|
||||
|
||||
|
|
@ -235,4 +236,30 @@ std::vector<ExceptionRow> parseExceptions(const QJsonArray& arr) {
|
|||
return out;
|
||||
}
|
||||
|
||||
GroupedExceptions groupExceptionsByConsortium(const std::vector<ExceptionRow>& rows) {
|
||||
GroupedExceptions out;
|
||||
std::unordered_map<std::string, size_t> indexById; // consortiumId → out.consortia 下标
|
||||
for (const auto& r : rows) {
|
||||
if (r.consortiumId.empty()) {
|
||||
out.loose.push_back(r);
|
||||
continue;
|
||||
}
|
||||
auto it = indexById.find(r.consortiumId);
|
||||
if (it == indexById.end()) {
|
||||
ConsortiumGroup g;
|
||||
g.id = r.consortiumId;
|
||||
g.name = r.consortiumName;
|
||||
g.typeName = r.consortiumType;
|
||||
indexById.emplace(r.consortiumId, out.consortia.size());
|
||||
out.consortia.push_back(std::move(g));
|
||||
it = indexById.find(r.consortiumId);
|
||||
}
|
||||
ConsortiumGroup& g = out.consortia[it->second];
|
||||
if (g.name.empty() && !r.consortiumName.empty()) g.name = r.consortiumName;
|
||||
if (g.typeName.empty() && !r.consortiumType.empty()) g.typeName = r.consortiumType;
|
||||
g.exceptions.push_back(r);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace geopro::data::dto
|
||||
|
|
|
|||
|
|
@ -48,4 +48,8 @@ DynamicForm parseDynamicForm(const QJsonObject& data);
|
|||
// detailSummary 由 exceptionMarkTypeName/createTime/elevationList/remark 拼成可读多行串。
|
||||
std::vector<ExceptionRow> parseExceptions(const QJsonArray& arr);
|
||||
|
||||
// 把一个对象(TM)的异常行按 consortiumId 分组:同 id 归一组(组名/类型取首个非空);
|
||||
// consortiumId 空 → loose。保持首次出现顺序稳定。纯函数、可单测。
|
||||
GroupedExceptions groupExceptionsByConsortium(const std::vector<ExceptionRow>& rows);
|
||||
|
||||
} // namespace geopro::data::dto
|
||||
|
|
|
|||
|
|
@ -44,4 +44,13 @@ struct ExceptionRow {
|
|||
std::string consortiumId, consortiumName, consortiumType;
|
||||
std::string detailSummary;
|
||||
};
|
||||
|
||||
// 异常体分组(树中间层)+ 对象分组(树根层,对应一个被勾选 TM)。
|
||||
struct ConsortiumGroup { std::string id, name, typeName; std::vector<ExceptionRow> exceptions; };
|
||||
struct ObjectExceptionGroup {
|
||||
std::string objectId, objectName;
|
||||
std::vector<ConsortiumGroup> consortia;
|
||||
std::vector<ExceptionRow> looseExceptions;
|
||||
};
|
||||
struct GroupedExceptions { std::vector<ConsortiumGroup> consortia; std::vector<ExceptionRow> loose; };
|
||||
} // namespace geopro::data
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "dto/NavDto.hpp"
|
||||
|
||||
using namespace geopro::data;
|
||||
|
|
@ -262,3 +264,29 @@ TEST(NavDto, ParseExceptionsMapsFieldsAndSummary) {
|
|||
EXPECT_TRUE(rows[1].consortiumId.empty());
|
||||
EXPECT_NE(rows[1].detailSummary.find("手动"), std::string::npos);
|
||||
}
|
||||
|
||||
TEST(NavDto, GroupExceptionsByConsortiumSplitsLooseAndGroups) {
|
||||
std::vector<ExceptionRow> rows = {
|
||||
{ "e1","空洞A","空洞","t1","c1","体A","溶洞群","" },
|
||||
{ "e2","空洞B","空洞","t1","c1","","","" },
|
||||
{ "e3","裂隙X","裂隙","t1","","","","" },
|
||||
{ "e4","空洞C","空洞","t1","c2","体B","溶洞群","" },
|
||||
};
|
||||
const auto g = dto::groupExceptionsByConsortium(rows);
|
||||
ASSERT_EQ(g.consortia.size(), 2u);
|
||||
EXPECT_EQ(g.consortia[0].id, "c1");
|
||||
EXPECT_EQ(g.consortia[0].name, "体A");
|
||||
EXPECT_EQ(g.consortia[0].typeName, "溶洞群");
|
||||
ASSERT_EQ(g.consortia[0].exceptions.size(), 2u);
|
||||
EXPECT_EQ(g.consortia[1].id, "c2");
|
||||
ASSERT_EQ(g.loose.size(), 1u);
|
||||
EXPECT_EQ(g.loose[0].id, "e3");
|
||||
}
|
||||
|
||||
TEST(NavDto, GroupExceptionsAllLooseWhenNoConsortium) {
|
||||
std::vector<ExceptionRow> rows = {
|
||||
{ "e1","a","t","t1","","","","" }, { "e2","b","t","t1","","","","" } };
|
||||
const auto g = dto::groupExceptionsByConsortium(rows);
|
||||
EXPECT_TRUE(g.consortia.empty());
|
||||
EXPECT_EQ(g.loose.size(), 2u);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue