feat(data): DatasetFieldDictionary 解析 arrayType/collectTime 映射+装置字典(纯函数)
This commit is contained in:
parent
1978a31fa7
commit
c5b3907fad
|
|
@ -4,6 +4,7 @@ add_library(geopro_data STATIC
|
||||||
parse/SampleParsers.cpp
|
parse/SampleParsers.cpp
|
||||||
repo/LocalSampleRepository.cpp
|
repo/LocalSampleRepository.cpp
|
||||||
repo/LocalSample3dRepository.cpp
|
repo/LocalSample3dRepository.cpp
|
||||||
|
repo/DatasetFieldDictionary.cpp
|
||||||
dto/NavDto.cpp
|
dto/NavDto.cpp
|
||||||
dto/Vtk3dRequests.cpp
|
dto/Vtk3dRequests.cpp
|
||||||
dto/DatasetChartDto.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_3d_repo.cpp)
|
||||||
target_sources(geopro_tests PRIVATE data/test_nav_dto.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_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_dataset_chart_dto.cpp)
|
||||||
target_sources(geopro_tests PRIVATE data/test_measurement_dto.cpp)
|
target_sources(geopro_tests PRIVATE data/test_measurement_dto.cpp)
|
||||||
target_sources(geopro_tests PRIVATE data/test_gr_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