From fa4bbf08b3f288f731faac43d2edb7287f37e3cb Mon Sep 17 00:00:00 2001 From: gaozheng Date: Tue, 9 Jun 2026 11:40:40 +0800 Subject: [PATCH] =?UTF-8?q?feat(data):=20ApiProjectRepository=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=205=20=E4=B8=AA=E5=AF=BC=E8=88=AA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/data/CMakeLists.txt | 3 +- src/data/api/ApiProjectRepository.cpp | 66 +++++++++++++++++++++++++++ src/data/api/ApiProjectRepository.hpp | 23 ++++++++++ 3 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 src/data/api/ApiProjectRepository.cpp create mode 100644 src/data/api/ApiProjectRepository.hpp diff --git a/src/data/CMakeLists.txt b/src/data/CMakeLists.txt index b513412..803e557 100644 --- a/src/data/CMakeLists.txt +++ b/src/data/CMakeLists.txt @@ -3,7 +3,8 @@ find_package(Qt6 COMPONENTS Core REQUIRED) add_library(geopro_data STATIC parse/SampleParsers.cpp repo/LocalSampleRepository.cpp - dto/NavDto.cpp) + dto/NavDto.cpp + api/ApiProjectRepository.cpp) target_include_directories(geopro_data PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(geopro_data PUBLIC geopro_core geopro_net Qt6::Core PRIVATE nlohmann_json::nlohmann_json) target_compile_features(geopro_data PUBLIC cxx_std_17) diff --git a/src/data/api/ApiProjectRepository.cpp b/src/data/api/ApiProjectRepository.cpp new file mode 100644 index 0000000..39f383d --- /dev/null +++ b/src/data/api/ApiProjectRepository.cpp @@ -0,0 +1,66 @@ +#include "api/ApiProjectRepository.hpp" + +#include +#include +#include + +#include "ApiClient.hpp" +#include "dto/NavDto.hpp" + +namespace geopro::data { + +namespace { +constexpr int kCodeSuccess = 200; + +bool ok(const net::ApiResponse& r) { return r.code == kCodeSuccess; } + +std::string errorOf(const net::ApiResponse& r, const char* fallback) { + if (!r.msg.isEmpty()) return r.msg.toStdString(); + if (!r.rawError.isEmpty()) return r.rawError.toStdString(); + return fallback; +} +} // namespace + +ApiProjectRepository::ApiProjectRepository(net::ApiClient& api) : api_(api) {} + +RepoResult> ApiProjectRepository::listWorkspaces() { + const net::ApiResponse r = + api_.get(QStringLiteral("/business/system/tenant/enterprise/joined/list")); + if (!ok(r)) return {false, {}, errorOf(r, "listWorkspaces failed")}; + return {true, dto::parseWorkspaces(r.data.value(QStringLiteral("value")).toArray()), {}}; +} + +RepoResult ApiProjectRepository::switchWorkspace(const std::string& tenantId) { + const QString path = + QStringLiteral("/business/system/tenant/enterprise/switch/%1").arg(QString::fromStdString(tenantId)); + const net::ApiResponse r = api_.postJson(path, QJsonObject{}); + if (!ok(r)) return {false, false, errorOf(r, "switchWorkspace failed")}; + return {true, true, {}}; +} + +RepoResult> ApiProjectRepository::listProjects( + const std::string& lastProjectId) { + const QString path = QStringLiteral("/business/project/queryByUser?lastProjectId=%1") + .arg(QString::fromStdString(lastProjectId)); + const net::ApiResponse r = api_.get(path); + if (!ok(r)) return {false, {}, errorOf(r, "listProjects failed")}; + return {true, dto::parseProjects(r.data).projects, {}}; +} + +RepoResult> ApiProjectRepository::loadStructure(const std::string& projectId) { + const QJsonObject body{{QStringLiteral("projectId"), QString::fromStdString(projectId)}}; + const net::ApiResponse r = + api_.postJson(QStringLiteral("/business/projectWorkbench/queryProjectStruct"), body); + if (!ok(r)) return {false, {}, errorOf(r, "loadStructure failed")}; + return {true, dto::parseStructNodes(r.data.value(QStringLiteral("projectStructList")).toArray()), {}}; +} + +RepoResult> ApiProjectRepository::loadDatasetsOfTm(const std::string& tmObjectId) { + const QString path = QStringLiteral("/business/projectWorkbench/queryDsByTmObjectId/%1") + .arg(QString::fromStdString(tmObjectId)); + const net::ApiResponse r = api_.get(path); + if (!ok(r)) return {false, {}, errorOf(r, "loadDatasetsOfTm failed")}; + return {true, dto::parseDatasets(r.data.value(QStringLiteral("value")).toArray()), {}}; +} + +} // namespace geopro::data diff --git a/src/data/api/ApiProjectRepository.hpp b/src/data/api/ApiProjectRepository.hpp new file mode 100644 index 0000000..b52ec51 --- /dev/null +++ b/src/data/api/ApiProjectRepository.hpp @@ -0,0 +1,23 @@ +#pragma once +#include "repo/IProjectRepository.hpp" + +namespace geopro::net { class ApiClient; } + +namespace geopro::data { + +// 用共享会话 ApiClient 实现导航仓储(同步阻塞)。token 由调用方注入 ApiClient。 +class ApiProjectRepository : public IProjectRepository { +public: + explicit ApiProjectRepository(net::ApiClient& api); + + RepoResult> listWorkspaces() override; + RepoResult switchWorkspace(const std::string& tenantId) override; + RepoResult> listProjects(const std::string& lastProjectId) override; + RepoResult> loadStructure(const std::string& projectId) override; + RepoResult> loadDatasetsOfTm(const std::string& tmObjectId) override; + +private: + net::ApiClient& api_; +}; + +} // namespace geopro::data