diff --git a/src/data/dto/NavDto.cpp b/src/data/dto/NavDto.cpp index ef2adcd..f4cf365 100644 --- a/src/data/dto/NavDto.cpp +++ b/src/data/dto/NavDto.cpp @@ -2,6 +2,7 @@ #include +#include #include #include @@ -154,4 +155,41 @@ std::vector buildStructTree(const std::vector& flat) return build(std::string(), true); } +DynamicForm parseDynamicForm(const QJsonObject& data) { + DynamicForm form; + form.name = str(data, "name"); + const QJsonObject props = data.value(QStringLiteral("properties")).toObject(); + + QJsonArray groups = data.value(QStringLiteral("formList")).toArray(); + std::vector gv; + gv.reserve(static_cast(groups.size())); + for (const QJsonValue& g : groups) gv.push_back(g.toObject()); + std::stable_sort(gv.begin(), gv.end(), [](const QJsonObject& a, const QJsonObject& b) { + return a.value(QStringLiteral("groupSort")).toInt() < + b.value(QStringLiteral("groupSort")).toInt(); + }); + + for (const QJsonObject& g : gv) { + DynamicFormGroup group; + group.name = str(g, "groupName"); + QJsonArray vals = g.value(QStringLiteral("values")).toArray(); + std::vector fv; + fv.reserve(static_cast(vals.size())); + for (const QJsonValue& v : vals) fv.push_back(v.toObject()); + std::stable_sort(fv.begin(), fv.end(), [](const QJsonObject& a, const QJsonObject& b) { + return a.value(QStringLiteral("displaySort")).toInt() < + b.value(QStringLiteral("displaySort")).toInt(); + }); + for (const QJsonObject& f : fv) { + DynamicFormField field; + field.name = str(f, "fieldName"); + const QString code = f.value(QStringLiteral("fieldCode")).toString(); + field.value = props.value(code).toVariant().toString().toStdString(); + group.fields.push_back(std::move(field)); + } + form.groups.push_back(std::move(group)); + } + return form; +} + } // namespace geopro::data::dto diff --git a/src/data/dto/NavDto.hpp b/src/data/dto/NavDto.hpp index 6a3c2b7..ac3ad91 100644 --- a/src/data/dto/NavDto.hpp +++ b/src/data/dto/NavDto.hpp @@ -38,4 +38,9 @@ struct StructTreeNode { }; std::vector buildStructTree(const std::vector& flat); +// DynamicFormVO 对象 → DynamicForm:合并 formList(字段定义) + properties(值)。 +// 组按 groupSort、字段按 displaySort 排序;值取 properties[fieldCode](缺失→空串)。 +// 表头 name 取 data["name"]。 +DynamicForm parseDynamicForm(const QJsonObject& data); + } // namespace geopro::data::dto diff --git a/src/data/repo/RepoTypes.hpp b/src/data/repo/RepoTypes.hpp index 1bb99a6..bc31bfa 100644 --- a/src/data/repo/RepoTypes.hpp +++ b/src/data/repo/RepoTypes.hpp @@ -32,4 +32,9 @@ struct ProjectListPage { std::vector rows; int total = 0; }; // 项目结构扁平节点(仅 GS / TM)。客户端按 parentId 建树,叶子=TM。 struct StructNode { std::string id, name, parentId, typeName, confCode; int type = 0; }; + +// 动态表单(GS/TM/DS 详情统一模型)。值已与字段定义合并、已按 sort 排好序。 +struct DynamicFormField { std::string name, value; }; +struct DynamicFormGroup { std::string name; std::vector fields; }; +struct DynamicForm { std::string name; std::vector groups; }; } // namespace geopro::data diff --git a/tests/data/test_nav_dto.cpp b/tests/data/test_nav_dto.cpp index 2f0e281..03d5c36 100644 --- a/tests/data/test_nav_dto.cpp +++ b/tests/data/test_nav_dto.cpp @@ -201,3 +201,37 @@ TEST(NavDto, ParseProjectPageAndTypes) { EXPECT_EQ(types[0].id, "t1"); EXPECT_EQ(types[0].name, "全量类型"); } + +TEST(NavDto, ParseDynamicFormMergesFieldsValuesAndSorts) { + const auto data = objOf(R"({ + "name": "测线1", + "properties": { "depth": "120", "len": "300", "owner": "张三" }, + "formList": [ + { "groupName": "几何", "groupSort": 1, "values": [ + { "fieldName": "长度", "fieldCode": "len", "displaySort": 2 }, + { "fieldName": "深度", "fieldCode": "depth", "displaySort": 1 } + ]}, + { "groupName": "归属", "groupSort": 2, "values": [ + { "fieldName": "负责人", "fieldCode": "owner", "displaySort": 1 }, + { "fieldName": "缺失项", "fieldCode": "nope", "displaySort": 2 } + ]} + ] + })"); + const auto form = dto::parseDynamicForm(data); + EXPECT_EQ(form.name, "测线1"); + ASSERT_EQ(form.groups.size(), 2u); + EXPECT_EQ(form.groups[0].name, "几何"); + ASSERT_EQ(form.groups[0].fields.size(), 2u); + EXPECT_EQ(form.groups[0].fields[0].name, "深度"); + EXPECT_EQ(form.groups[0].fields[0].value, "120"); + EXPECT_EQ(form.groups[0].fields[1].name, "长度"); + EXPECT_EQ(form.groups[0].fields[1].value, "300"); + EXPECT_EQ(form.groups[1].fields[1].value, ""); +} + +TEST(NavDto, ParseDynamicFormEmptyFormListYieldsNoGroups) { + const auto data = objOf(R"({ "name":"空", "properties":{}, "formList":[] })"); + const auto form = dto::parseDynamicForm(data); + EXPECT_EQ(form.name, "空"); + EXPECT_TRUE(form.groups.empty()); +}