feat/object-selection-panels #4
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <QJsonValue>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
|
||||
|
|
@ -154,4 +155,41 @@ std::vector<StructTreeNode> buildStructTree(const std::vector<StructNode>& 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<QJsonObject> gv;
|
||||
gv.reserve(static_cast<size_t>(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<QJsonObject> fv;
|
||||
fv.reserve(static_cast<size_t>(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
|
||||
|
|
|
|||
|
|
@ -38,4 +38,9 @@ struct StructTreeNode {
|
|||
};
|
||||
std::vector<StructTreeNode> buildStructTree(const std::vector<StructNode>& flat);
|
||||
|
||||
// DynamicFormVO 对象 → DynamicForm:合并 formList(字段定义) + properties(值)。
|
||||
// 组按 groupSort、字段按 displaySort 排序;值取 properties[fieldCode](缺失→空串)。
|
||||
// 表头 name 取 data["name"]。
|
||||
DynamicForm parseDynamicForm(const QJsonObject& data);
|
||||
|
||||
} // namespace geopro::data::dto
|
||||
|
|
|
|||
|
|
@ -32,4 +32,9 @@ struct ProjectListPage { std::vector<ProjectSummary> 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<DynamicFormField> fields; };
|
||||
struct DynamicForm { std::string name; std::vector<DynamicFormGroup> groups; };
|
||||
} // namespace geopro::data
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue