vdi-cloud/terminal/kiosk-shell/src/desktop_store.cpp
宋一鸣 8cbb867371 功能:持久化桌面连接配置到 desktops.json
变更详情:新增桌面连接配置持久化(desktops.json)
2026-10-29 02:09:57 -04:00

161 lines
5.3 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "desktop_store.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include "config.h"
namespace vdi {
namespace {
// 三张默认桌面卡:id/name/os 固定,连接参数由现场配置。
// endpoint 为空 = 待分配,配置地址后即变为可连接。
std::vector<DesktopInfo> defaultDesktops(const QString& migratedServer) {
std::vector<DesktopInfo> list;
DesktopInfo win;
win.id = QStringLiteral("desk-win10-01");
win.name = QStringLiteral("Windows 10");
win.os = QStringLiteral("Windows 桌面");
win.protocol = Protocol::kMoonlight;
win.endpoint = migratedServer; // 兼容老盒子:迁移 client.conf 的 server
win.app = QStringLiteral("Desktop");
win.width = 1920;
win.height = 1080;
win.fps = 60;
list.push_back(win);
DesktopInfo ubuntu;
ubuntu.id = QStringLiteral("desk-ubuntu-01");
ubuntu.name = QStringLiteral("Ubuntu");
ubuntu.os = QStringLiteral("Ubuntu 桌面");
ubuntu.protocol = Protocol::kRdp;
list.push_back(ubuntu);
DesktopInfo kylin;
kylin.id = QStringLiteral("desk-kylin-01");
kylin.name = QStringLiteral("麒麟");
kylin.os = QStringLiteral("银河麒麟桌面");
kylin.protocol = Protocol::kRdp;
list.push_back(kylin);
return list;
}
DesktopInfo fromJson(const QJsonObject& obj) {
DesktopInfo d;
d.id = obj.value(QStringLiteral("id")).toString();
d.name = obj.value(QStringLiteral("name")).toString();
d.os = obj.value(QStringLiteral("os")).toString();
d.protocol = obj.value(QStringLiteral("protocol")).toString() == QStringLiteral("rdp")
? Protocol::kRdp
: Protocol::kMoonlight;
d.endpoint = obj.value(QStringLiteral("endpoint")).toString();
d.app = obj.value(QStringLiteral("app")).toString();
d.width = obj.value(QStringLiteral("width")).toInt(1920);
d.height = obj.value(QStringLiteral("height")).toInt(1080);
d.fps = obj.value(QStringLiteral("fps")).toInt(60);
d.state = d.endpoint.isEmpty() ? DesktopState::kUnassigned : DesktopState::kAvailable;
return d;
}
QJsonObject toJson(const DesktopInfo& d) {
QJsonObject obj;
obj.insert(QStringLiteral("id"), d.id);
obj.insert(QStringLiteral("name"), d.name);
obj.insert(QStringLiteral("os"), d.os);
obj.insert(QStringLiteral("protocol"),
d.protocol == Protocol::kRdp ? QStringLiteral("rdp") : QStringLiteral("moonlight"));
obj.insert(QStringLiteral("endpoint"), d.endpoint);
obj.insert(QStringLiteral("app"), d.app);
obj.insert(QStringLiteral("width"), d.width);
obj.insert(QStringLiteral("height"), d.height);
obj.insert(QStringLiteral("fps"), d.fps);
return obj;
}
} // namespace
QString DesktopStore::storePath() {
return QString::fromStdString(configDir()) + QStringLiteral("/desktops.json");
}
std::vector<DesktopInfo> DesktopStore::load() {
std::vector<DesktopInfo> result;
QFile file(storePath());
if (file.exists() && file.open(QIODevice::ReadOnly)) {
const QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
const QJsonArray arr = doc.object().value(QStringLiteral("desktops")).toArray();
for (const QJsonValue& v : arr) {
DesktopInfo d = fromJson(v.toObject());
if (!d.id.isEmpty()) {
result.push_back(d);
}
}
}
// 确保三张默认卡始终存在(新环境骨架 / 防止手工编辑删卡)。
// 兼容老盒子:client.conf 里只要配过 server,就迁移为 Windows 桌面地址。
const TerminalConfig cfg = loadConfig();
const QString migrated = result.empty() && !cfg.server.empty()
? QString::fromStdString(cfg.server)
: QString();
const std::vector<DesktopInfo> defaults = defaultDesktops(migrated);
for (const DesktopInfo& def : defaults) {
bool found = false;
for (const DesktopInfo& d : result) {
if (d.id == def.id) {
found = true;
break;
}
}
if (!found) {
result.push_back(def);
}
}
// 统一按 endpoint 推导状态:有地址=可连接,无地址=待分配
for (DesktopInfo& d : result) {
d.state = d.endpoint.isEmpty() ? DesktopState::kUnassigned : DesktopState::kAvailable;
}
return result;
}
bool DesktopStore::save(const std::vector<DesktopInfo>& desktops) {
QJsonArray arr;
for (const DesktopInfo& d : desktops) {
arr.append(toJson(d));
}
QJsonObject root;
root.insert(QStringLiteral("version"), 1);
root.insert(QStringLiteral("desktops"), arr);
const QString path = storePath();
QDir().mkpath(QFileInfo(path).absolutePath());
QFile file(path);
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
return false;
}
file.write(QJsonDocument(root).toJson(QJsonDocument::Indented));
return true;
}
bool DesktopStore::update(const DesktopInfo& info) {
std::vector<DesktopInfo> list = load();
for (DesktopInfo& d : list) {
if (d.id == info.id) {
d = info;
d.state = d.endpoint.isEmpty() ? DesktopState::kUnassigned : DesktopState::kAvailable;
return save(list);
}
}
return false;
}
} // namespace vdi