From 8cab498f813a78e23f15851dfdf753d2980c25bc Mon Sep 17 00:00:00 2001 From: gaozheng Date: Wed, 10 Jun 2026 20:22:09 +0800 Subject: [PATCH] =?UTF-8?q?feat(controller):=20selectObject/setCheckedTms/?= =?UTF-8?q?selectDataset=20=E7=BC=96=E6=8E=92=20+=20=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/controller/WorkbenchNavController.cpp | 85 +++++++++++++++++++---- src/controller/WorkbenchNavController.hpp | 14 +++- 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/src/controller/WorkbenchNavController.cpp b/src/controller/WorkbenchNavController.cpp index a3366fa..74c286a 100644 --- a/src/controller/WorkbenchNavController.cpp +++ b/src/controller/WorkbenchNavController.cpp @@ -1,5 +1,7 @@ #include "WorkbenchNavController.hpp" +#include "dto/NavDto.hpp" + namespace geopro::controller { using data::ProjectSummary; @@ -63,6 +65,8 @@ void WorkbenchNavController::loadProjectsAndStructure() { emit projectsLoaded(ps.value.rows, curP, ps.value.total); if (curP.isEmpty()) { + lastStructNodes_.clear(); + tmExceptionCache_.clear(); emit structureLoaded(QString(), {}); // 暂无项目 → 空树 return; } @@ -71,6 +75,7 @@ void WorkbenchNavController::loadProjectsAndStructure() { emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error)); return; } + lastStructNodes_ = st.value; emit structureLoaded(QString::fromStdString(currentProjectName_), st.value); } @@ -100,54 +105,108 @@ void WorkbenchNavController::switchProject(const QString& projectId) { emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error)); return; } + lastStructNodes_ = st.value; + tmExceptionCache_.clear(); emit structureLoaded(QString::fromStdString(currentProjectName_), st.value); } -void WorkbenchNavController::selectTm(const QString& tmObjectId) { - if (tmObjectId.isEmpty() || busy_) return; +void WorkbenchNavController::selectObject(const QString& objectId, int confType) { + if (objectId.isEmpty() || busy_) return; BusyGuard guard(this, &busy_); - currentTmId_ = tmObjectId.toStdString(); + currentParentId_ = objectId.toStdString(); + currentParentConfType_ = confType; const std::string pid = currentProjectId_; dataPageNo_ = 1; filePageNo_ = 1; - const auto d = repo_.loadTmRows(pid, currentTmId_, 3, dataPageNo_); + const auto d = repo_.loadRows(pid, currentParentId_, confType, 3, dataPageNo_); if (!d.ok) { emit loadFailed(QStringLiteral("datasets"), QString::fromStdString(d.error)); return; } dataTotal_ = d.value.total; - emit datasetsLoaded(tmObjectId, d.value.rows, d.value.total, false); - const auto f = repo_.loadTmRows(pid, currentTmId_, 1, filePageNo_); + emit datasetsLoaded(objectId, d.value.rows, d.value.total, false); + const auto f = repo_.loadRows(pid, currentParentId_, confType, 1, filePageNo_); if (!f.ok) { emit loadFailed(QStringLiteral("files"), QString::fromStdString(f.error)); return; } fileTotal_ = f.value.total; - emit filesLoaded(tmObjectId, f.value.rows, f.value.total, false); + emit filesLoaded(objectId, f.value.rows, f.value.total, false); + + const auto detail = repo_.loadObjectDetail(currentParentId_, confType); + if (!detail.ok) { + emit loadFailed(QStringLiteral("objectDetail"), QString::fromStdString(detail.error)); + return; + } + emit objectDetailLoaded(objectId, detail.value); } void WorkbenchNavController::loadMoreData() { - if (currentTmId_.empty() || busy_) return; + if (currentParentId_.empty() || busy_) return; BusyGuard guard(this, &busy_); - const auto d = repo_.loadTmRows(currentProjectId_, currentTmId_, 3, ++dataPageNo_); + const auto d = repo_.loadRows(currentProjectId_, currentParentId_, currentParentConfType_, 3, ++dataPageNo_); if (!d.ok) { emit loadFailed(QStringLiteral("datasets"), QString::fromStdString(d.error)); return; } dataTotal_ = d.value.total; - emit datasetsLoaded(QString::fromStdString(currentTmId_), d.value.rows, d.value.total, true); + emit datasetsLoaded(QString::fromStdString(currentParentId_), d.value.rows, d.value.total, true); } void WorkbenchNavController::loadMoreFiles() { - if (currentTmId_.empty() || busy_) return; + if (currentParentId_.empty() || busy_) return; BusyGuard guard(this, &busy_); - const auto f = repo_.loadTmRows(currentProjectId_, currentTmId_, 1, ++filePageNo_); + const auto f = repo_.loadRows(currentProjectId_, currentParentId_, currentParentConfType_, 1, ++filePageNo_); if (!f.ok) { emit loadFailed(QStringLiteral("files"), QString::fromStdString(f.error)); return; } fileTotal_ = f.value.total; - emit filesLoaded(QString::fromStdString(currentTmId_), f.value.rows, f.value.total, true); + emit filesLoaded(QString::fromStdString(currentParentId_), f.value.rows, f.value.total, true); +} + +void WorkbenchNavController::setCheckedTms(const QStringList& tmObjectIds) { + if (busy_) return; + BusyGuard guard(this, &busy_); + auto nameOf = [this](const std::string& id) -> std::string { + for (const auto& n : lastStructNodes_) + if (n.id == id) return n.name; + return id; + }; + std::vector groups; + int total = 0; + for (const QString& tmQ : tmObjectIds) { + const std::string tm = tmQ.toStdString(); + auto it = tmExceptionCache_.find(tm); + if (it == tmExceptionCache_.end()) { + const auto ex = repo_.loadExceptionsByTm(tm); + if (!ex.ok) { + emit loadFailed(QStringLiteral("exceptions"), QString::fromStdString(ex.error)); + return; + } + it = tmExceptionCache_.emplace(tm, ex.value).first; + } + const auto grouped = data::dto::groupExceptionsByConsortium(it->second); + data::ObjectExceptionGroup g; + g.objectId = tm; + g.objectName = nameOf(tm); + g.consortia = grouped.consortia; + g.looseExceptions = grouped.loose; + total += static_cast(it->second.size()); + groups.push_back(std::move(g)); + } + emit exceptionTreeLoaded(groups, total); +} + +void WorkbenchNavController::selectDataset(const QString& dsObjectId) { + if (dsObjectId.isEmpty() || busy_) return; + BusyGuard guard(this, &busy_); + const auto form = repo_.loadDatasetForm(dsObjectId.toStdString()); + if (!form.ok) { + emit loadFailed(QStringLiteral("datasetDetail"), QString::fromStdString(form.error)); + return; + } + emit datasetDetailLoaded(form.value); } } // namespace geopro::controller diff --git a/src/controller/WorkbenchNavController.hpp b/src/controller/WorkbenchNavController.hpp index 04f6a66..52616ba 100644 --- a/src/controller/WorkbenchNavController.hpp +++ b/src/controller/WorkbenchNavController.hpp @@ -1,6 +1,8 @@ #pragma once #include #include +#include +#include #include #include @@ -21,7 +23,9 @@ public: public slots: void switchWorkspace(const QString& tenantId); void switchProject(const QString& projectId); - void selectTm(const QString& tmObjectId); + void selectObject(const QString& objectId, int confType); // 单击对象→DS列表+对象详情 + void setCheckedTms(const QStringList& tmObjectIds); // 勾选叶子集→异常树 + void selectDataset(const QString& dsObjectId); // 单击DS→数据集动态表单 void loadMoreData(); void loadMoreFiles(); @@ -35,6 +39,9 @@ signals: int total, bool append); void filesLoaded(const QString& tmObjectId, const std::vector& rows, int total, bool append); + void objectDetailLoaded(const QString& title, const geopro::data::DynamicForm& form); + void exceptionTreeLoaded(const std::vector& groups, int tmCount); + void datasetDetailLoaded(const geopro::data::DynamicForm& form); void loadFailed(const QString& stage, const QString& message); private: @@ -44,7 +51,10 @@ private: bool busy_ = false; std::vector lastProjects_; std::string currentWorkspaceId_, currentProjectId_, currentProjectName_, currentCrsCode_; - std::string currentTmId_; + std::string currentParentId_; + int currentParentConfType_ = 0; + std::vector lastStructNodes_; // tmId→name 解析 + std::map> tmExceptionCache_; int dataPageNo_ = 0; int filePageNo_ = 0; int dataTotal_ = 0;