From acf71bdaef5696f3d8321b371e28d86e5334fcc3 Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 10 Jun 2026 20:03:28 +0800 Subject: [PATCH] =?UTF-8?q?feat(data):=20parseExceptions=20=E6=98=A0?= =?UTF-8?q?=E5=B0=84=E5=BC=82=E5=B8=B8=E5=AD=97=E6=AE=B5=20+=20=E8=AF=A6?= =?UTF-8?q?=E6=83=85=E6=91=98=E8=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/dto/NavDto.cpp | 43 +++++++++++++++++++++++++++++++++++++ src/data/dto/NavDto.hpp | 5 +++++ src/data/repo/RepoTypes.hpp | 7 ++++++ tests/data/test_nav_dto.cpp | 27 +++++++++++++++++++++++ 4 files changed, 82 insertions(+) diff --git a/src/data/dto/NavDto.cpp b/src/data/dto/NavDto.cpp index f4cf365..91dec64 100644 --- a/src/data/dto/NavDto.cpp +++ b/src/data/dto/NavDto.cpp @@ -1,9 +1,12 @@ #include "dto/NavDto.hpp" #include +#include +#include #include #include +#include #include namespace geopro::data::dto { @@ -28,6 +31,19 @@ ProjectSummary parseProjectItem(const QJsonObject& o) { p.status = o.value(QStringLiteral("status")).toInt(); return p; } + +// elevationList 极值拼 "高程 min~max m";空返回空串。 +std::string elevationSummary(const QJsonArray& el) { + if (el.isEmpty()) return {}; + double lo = std::numeric_limits::max(), hi = -std::numeric_limits::max(); + for (const QJsonValue& v : el) { + const double d = v.toDouble(); + if (d < lo) lo = d; + if (d > hi) hi = d; + } + return QStringLiteral("高程 %1~%2m") + .arg(lo, 0, 'f', 0).arg(hi, 0, 'f', 0).toStdString(); +} } // namespace std::vector parseWorkspaces(const QJsonArray& arr) { @@ -192,4 +208,31 @@ DynamicForm parseDynamicForm(const QJsonObject& data) { return form; } +std::vector parseExceptions(const QJsonArray& arr) { + std::vector out; + out.reserve(static_cast(arr.size())); + for (const QJsonValue& v : arr) { + const QJsonObject o = v.toObject(); + ExceptionRow r; + r.id = str(o, "id"); + r.name = str(o, "exceptionName"); + r.typeName = str(o, "exceptionTypeName"); + r.createTime = str(o, "createTime"); + r.consortiumId = str(o, "consortiumId"); + r.consortiumName = str(o, "consortiumName"); + r.consortiumType = str(o, "consortiumType"); + QStringList lines; + lines << QStringLiteral("标记 %1 · 创建 %2") + .arg(QString::fromStdString(str(o, "exceptionMarkTypeName"))) + .arg(QString::fromStdString(r.createTime)); + const std::string elev = elevationSummary(o.value(QStringLiteral("elevationList")).toArray()); + if (!elev.empty()) lines << QString::fromStdString(elev); + const std::string remark = str(o, "remark"); + if (!remark.empty()) lines << QStringLiteral("备注 %1").arg(QString::fromStdString(remark)); + r.detailSummary = lines.join(QLatin1Char('\n')).toStdString(); + out.push_back(std::move(r)); + } + return out; +} + } // namespace geopro::data::dto diff --git a/src/data/dto/NavDto.hpp b/src/data/dto/NavDto.hpp index ac3ad91..1c587eb 100644 --- a/src/data/dto/NavDto.hpp +++ b/src/data/dto/NavDto.hpp @@ -43,4 +43,9 @@ std::vector buildStructTree(const std::vector& flat) // 表头 name 取 data["name"]。 DynamicForm parseDynamicForm(const QJsonObject& data); +// ExceptionVO 数组 → [ExceptionRow]。字段:id、name=exceptionName、typeName=exceptionTypeName、 +// createTime;consortium* 取自 consortiumId/consortiumName/consortiumType(来源待 live 验证); +// detailSummary 由 exceptionMarkTypeName/createTime/elevationList/remark 拼成可读多行串。 +std::vector parseExceptions(const QJsonArray& arr); + } // namespace geopro::data::dto diff --git a/src/data/repo/RepoTypes.hpp b/src/data/repo/RepoTypes.hpp index bc31bfa..5210d3c 100644 --- a/src/data/repo/RepoTypes.hpp +++ b/src/data/repo/RepoTypes.hpp @@ -37,4 +37,11 @@ struct StructNode { std::string id, name, parentId, typeName, confCode; int type struct DynamicFormField { std::string name, value; }; struct DynamicFormGroup { std::string name; std::vector fields; }; struct DynamicForm { std::string name; std::vector groups; }; + +// 异常(树叶,本轮只读)。consortium* 空 = 独立异常;detailSummary = 详情展开内联显示。 +struct ExceptionRow { + std::string id, name, typeName, createTime; + std::string consortiumId, consortiumName, consortiumType; + std::string detailSummary; +}; } // namespace geopro::data diff --git a/tests/data/test_nav_dto.cpp b/tests/data/test_nav_dto.cpp index 03d5c36..1eda3c2 100644 --- a/tests/data/test_nav_dto.cpp +++ b/tests/data/test_nav_dto.cpp @@ -235,3 +235,30 @@ TEST(NavDto, ParseDynamicFormEmptyFormListYieldsNoGroups) { EXPECT_EQ(form.name, "空"); EXPECT_TRUE(form.groups.empty()); } + +TEST(NavDto, ParseExceptionsMapsFieldsAndSummary) { + const auto arr = arrOf(R"([ + { "id":"e1", "exceptionName":"空洞A", "exceptionTypeName":"空洞", + "exceptionMarkTypeName":"自动", "createTime":"2026-06-01", + "elevationList":[120.0, 80.0, 100.0], "remark":"复核中", + "consortiumId":"c1", "consortiumName":"体A", "consortiumType":"溶洞群" }, + { "id":"e2", "exceptionName":"裂隙B", "exceptionTypeName":"裂隙", + "exceptionMarkTypeName":"手动", "createTime":"2026-06-02", + "elevationList":[], "remark":"" } + ])"); + const auto rows = dto::parseExceptions(arr); + ASSERT_EQ(rows.size(), 2u); + EXPECT_EQ(rows[0].id, "e1"); + EXPECT_EQ(rows[0].name, "空洞A"); + EXPECT_EQ(rows[0].typeName, "空洞"); + EXPECT_EQ(rows[0].consortiumId, "c1"); + EXPECT_EQ(rows[0].consortiumName, "体A"); + EXPECT_EQ(rows[0].consortiumType, "溶洞群"); + EXPECT_NE(rows[0].detailSummary.find("自动"), std::string::npos); + EXPECT_NE(rows[0].detailSummary.find("2026-06-01"), std::string::npos); + EXPECT_NE(rows[0].detailSummary.find("80"), std::string::npos); + EXPECT_NE(rows[0].detailSummary.find("120"), std::string::npos); + EXPECT_NE(rows[0].detailSummary.find("复核中"), std::string::npos); + EXPECT_TRUE(rows[1].consortiumId.empty()); + EXPECT_NE(rows[1].detailSummary.find("手动"), std::string::npos); +}