#include "api/ApiProjectRepository.hpp" #include #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; } // 后端 id 进 URL 前做百分号编码(不可信外部数据:防 ? # & / 空格 破坏路径/查询)。 QString enc(const std::string& s) { return QString::fromUtf8(QUrl::toPercentEncoding(QString::fromStdString(s))); } } // 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(enc(tenantId)); const net::ApiResponse r = api_.postJson(path, QJsonObject{}); if (!ok(r)) return {false, false, errorOf(r, "switchWorkspace failed")}; // 切换空间返回新 accessToken:必须重新注入,后续请求才落到新空间。 const QString token = r.data.value(QStringLiteral("accessToken")).toString(); if (!token.isEmpty()) api_.setToken(token); return {true, true, {}}; } RepoResult ApiProjectRepository::pageProjects(const std::string& nameFilter, const std::string& typeId, int pageNo, int pageSize) { QJsonObject body{{QStringLiteral("projectName"), QString::fromStdString(nameFilter)}, {QStringLiteral("pageNo"), pageNo}, {QStringLiteral("pageSize"), pageSize}}; if (!typeId.empty()) body[QStringLiteral("projectTypeId")] = QString::fromStdString(typeId); const net::ApiResponse r = api_.postJson(QStringLiteral("/business/my/profile/project/page"), body); if (!ok(r)) return {false, {}, errorOf(r, "pageProjects failed")}; return {true, dto::parseProjectPage(r.data), {}}; } RepoResult> ApiProjectRepository::listProjectTypes() { const net::ApiResponse r = api_.get(QStringLiteral("/business/project/type/list")); if (!ok(r)) return {false, {}, errorOf(r, "listProjectTypes failed")}; return {true, dto::parseProjectTypes(r.data.value(QStringLiteral("value")).toArray()), {}}; } RepoResult> ApiProjectRepository::loadStructure(const std::string& projectId) { // 项目结构(项目根 + GS + TM;不含 DS)。比 projectWorkbench 干净。 const QString path = QStringLiteral("/business/projectStruct/queryProjectStruct/%1").arg(enc(projectId)); const net::ApiResponse r = api_.get(path); if (!ok(r)) return {false, {}, errorOf(r, "loadStructure failed")}; return {true, dto::parseStructNodes(r.data.value(QStringLiteral("value")).toArray()), {}}; } RepoResult ApiProjectRepository::loadTmRows(const std::string& projectId, const std::string& tmObjectId, int classifyType, int pageNo) { const QString path = (classifyType == 1) ? QStringLiteral("/business/dsObject/file/page") : QStringLiteral("/business/dsObject/data/page"); const QJsonObject body{ {QStringLiteral("projectId"), QString::fromStdString(projectId)}, {QStringLiteral("structParentId"), QString::fromStdString(tmObjectId)}, {QStringLiteral("structParentConfType"), 2}, {QStringLiteral("classifyTypeList"), QJsonArray{classifyType}}, {QStringLiteral("pageNo"), pageNo}, {QStringLiteral("pageSize"), 5}}; // 数据/文件页签每页 5;不足 total 时"加载更多"追加 const net::ApiResponse r = api_.postJson(path, body); if (!ok(r)) return {false, {}, errorOf(r, "loadTmRows failed")}; return {true, dto::parseDsPage(r.data), {}}; } } // namespace geopro::data