#include "api/ApiDatasetRepository.hpp" #include #include #include #include #include #include #include "ApiClient.hpp" #include "ApiBatch.hpp" #include "api/DatasetLoadHandles.hpp" #include "dto/DatasetChartDto.hpp" #include "dto/GrMeasurementDto.hpp" #include "dto/GridDto.hpp" #include "dto/MeasurementDto.hpp" #include "dto/TrajectoryDto.hpp" #include "model/detail/DetailPayloads.hpp" namespace geopro::data { namespace { QString enc(const std::string& s) { return QString::fromUtf8(QUrl::toPercentEncoding(QString::fromStdString(s))); } // 解析中间态(仅本 .cpp 内部使用,故置匿名命名空间,避免对外双份表示)。 // 原数据加载结果:scatter + 散点色阶(type1)。 struct ChartParts { geopro::core::ScatterField scatter; geopro::core::ColorScale scatterScale; QString templateId; // 散点色阶模板 id(保存色阶回带,对照原版 lvlTemplateId) }; // 网格数据加载结果:grid(rows) + 网格色阶(type2) + 异常。 struct GridParts { geopro::core::Grid grid{1, 1}; // Grid 无默认构造;占位 geopro::core::ColorScale gridScale; std::vector anomalies; QString templateId; // 网格色阶模板 id(保存/覆盖回带,对照原版 lvlTemplateId) }; // 失败判定(原 must() 口径):业务码 != 200 或传输错误。 bool isFailure(const geopro::net::ApiResponse& r) { return r.code != 200 || !r.rawError.isEmpty(); } QJsonObject colorBody(const std::string& dsId, int type) { return QJsonObject{{"dsObjectId", QString::fromStdString(dsId)}, {"businessCode", ""}, {"type", type}}; } // ── 共享批次构造:唯一端点定义处,old/new 路径复用,避免双份解析逻辑。 ── // 反演原数据:index 0 = scatter(GET),1 = 散点色阶 type1(POST)。 net::ApiBatch* inversionScatterBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/inversion/getErtRawDataScatterGraph/%1").arg(enc(dsId))), api.postJsonAsync(QStringLiteral("/business/lvl/colorGradation/getDetail"), colorBody(dsId, 1)), }; return new net::ApiBatch(calls, &isFailure); } ChartParts parseScatterParts(const QList& r) { ChartParts p; p.scatter = dto::parseScatterGraph(r[0].data); p.scatterScale = dto::parseColorBar(r[1].data); p.templateId = r[1].data.value(QStringLiteral("templateId")).toVariant().toString(); return p; } // 反演网格:index 0 = rows(GET,慢),1 = 色阶 type2(POST),2 = 异常(GET)。 net::ApiBatch* inversionGridBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/inversion/rows/%1").arg(enc(dsId))), api.postJsonAsync(QStringLiteral("/business/lvl/colorGradation/getDetail"), colorBody(dsId, 2)), api.getAsync(QStringLiteral("/business/exception/queryException/%1").arg(enc(dsId))), }; return new net::ApiBatch(calls, &isFailure); } GridParts parseGridParts(const QList& r) { GridParts p; p.grid = dto::parseInversionGrid(r[0].data); p.gridScale = dto::parseColorBar(r[1].data); p.anomalies = dto::parseDatasetAnomalies(r[2].data.value(QStringLiteral("value")).toArray()); // 顶层 templateId(对照原版 lvlConfig?.templateId,与散点 parseScatterParts 同范式)。 p.templateId = r[1].data.value(QStringLiteral("templateId")).toVariant().toString(); return p; } // measurement 散点:index 0 = scatter/graph(GET,query 参数),1 = 色阶 type3(POST,businessCode=R0)。 net::ApiBatch* measurementScatterBatch(net::ApiClient& api, const std::string& dsId) { const QString did = enc(dsId); QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/measurement/scatter/graph?dsObjectId=%1&vFieldCode=").arg(did)), api.postJsonAsync(QStringLiteral("/business/lvl/colorGradation/getDetail"), QJsonObject{{"dsObjectId", QString::fromStdString(dsId)}, {"businessCode", "R0"}, {"type", 3}}), }; return new net::ApiBatch(calls, &isFailure); } // measurement 列表:单请求 measurement/rows(GET,query 参数)。 net::ApiBatch* measurementRowsBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/measurement/rows?dsObjectId=%1").arg(enc(dsId))), }; return new net::ApiBatch(calls, &isFailure); } // 接地电阻(gr):柱状图与列表同一端点 measurement/gr/rows(GET,query 参数)。 // 响应 data 是 JSON 数组 → ApiResponseParse 包成 {value:[...]},取 r[0].data.value("value").toArray()。 net::ApiBatch* grRowsBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/measurement/gr/rows?dsObjectId=%1").arg(enc(dsId))), }; return new net::ApiBatch(calls, &isFailure); } // gr 响应数组(包在 data.value 里)。 QJsonArray grDataArray(const QList& r) { return r[0].data.value(QStringLiteral("value")).toArray(); } // 轨迹(trajectory):列表与高程同一端点 trajectory/rows(GET,query 参数)。 // 响应 data = {rowList[40], gridHeaderDisplay[14], ...}。 net::ApiBatch* trajectoryRowsBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/trajectory/rows?dsObjectId=%1").arg(enc(dsId))), }; return new net::ApiBatch(calls, &isFailure); } // 轨迹地图:单请求 trajectory/line(GET,query 参数)。frontCrsCode=EPSG:4326(原版发 EPSG%3A4326, // 此处用 enc() 对整串 url 编码故 ':' → %3A)。响应 data = {electrodelList[...]}。 net::ApiBatch* trajectoryLineBatch(net::ApiClient& api, const std::string& dsId) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/trajectory/line?dsObjectId=%1&frontCrsCode=%2") .arg(enc(dsId), enc("EPSG:4326"))), }; return new net::ApiBatch(calls, &isFailure); } // dd_grid 白化数据列表(服务端分页):单请求 grid/rows(GET,query:dsObjectId/pageNo/pageSize)。 // 响应 data = {rowList[{x,y,id}], gridHeaderDisplay[x,y], total}。 net::ApiBatch* gridRowsBatch(net::ApiClient& api, const std::string& dsId, int pageNo, int pageSize) { QList calls{ api.getAsync(QStringLiteral("/business/dd/ert/grid/rows?dsObjectId=%1&pageNo=%2&pageSize=%3") .arg(enc(dsId)) .arg(pageNo) .arg(pageSize)), }; return new net::ApiBatch(calls, &isFailure); } } // namespace ApiDatasetRepository::ApiDatasetRepository(net::ApiClient& api) : api_(api) {} DetailLoad* ApiDatasetRepository::loadAsync(const std::string& loaderKey, const std::string& dsId, int pageNo, int pageSize) { if (loaderKey == "inversion.scatter") return makeInversionScatter(dsId); if (loaderKey == "inversion.grid") return makeInversionGrid(dsId); if (loaderKey == "ert_measurement.scatter") return makeMeasurementScatter(dsId); if (loaderKey == "ert_measurement.rows") return makeMeasurementRows(dsId); if (loaderKey == "gr.bar") return makeGrBar(dsId); if (loaderKey == "gr.rows") return makeGrRows(dsId); if (loaderKey == "traj.rows") return makeTrajectoryRows(dsId); if (loaderKey == "traj.elev") return makeTrajectoryElevation(dsId); if (loaderKey == "traj.map") return makeTrajectoryMap(dsId); if (loaderKey == "grid.rows") return makeGridRows(dsId, pageNo, pageSize); throw std::runtime_error("unknown loaderKey: " + loaderKey); } DetailLoad* ApiDatasetRepository::makeInversionScatter(const std::string& dsId) { // 复用同一批次 + 解析器,再映射为 ScatterPayload(不复制 JSON 解析逻辑)。 return new ApiDetailLoad(inversionScatterBatch(api_, dsId), [](const QList& r) { ChartParts p = parseScatterParts(r); core::ScatterPayload payload{p.scatter, p.scatterScale}; payload.templateId = p.templateId; // 色阶保存回带(对照原版 lvlTemplateId) return QVariant::fromValue(payload); }); } DetailLoad* ApiDatasetRepository::makeInversionGrid(const std::string& dsId) { return new ApiDetailLoad(inversionGridBatch(api_, dsId), [](const QList& r) { GridParts p = parseGridParts(r); core::ContourPayload payload{p.grid, p.gridScale, p.anomalies}; payload.templateId = p.templateId; // 色阶保存/覆盖回带(对照原版 lvlTemplateId) return QVariant::fromValue(payload); }); } DetailLoad* ApiDatasetRepository::makeMeasurementScatter(const std::string& dsId) { // index 0 = scatter/graph, 1 = colorBar(type3) → 离散上色的 ScatterPayload。 return new ApiDetailLoad(measurementScatterBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseMeasurementScatter(r[0].data, r[1].data)); }); } DetailLoad* ApiDatasetRepository::makeMeasurementRows(const std::string& dsId) { return new ApiDetailLoad(measurementRowsBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseMeasurementTable(r[0].data)); }); } DetailLoad* ApiDatasetRepository::makeGrBar(const std::string& dsId) { return new ApiDetailLoad(grRowsBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseGrBar(grDataArray(r))); }); } DetailLoad* ApiDatasetRepository::makeGrRows(const std::string& dsId) { return new ApiDetailLoad(grRowsBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseGrTable(grDataArray(r))); }); } DetailLoad* ApiDatasetRepository::makeTrajectoryRows(const std::string& dsId) { return new ApiDetailLoad(trajectoryRowsBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseTrajectoryTable(r[0].data)); }); } DetailLoad* ApiDatasetRepository::makeTrajectoryElevation(const std::string& dsId) { return new ApiDetailLoad(trajectoryRowsBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseTrajectoryElevation(r[0].data)); }); } DetailLoad* ApiDatasetRepository::makeTrajectoryMap(const std::string& dsId) { return new ApiDetailLoad(trajectoryLineBatch(api_, dsId), [](const QList& r) { return QVariant::fromValue(dto::parseTrajectoryMap(r[0].data)); }); } DetailLoad* ApiDatasetRepository::makeGridRows(const std::string& dsId, int pageNo, int pageSize) { // 解析默认值:pageNo<=0→1,pageSize<=0→50(原版默认每页 50 条),再传入 URL 与解析器 // (保证 URL 参数与「序号」列偏移一致)。 const int pn = pageNo > 0 ? pageNo : 1; const int ps = pageSize > 0 ? pageSize : 50; return new ApiDetailLoad(gridRowsBatch(api_, dsId, pn, ps), [pn, ps](const QList& r) { return QVariant::fromValue(dto::parseGridTable(r[0].data, pn, ps)); }); } } // namespace geopro::data