fix: 重构App结构体,settings数据持久化到App中

This commit is contained in:
xiaji
2026-04-13 22:43:55 +08:00
parent 21103bdf9f
commit c6c92d31ec

View File

@@ -51,7 +51,6 @@ impl Config {
}
}
// 尝试从环境变量加载
dotenv().ok();
Self {
host: env::var("PROXMOX_HOST").unwrap_or_default(),
@@ -91,17 +90,10 @@ pub struct AppState {
pub vm_status: String,
pub log_buffer: Vec<String>,
pub is_connected: bool,
pub host: String,
pub port: u16,
pub show_settings: bool,
pub token_id: String,
pub token_secret: String,
}
impl AppState {
pub fn new() -> Self {
let config = Config::load();
pub fn new(config: &Config) -> Self {
let client = if !config.host.is_empty() && !config.token_id.is_empty() && !config.token_secret.is_empty() {
let c = ProxmoxClient::new(&config.host, config.port, &config.token_id, &config.token_secret);
Arc::new(Mutex::new(Some(c)))
@@ -114,15 +106,10 @@ impl AppState {
Self {
client,
vm_id: config.vm_id,
node: config.node,
node: config.node.clone(),
vm_status: "未知".to_string(),
log_buffer: vec!["程序启动".to_string()],
is_connected,
host: config.host,
port: config.port,
show_settings: false,
token_id: config.token_id,
token_secret: config.token_secret,
}
}
@@ -133,18 +120,13 @@ impl AppState {
self.log_buffer.remove(0);
}
}
}
pub fn save_config(&self) {
let config = Config {
host: self.host.clone(),
port: self.port,
token_id: self.token_id.clone(),
token_secret: self.token_secret.clone(),
vm_id: self.vm_id,
node: self.node.clone(),
};
config.save();
}
pub struct SettingsData {
pub host: String,
pub port: u16,
pub token_id: String,
pub token_secret: String,
}
pub fn gui_run() {
@@ -178,12 +160,24 @@ pub fn gui_run() {
struct App {
state: SharedState,
show_settings: bool,
settings: SettingsData,
}
impl App {
fn new() -> Self {
let config = Config::load();
let settings = SettingsData {
host: config.host.clone(),
port: config.port,
token_id: config.token_id.clone(),
token_secret: config.token_secret.clone(),
};
Self {
state: Arc::new(RwLock::new(AppState::new())),
state: Arc::new(RwLock::new(AppState::new(&config))),
show_settings: false,
settings,
}
}
}
@@ -191,7 +185,6 @@ impl App {
impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
let state = self.state.clone();
let ctx_clone = ctx.clone();
egui::CentralPanel::default().show(ctx, |ui| {
// 标题栏
@@ -199,7 +192,7 @@ impl eframe::App for App {
ui.heading("Proxmox VM 控制器");
ui.with_layout(egui::Layout::right_to_left(egui::Align::Min), |ui| {
if ui.button("⚙ 设置").clicked() {
state.write().unwrap().show_settings = true;
self.show_settings = true;
}
});
});
@@ -345,12 +338,9 @@ impl eframe::App for App {
ctx.request_repaint();
thread::spawn(move || {
let rt = tokio::runtime::Runtime::new().unwrap();
// 先停止所有运行的虚拟机
let _ = rt.block_on(async {
// 获取节点上所有虚拟机
let client = client.lock().unwrap();
if let Some(c) = client.as_ref() {
// 发送关闭节点命令
c.shutdown_node(&node).await.ok();
}
});
@@ -376,17 +366,10 @@ impl eframe::App for App {
});
});
// 设置窗口
let show_settings = st.show_settings;
let state_clone = state.clone();
let mut st_host = st.host.clone();
let mut st_port = st.port;
let mut st_token_id = st.token_id.clone();
let mut st_token_secret = st.token_secret.clone();
drop(st);
if show_settings {
// 设置窗口
if self.show_settings {
egui::Window::new("设置")
.collapsible(false)
.resizable(false)
@@ -401,59 +384,68 @@ impl eframe::App for App {
// Base URL 显示
ui.label("API 地址:");
ui.colored_label(egui::Color32::GRAY, format!("https://{}:{}/api2/json/", st_host, st_port));
ui.colored_label(egui::Color32::GRAY, format!("https://{}:{}/api2/json/", self.settings.host, self.settings.port));
ui.add_space(8.0);
// Host 输入
ui.horizontal(|ui| {
ui.label("Host:");
ui.add(egui::TextEdit::singleline(&mut st_host).desired_width(200.0));
ui.add(egui::TextEdit::singleline(&mut self.settings.host).desired_width(200.0));
});
// Port 输入
ui.horizontal(|ui| {
ui.label("端口:");
ui.add(egui::DragValue::new(&mut st_port).range(1..=65535).speed(1));
ui.add(egui::DragValue::new(&mut self.settings.port).range(1..=65535).speed(1));
});
// 令牌ID 输入
ui.horizontal(|ui| {
ui.label("令牌ID:");
ui.add(egui::TextEdit::singleline(&mut st_token_id).desired_width(200.0));
ui.add(egui::TextEdit::singleline(&mut self.settings.token_id).desired_width(200.0));
});
// 密钥 输入(密码框)
ui.horizontal(|ui| {
ui.label("密钥:");
ui.add(egui::TextEdit::singleline(&mut st_token_secret).password(true).desired_width(200.0));
ui.add(egui::TextEdit::singleline(&mut self.settings.token_secret).password(true).desired_width(200.0));
});
ui.add_space(12.0);
// 按钮
ui.horizontal(|ui| {
let save_clicked = ui.button("💾 保存").clicked();
let cancel_clicked = ui.button("取消").clicked();
if save_clicked {
if !st_host.is_empty() && !st_token_id.is_empty() && !st_token_secret.is_empty() {
let client = ProxmoxClient::new(&st_host, st_port, &st_token_id, &st_token_secret);
let mut state = state_clone.write().unwrap();
state.host = st_host;
state.port = st_port;
state.token_id = st_token_id;
state.token_secret = st_token_secret;
state.client = Arc::new(Mutex::new(Some(client)));
state.is_connected = true;
state.save_config();
state.add_log("配置已保存");
state.show_settings = false;
if ui.button("💾 保存").clicked() {
if !self.settings.host.is_empty() && !self.settings.token_id.is_empty() && !self.settings.token_secret.is_empty() {
let client = ProxmoxClient::new(
&self.settings.host,
self.settings.port,
&self.settings.token_id,
&self.settings.token_secret
);
let config = Config {
host: self.settings.host.clone(),
port: self.settings.port,
token_id: self.settings.token_id.clone(),
token_secret: self.settings.token_secret.clone(),
vm_id: state.read().unwrap().vm_id,
node: state.read().unwrap().node.clone(),
};
config.save();
let mut st = state.write().unwrap();
st.client = Arc::new(Mutex::new(Some(client)));
st.is_connected = true;
st.add_log("配置已保存");
self.show_settings = false;
}
}
if cancel_clicked {
state_clone.write().unwrap().show_settings = false;
if ui.button("取消").clicked() {
self.show_settings = false;
}
});