From c6c92d31ec4b664948ac13a87ff7decfc2a26016 Mon Sep 17 00:00:00 2001 From: xiaji Date: Mon, 13 Apr 2026 22:43:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=8D=E6=9E=84App=E7=BB=93=E6=9E=84?= =?UTF-8?q?=E4=BD=93=EF=BC=8Csettings=E6=95=B0=E6=8D=AE=E6=8C=81=E4=B9=85?= =?UTF-8?q?=E5=8C=96=E5=88=B0App=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/gui.rs | 120 +++++++++++++++++++++++++---------------------------- 1 file changed, 56 insertions(+), 64 deletions(-) diff --git a/src/gui.rs b/src/gui.rs index 92c7e18..47a1d57 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -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, 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; } });