diff --git a/package.json b/package.json index dd4c7ac..06f7208 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@tauri-apps/api": "^2", "@tauri-apps/plugin-opener": "^2", + "@tauri-apps/plugin-shell": "^2.3.0", "@vueuse/core": "^13.6.0", "lucide-vue-next": "^0.539.0", "vue": "^3.5.13" diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index a358b2f..f1baf20 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -12,6 +12,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-plugin-opener", + "tauri-plugin-shell", "tempfile", "tokio", "uuid", @@ -853,6 +854,15 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endi" version = "1.1.0" @@ -2399,6 +2409,16 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_pipe" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db335f4760b14ead6290116f2427bf33a14d4f0617d49f78a246de10c1831224" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "pango" version = "0.18.3" @@ -3283,12 +3303,44 @@ dependencies = [ "digest", ] +[[package]] +name = "shared_child" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e362d9935bc50f019969e2f9ecd66786612daae13e8f277be7bfb66e8bed3f7" +dependencies = [ + "libc", + "sigchld", + "windows-sys 0.60.2", +] + [[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "sigchld" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47106eded3c154e70176fc83df9737335c94ce22f821c32d17ed1db1f83badb1" +dependencies = [ + "libc", + "os_pipe", + "signal-hook", +] + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.4.6" @@ -3703,6 +3755,27 @@ dependencies = [ "zbus", ] +[[package]] +name = "tauri-plugin-shell" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b9ffadec5c3523f11e8273465cacb3d86ea7652a28e6e2a2e9b5c182f791d25" +dependencies = [ + "encoding_rs", + "log", + "open", + "os_pipe", + "regex", + "schemars 0.8.22", + "serde", + "serde_json", + "shared_child", + "tauri", + "tauri-plugin", + "thiserror 2.0.12", + "tokio", +] + [[package]] name = "tauri-runtime" version = "2.7.1" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 2f711e7..bfc38dc 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -11,10 +11,12 @@ crate-type = ["staticlib", "cdylib", "rlib"] [build-dependencies] tauri-build = { version = "2", features = [] } +chrono = { version = "0.4.41", features = ["serde"] } [dependencies] tauri = { version = "2", features = [] } tauri-plugin-opener = "2" +tauri-plugin-shell = "2.0" serde = { version = "1", features = ["derive"] } serde_json = "1" tokio = "1.47.1" diff --git a/src-tauri/build.rs b/src-tauri/build.rs index d860e1e..920cd1c 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,13 @@ fn main() { + // 设置构建时间 + let build_time = chrono::Utc::now() + .format("%Y-%m-%d %H:%M:%S UTC") + .to_string(); + println!("cargo:rustc-env=BUILD_TIME={}", build_time); + + // 重新构建触发条件 + println!("cargo:rerun-if-changed=build.rs"); + + // Tauri 的构建脚本 tauri_build::build() } diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 4cdbf49..47bb51d 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -2,9 +2,13 @@ "$schema": "../gen/schemas/desktop-schema.json", "identifier": "default", "description": "Capability for the main window", - "windows": ["main"], + "windows": [ + "main" + ], "permissions": [ "core:default", - "opener:default" + "opener:default", + "shell:allow-open", + "shell:default" ] } diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index c3f178b..23a7b53 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -4,7 +4,10 @@ )] mod plugins; +mod setup; +use crate::setup::app::get_app_info; +use chrono::Utc; use plugins::{CodeExecutionRequest, ExecutionResult, LanguageInfo, PluginManager}; use std::fs; use std::process::{Command, Stdio}; @@ -213,15 +216,26 @@ async fn clear_execution_history(history: State<'_, ExecutionHistory>) -> Result } fn main() { + let build_time = Utc::now().format("%Y-%m-%d %H:%M:%S UTC").to_string(); + println!("cargo:rustc-env=BUILD_TIME={}", build_time); + tauri::Builder::default() + .plugin(tauri_plugin_shell::init()) .manage(ExecutionHistory::default()) .manage(PluginManagerState::new(PluginManager::new())) + .setup(|app| { + let menu = setup::menu::create_menu(app.handle())?; + app.set_menu(menu)?; + setup::menu::setup_menu_handler(app.handle()); + Ok(()) + }) .invoke_handler(tauri::generate_handler![ execute_code, get_info, get_supported_languages, get_execution_history, - clear_execution_history + clear_execution_history, + get_app_info ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src-tauri/src/setup/app.rs b/src-tauri/src/setup/app.rs new file mode 100644 index 0000000..6cc1538 --- /dev/null +++ b/src-tauri/src/setup/app.rs @@ -0,0 +1,20 @@ +use serde::{Deserialize, Serialize}; +use tauri::command; + +#[derive(Debug, Serialize, Deserialize)] +pub struct AppInfo { + pub version: String, + pub build_time: String, + pub platform: String, + pub arch: String, +} + +#[command] +pub async fn get_app_info() -> Result { + Ok(AppInfo { + version: env!("CARGO_PKG_VERSION").to_string(), + build_time: env!("BUILD_TIME", "Unknown").to_string(), + platform: std::env::consts::OS.to_string(), + arch: std::env::consts::ARCH.to_string(), + }) +} diff --git a/src-tauri/src/setup/menu.rs b/src-tauri/src/setup/menu.rs new file mode 100644 index 0000000..3b703ac --- /dev/null +++ b/src-tauri/src/setup/menu.rs @@ -0,0 +1,26 @@ +use tauri::{ + AppHandle, Emitter, + menu::{Menu, MenuBuilder, MenuItemBuilder, SubmenuBuilder}, +}; + +pub fn create_menu(app: &AppHandle) -> tauri::Result> { + let about_item = MenuItemBuilder::new("关于 CodeForge") + .id("about") + .build(app)?; + + let app_submenu = SubmenuBuilder::new(app, "CodeForge") + .item(&about_item) + .build()?; + + let menu = MenuBuilder::new(app).items(&[&app_submenu]).build()?; + + Ok(menu) +} + +pub fn setup_menu_handler(app: &AppHandle) { + app.on_menu_event(move |app, event| { + if event.id().as_ref() == "about" { + let _event = app.emit("show-about", ()); + } + }); +} diff --git a/src-tauri/src/setup/mod.rs b/src-tauri/src/setup/mod.rs new file mode 100644 index 0000000..36f60ad --- /dev/null +++ b/src-tauri/src/setup/mod.rs @@ -0,0 +1,2 @@ +pub mod app; +pub mod menu; diff --git a/src/App.vue b/src/App.vue index f2eca06..fa12e08 100644 --- a/src/App.vue +++ b/src/App.vue @@ -48,17 +48,22 @@ :show-progress="true" @close="toast.show = false"> + + + \ No newline at end of file diff --git a/src/components/About.vue b/src/components/About.vue new file mode 100644 index 0000000..666e037 --- /dev/null +++ b/src/components/About.vue @@ -0,0 +1,175 @@ + + +