feat/vtk-3d-view #7
|
|
@ -4,6 +4,7 @@ add_library(geopro_data STATIC
|
|||
parse/SampleParsers.cpp
|
||||
repo/LocalSampleRepository.cpp
|
||||
repo/LocalSample3dRepository.cpp
|
||||
repo/DatasetFieldDictionary.cpp
|
||||
dto/NavDto.cpp
|
||||
dto/Vtk3dRequests.cpp
|
||||
dto/DatasetChartDto.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
#include "repo/DatasetFieldDictionary.hpp"
|
||||
#include <QJsonArray>
|
||||
|
||||
namespace geopro::data {
|
||||
|
||||
DsTypeFields parseFieldMapping(const QJsonObject& d) {
|
||||
DsTypeFields f;
|
||||
for (const QJsonValue& gv : d.value(QStringLiteral("formList")).toArray()) {
|
||||
for (const QJsonValue& vv : gv.toObject().value(QStringLiteral("values")).toArray()) {
|
||||
const QJsonObject fo = vv.toObject();
|
||||
const QString code = fo.value(QStringLiteral("fieldCode")).toString();
|
||||
const std::string cfid = fo.value(QStringLiteral("confFieldId")).toString().toStdString();
|
||||
if (code == QStringLiteral("arrayType")) {
|
||||
f.arrayTypeConfFieldId = cfid;
|
||||
for (const QJsonValue& ov : fo.value(QStringLiteral("optionsObject")).toArray()) {
|
||||
const QJsonObject oo = ov.toObject();
|
||||
f.arrayTypeLabels[oo.value(QStringLiteral("value")).toString().toStdString()] =
|
||||
oo.value(QStringLiteral("label")).toString().toStdString();
|
||||
}
|
||||
} else if (code == QStringLiteral("collectTime")) {
|
||||
f.collectTimeConfFieldId = cfid;
|
||||
}
|
||||
}
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
namespace {
|
||||
std::string propValue(const DsRow& row, const std::string& cfid) {
|
||||
if (cfid.empty()) return {};
|
||||
for (const auto& kv : row.properties)
|
||||
if (kv.confFieldId == cfid) return kv.value;
|
||||
return {};
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string arrayValueOf(const DsRow& row, const DsTypeFields& f) {
|
||||
return propValue(row, f.arrayTypeConfFieldId);
|
||||
}
|
||||
std::string collectTimeOf(const DsRow& row, const DsTypeFields& f) {
|
||||
return propValue(row, f.collectTimeConfFieldId);
|
||||
}
|
||||
|
||||
std::string arrayLabel(const DsTypeFields& f, const std::string& value) {
|
||||
const auto it = f.arrayTypeLabels.find(value);
|
||||
return it != f.arrayTypeLabels.end() ? it->second : value; // 缺失回退原值(spec §11)
|
||||
}
|
||||
|
||||
} // namespace geopro::data
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#pragma once
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <QJsonObject>
|
||||
#include "repo/RepoTypes.hpp"
|
||||
|
||||
namespace geopro::data {
|
||||
|
||||
// 某 dsType 的字段映射(spec §10)。
|
||||
struct DsTypeFields {
|
||||
std::string arrayTypeConfFieldId; // ds 行 properties 里装置类型项的 confFieldId
|
||||
std::string collectTimeConfFieldId; // 采集时间项的 confFieldId
|
||||
std::map<std::string, std::string> arrayTypeLabels; // value→中文(来自 optionsObject)
|
||||
};
|
||||
|
||||
// 纯函数:从 dsObject/dynamicForm 的 data 解析字段映射(formList → fieldCode==arrayType/collectTime)。
|
||||
DsTypeFields parseFieldMapping(const QJsonObject& dynamicFormData);
|
||||
|
||||
// ds 行的装置类型原始值:properties 中 confFieldId==arrayTypeConfFieldId 的 value(缺=空)。
|
||||
std::string arrayValueOf(const DsRow& row, const DsTypeFields& f);
|
||||
// ds 行的采集时间:properties 中 confFieldId==collectTimeConfFieldId 的 value(缺=空)。
|
||||
std::string collectTimeOf(const DsRow& row, const DsTypeFields& f);
|
||||
|
||||
// 装置类型 value→中文:命中 arrayTypeLabels 取中文,否则回退原值(spec §11 字典源待坐实时的安全退路)。
|
||||
std::string arrayLabel(const DsTypeFields& f, const std::string& value);
|
||||
|
||||
} // namespace geopro::data
|
||||
|
|
@ -43,6 +43,7 @@ target_sources(geopro_tests PRIVATE data/test_local_repo.cpp)
|
|||
target_sources(geopro_tests PRIVATE data/test_3d_repo.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_nav_dto.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_vtk3d_requests.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_dataset_field_dictionary.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_dataset_chart_dto.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_measurement_dto.cpp)
|
||||
target_sources(geopro_tests PRIVATE data/test_gr_dto.cpp)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <QJsonDocument>
|
||||
#include "repo/DatasetFieldDictionary.hpp"
|
||||
using namespace geopro::data;
|
||||
|
||||
namespace {
|
||||
DsTypeFields parse(const char* js) {
|
||||
return parseFieldMapping(QJsonDocument::fromJson(QByteArray(js)).object());
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST(ParseFieldMapping, ExtractsArrayTypeAndCollectTimeConfFieldIds) {
|
||||
const DsTypeFields f = parse(R"({"formList":[{"groupName":"基本信息","values":[
|
||||
{"confFieldId":"f_ct","fieldCode":"collectTime","fieldName":"采集时间","optionsObject":null},
|
||||
{"confFieldId":"f_at","fieldCode":"arrayType","fieldName":"装置类型","optionsObject":[
|
||||
{"label":"温纳-施伦贝尔排列","value":"v1"},{"label":"全梯度","value":"v2"}]}
|
||||
]}]})");
|
||||
EXPECT_EQ(f.arrayTypeConfFieldId, "f_at");
|
||||
EXPECT_EQ(f.collectTimeConfFieldId, "f_ct");
|
||||
ASSERT_EQ(f.arrayTypeLabels.count("v1"), 1u);
|
||||
EXPECT_EQ(f.arrayTypeLabels.at("v1"), "温纳-施伦贝尔排列");
|
||||
EXPECT_EQ(f.arrayTypeLabels.at("v2"), "全梯度");
|
||||
}
|
||||
|
||||
TEST(DatasetFieldDictionary, ArrayValueAndCollectTimeFromRow) {
|
||||
DsTypeFields f;
|
||||
f.arrayTypeConfFieldId = "f_at";
|
||||
f.collectTimeConfFieldId = "f_ct";
|
||||
DsRow row;
|
||||
row.properties = {{"f_at", "v2"}, {"f_ct", "2026-03-25 16:48:57"}, {"other", "x"}};
|
||||
EXPECT_EQ(arrayValueOf(row, f), "v2");
|
||||
EXPECT_EQ(collectTimeOf(row, f), "2026-03-25 16:48:57");
|
||||
}
|
||||
|
||||
TEST(DatasetFieldDictionary, MissingPropReturnsEmpty) {
|
||||
DsTypeFields f;
|
||||
f.arrayTypeConfFieldId = "f_at";
|
||||
DsRow row; // 无 properties
|
||||
EXPECT_EQ(arrayValueOf(row, f), "");
|
||||
}
|
||||
|
||||
TEST(DatasetFieldDictionary, ArrayLabelHitsAndFallsBackToRawValue) {
|
||||
DsTypeFields f;
|
||||
f.arrayTypeLabels = {{"v1", "温纳"}};
|
||||
EXPECT_EQ(arrayLabel(f, "v1"), "温纳");
|
||||
// spec §11:原始值不在 optionsObject 时回退显示原值(如实测 1429468249448449)。
|
||||
EXPECT_EQ(arrayLabel(f, "1429468249448449"), "1429468249448449");
|
||||
}
|
||||
Loading…
Reference in New Issue