237 lines
11 KiB
C++
237 lines
11 KiB
C++
#include "api/ApiDatasetRepository.hpp"
|
||
#include <stdexcept>
|
||
#include <QJsonArray>
|
||
#include <QJsonObject>
|
||
#include <QString>
|
||
#include <QUrl>
|
||
#include <QVariant>
|
||
#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;
|
||
};
|
||
// 网格数据加载结果:grid(rows) + 网格色阶(type2) + 异常。
|
||
struct GridParts {
|
||
geopro::core::Grid grid{1, 1}; // Grid 无默认构造;占位
|
||
geopro::core::ColorScale gridScale;
|
||
std::vector<geopro::core::Anomaly> anomalies;
|
||
};
|
||
|
||
// 失败判定(原 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<net::IApiCall*> 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<net::ApiResponse>& r) {
|
||
ChartParts p;
|
||
p.scatter = dto::parseScatterGraph(r[0].data);
|
||
p.scatterScale = dto::parseColorBar(r[1].data);
|
||
return p;
|
||
}
|
||
|
||
// 反演网格:index 0 = rows(GET,慢),1 = 色阶 type2(POST),2 = 异常(GET)。
|
||
net::ApiBatch* inversionGridBatch(net::ApiClient& api, const std::string& dsId) {
|
||
QList<net::IApiCall*> 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<net::ApiResponse>& 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());
|
||
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<net::IApiCall*> 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<net::IApiCall*> 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<net::IApiCall*> 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<net::ApiResponse>& 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<net::IApiCall*> 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<net::IApiCall*> 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<net::IApiCall*> 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<net::ApiResponse>& r) {
|
||
ChartParts p = parseScatterParts(r);
|
||
return QVariant::fromValue(core::ScatterPayload{p.scatter, p.scatterScale});
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeInversionGrid(const std::string& dsId) {
|
||
return new ApiDetailLoad(inversionGridBatch(api_, dsId), [](const QList<net::ApiResponse>& r) {
|
||
GridParts p = parseGridParts(r);
|
||
return QVariant::fromValue(core::ContourPayload{p.grid, p.gridScale, p.anomalies});
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeMeasurementScatter(const std::string& dsId) {
|
||
// index 0 = scatter/graph, 1 = colorBar(type3) → 离散上色的 ScatterPayload。
|
||
return new ApiDetailLoad(measurementScatterBatch(api_, dsId), [](const QList<net::ApiResponse>& 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<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseMeasurementTable(r[0].data));
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeGrBar(const std::string& dsId) {
|
||
return new ApiDetailLoad(grRowsBatch(api_, dsId), [](const QList<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseGrBar(grDataArray(r)));
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeGrRows(const std::string& dsId) {
|
||
return new ApiDetailLoad(grRowsBatch(api_, dsId), [](const QList<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseGrTable(grDataArray(r)));
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeTrajectoryRows(const std::string& dsId) {
|
||
return new ApiDetailLoad(trajectoryRowsBatch(api_, dsId), [](const QList<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseTrajectoryTable(r[0].data));
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeTrajectoryElevation(const std::string& dsId) {
|
||
return new ApiDetailLoad(trajectoryRowsBatch(api_, dsId), [](const QList<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseTrajectoryElevation(r[0].data));
|
||
});
|
||
}
|
||
|
||
DetailLoad* ApiDatasetRepository::makeTrajectoryMap(const std::string& dsId) {
|
||
return new ApiDetailLoad(trajectoryLineBatch(api_, dsId), [](const QList<net::ApiResponse>& 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<net::ApiResponse>& r) {
|
||
return QVariant::fromValue(dto::parseGridTable(r[0].data, pn, ps));
|
||
});
|
||
}
|
||
|
||
} // namespace geopro::data
|