feat(controller): WorkbenchNavController 导航状态机
This commit is contained in:
parent
fa4bbf08b3
commit
f4ca9bcd38
|
|
@ -12,4 +12,5 @@ add_subdirectory(core)
|
|||
add_subdirectory(data)
|
||||
add_subdirectory(net)
|
||||
add_subdirectory(render)
|
||||
add_subdirectory(controller)
|
||||
add_subdirectory(app)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
find_package(Qt6 COMPONENTS Core REQUIRED)
|
||||
add_library(geopro_controller STATIC
|
||||
WorkbenchNavController.cpp)
|
||||
target_include_directories(geopro_controller PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
target_link_libraries(geopro_controller PUBLIC geopro_data Qt6::Core)
|
||||
target_compile_features(geopro_controller PUBLIC cxx_std_17)
|
||||
set_target_properties(geopro_controller PROPERTIES AUTOMOC ON AUTOUIC OFF AUTORCC OFF)
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
#include "WorkbenchNavController.hpp"
|
||||
|
||||
namespace geopro::controller {
|
||||
|
||||
using data::ProjectSummary;
|
||||
using data::Workspace;
|
||||
|
||||
WorkbenchNavController::WorkbenchNavController(data::IProjectRepository& repo, QObject* parent)
|
||||
: QObject(parent), repo_(repo) {}
|
||||
|
||||
void WorkbenchNavController::start() {
|
||||
emit busyChanged(true);
|
||||
const auto ws = repo_.listWorkspaces();
|
||||
if (!ws.ok) {
|
||||
emit busyChanged(false);
|
||||
emit loadFailed(QStringLiteral("workspaces"), QString::fromStdString(ws.error));
|
||||
return;
|
||||
}
|
||||
QString cur;
|
||||
for (const auto& w : ws.value)
|
||||
if (w.isCurrent) cur = QString::fromStdString(w.id);
|
||||
if (cur.isEmpty() && !ws.value.empty()) cur = QString::fromStdString(ws.value.front().id);
|
||||
currentWorkspaceId_ = cur.toStdString();
|
||||
emit workspacesLoaded(ws.value, cur);
|
||||
|
||||
loadProjectsAndStructure();
|
||||
emit busyChanged(false);
|
||||
}
|
||||
|
||||
void WorkbenchNavController::loadProjectsAndStructure() {
|
||||
const auto ps = repo_.listProjects(std::string());
|
||||
if (!ps.ok) {
|
||||
emit loadFailed(QStringLiteral("projects"), QString::fromStdString(ps.error));
|
||||
return;
|
||||
}
|
||||
lastProjects_ = ps.value;
|
||||
QString curP;
|
||||
if (!ps.value.empty()) {
|
||||
const auto& first = ps.value.front();
|
||||
curP = QString::fromStdString(first.id);
|
||||
currentProjectId_ = first.id;
|
||||
currentProjectName_ = first.name;
|
||||
currentCrsCode_ = first.crsCode;
|
||||
} else {
|
||||
currentProjectId_.clear();
|
||||
currentProjectName_.clear();
|
||||
currentCrsCode_.clear();
|
||||
}
|
||||
emit projectsLoaded(ps.value, curP);
|
||||
|
||||
if (curP.isEmpty()) {
|
||||
emit structureLoaded(QString(), {}); // 暂无项目 → 空树
|
||||
return;
|
||||
}
|
||||
const auto st = repo_.loadStructure(currentProjectId_);
|
||||
if (!st.ok) {
|
||||
emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error));
|
||||
return;
|
||||
}
|
||||
emit structureLoaded(QString::fromStdString(currentProjectName_), st.value);
|
||||
}
|
||||
|
||||
void WorkbenchNavController::switchWorkspace(const QString& tenantId) {
|
||||
if (tenantId.isEmpty()) return;
|
||||
emit busyChanged(true);
|
||||
const auto r = repo_.switchWorkspace(tenantId.toStdString());
|
||||
if (!r.ok) {
|
||||
emit busyChanged(false);
|
||||
emit loadFailed(QStringLiteral("switchWorkspace"), QString::fromStdString(r.error));
|
||||
return;
|
||||
}
|
||||
currentWorkspaceId_ = tenantId.toStdString();
|
||||
loadProjectsAndStructure();
|
||||
emit busyChanged(false);
|
||||
}
|
||||
|
||||
void WorkbenchNavController::switchProject(const QString& projectId) {
|
||||
if (projectId.isEmpty()) return;
|
||||
emit busyChanged(true);
|
||||
currentProjectId_ = projectId.toStdString();
|
||||
for (const auto& p : lastProjects_)
|
||||
if (p.id == currentProjectId_) {
|
||||
currentProjectName_ = p.name;
|
||||
currentCrsCode_ = p.crsCode;
|
||||
}
|
||||
const auto st = repo_.loadStructure(currentProjectId_);
|
||||
if (!st.ok) {
|
||||
emit busyChanged(false);
|
||||
emit loadFailed(QStringLiteral("structure"), QString::fromStdString(st.error));
|
||||
return;
|
||||
}
|
||||
emit structureLoaded(QString::fromStdString(currentProjectName_), st.value);
|
||||
emit busyChanged(false);
|
||||
}
|
||||
|
||||
void WorkbenchNavController::selectTm(const QString& tmObjectId) {
|
||||
if (tmObjectId.isEmpty()) return;
|
||||
emit busyChanged(true);
|
||||
const auto ds = repo_.loadDatasetsOfTm(tmObjectId.toStdString());
|
||||
emit busyChanged(false);
|
||||
if (!ds.ok) {
|
||||
emit loadFailed(QStringLiteral("datasets"), QString::fromStdString(ds.error));
|
||||
return;
|
||||
}
|
||||
emit datasetsLoaded(tmObjectId, ds.value);
|
||||
}
|
||||
|
||||
} // namespace geopro::controller
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
#pragma once
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "repo/IProjectRepository.hpp"
|
||||
|
||||
namespace geopro::controller {
|
||||
|
||||
// 导航状态机:编排 IProjectRepository,持有当前 空间/项目 状态,经信号驱动 UI。不持有 widget。
|
||||
class WorkbenchNavController : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WorkbenchNavController(data::IProjectRepository& repo, QObject* parent = nullptr);
|
||||
|
||||
void start(); // 启动:拉空间 → 项目 → 结构
|
||||
|
||||
QString currentCrsCode() const { return QString::fromStdString(currentCrsCode_); }
|
||||
|
||||
public slots:
|
||||
void switchWorkspace(const QString& tenantId);
|
||||
void switchProject(const QString& projectId);
|
||||
void selectTm(const QString& tmObjectId);
|
||||
|
||||
signals:
|
||||
void busyChanged(bool busy);
|
||||
void workspacesLoaded(const std::vector<geopro::data::Workspace>& list, const QString& currentId);
|
||||
void projectsLoaded(const std::vector<geopro::data::ProjectSummary>& list, const QString& currentId);
|
||||
void structureLoaded(const QString& projectName, const std::vector<geopro::data::StructNode>& nodes);
|
||||
void datasetsLoaded(const QString& tmObjectId, const std::vector<geopro::data::DsNode>& list);
|
||||
void loadFailed(const QString& stage, const QString& message);
|
||||
|
||||
private:
|
||||
void loadProjectsAndStructure(); // start + switchWorkspace 共用
|
||||
|
||||
data::IProjectRepository& repo_;
|
||||
std::vector<data::ProjectSummary> lastProjects_;
|
||||
std::string currentWorkspaceId_, currentProjectId_, currentProjectName_, currentCrsCode_;
|
||||
};
|
||||
|
||||
} // namespace geopro::controller
|
||||
Loading…
Reference in New Issue