diff --git a/src-tauri/src/app_config.rs b/src-tauri/src/app_config.rs index df77461..2dcc4cd 100644 --- a/src-tauri/src/app_config.rs +++ b/src-tauri/src/app_config.rs @@ -35,6 +35,14 @@ pub struct AppConfig { fn is_dev() -> bool { cfg!(debug_assertions) } + +/// 开发态下注入的运行时环境变量(不走 desktop_configs 表)。 +fn apply_node_runtime_env(env: &mut HashMap) { + if is_dev() { + // 一键仿写等 Puppeteer 流程:开发时显示浏览器窗口,便于调试扫码/页面跳转。 + env.insert("AICLIENT_PUPPETEER_HEADLESS".into(), "0".into()); + } +} pub fn api_base() -> String { std::env::var("AICLIENT_API_BASE").unwrap_or_else(|_| { if is_dev() { @@ -208,10 +216,12 @@ impl AppConfig { pub async fn env_for_node(&self) -> HashMap { let g = self.inner.read().await; let merged = merged_entries(&g.server_entries, &g.local_entries); - merged + let mut env: HashMap = merged .iter() .map(|(name, value)| (node_env_var_name(name), value.clone())) - .collect() + .collect(); + apply_node_runtime_env(&mut env); + env } pub async fn refresh_after_auth(&self, token: &str) -> Result<(), AppConfigError> { diff --git a/src-tauri/src/nodejs.rs b/src-tauri/src/nodejs.rs index a0f7715..c74c3e5 100644 --- a/src-tauri/src/nodejs.rs +++ b/src-tauri/src/nodejs.rs @@ -511,8 +511,14 @@ async fn run_script_bundle( let (status, cancelled, result_line, stdout_done) = tokio::select! { result = &mut stdout_task => { let result_line = result.unwrap_or(None); - let _ = child.start_kill(); - let status = child.wait().await?; + // 已收到结果时优先给脚本清理资源(如关闭浏览器)机会,超时再强制结束。 + let status = match timeout(Duration::from_secs(5), child.wait()).await { + Ok(status) => status?, + Err(_) => { + let _ = child.start_kill(); + child.wait().await? + } + }; (status, false, result_line, true) } status = child.wait() => (status?, false, None, false), @@ -552,16 +558,29 @@ async fn run_script_bundle( return Err(NodeError::Cancelled); } + if let Some(result_str) = result_line { + if !status.success() { + log::warn!( + target: "nodejs", + "node exited non-zero after __RESULT__: status={:?}, stderr_tail={}", + status.code(), + stderr_tail + ); + } + let v: Value = serde_json::from_str(&result_str)?; + return Ok(v); + } + if !status.success() { return Err(NodeError::NonZero { status: status.code(), stderr: stderr_tail, }); } - - let result_str = result_line.ok_or(NodeError::NoResult)?; - let v: Value = serde_json::from_str(&result_str)?; - Ok(v) + // let result_str = result_line.ok_or(NodeError::NoResult)?; + // let v: Value = serde_json::from_str(&result_str)?; + // Ok(v) + Err(NodeError::NoResult) } async fn wait_for_cancel(cancel_rx: &mut watch::Receiver) {