diff --git a/package.json b/package.json index 4f3668a..47a2192 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "dependencies": { "@ant-design/icons-vue": "^7.0.1", "@tauri-apps/api": "^2", + "@tauri-apps/plugin-autostart": "^2.7.0", "@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-process": "^2.4.0", "@tauri-apps/plugin-updater": "^2.13.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ece1cc6..ac13877 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@tauri-apps/api': specifier: ^2 version: 2.12.3 + '@tauri-apps/plugin-autostart': + specifier: ^2.7.0 + version: 2.7.0 '@tauri-apps/plugin-opener': specifier: ^2 version: 2.7.1 @@ -535,6 +538,9 @@ packages: engines: {node: '>= 10'} hasBin: true + '@tauri-apps/plugin-autostart@2.7.0': + resolution: {integrity: sha512-4uRq+rqKSAh6MWAxgk6FnUPigc8VMG8eDVYTLk3A7OfKs9sLVwfeM8kbUvzjpabRQvyl4zd9tfzXBTrrtuprsA==} + '@tauri-apps/plugin-opener@2.7.1': resolution: {integrity: sha512-XkXdt30rontti9TII/gBBxFRXWfj8DiprFW7RgBFRBj1OhdfjBNVcFqSEWkkZ4hXafHnuEnB7F1sFsmu6uyywQ==} @@ -1578,6 +1584,10 @@ snapshots: '@tauri-apps/cli-win32-ia32-msvc': 2.12.2 '@tauri-apps/cli-win32-x64-msvc': 2.12.2 + '@tauri-apps/plugin-autostart@2.7.0': + dependencies: + '@tauri-apps/api': 2.12.3 + '@tauri-apps/plugin-opener@2.7.1': dependencies: '@tauri-apps/api': 2.12.3 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 43d0fcc..05334ec 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -231,6 +231,20 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto-launch" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17918dba7ecf78b9a14507ec9f984e7977d13fad87dc86d61038980a45d128cf" +dependencies = [ + "dirs 6.0.0", + "os_info", + "smappservice-rs", + "thiserror 2.0.21", + "windows-registry", + "windows-result", +] + [[package]] name = "autocfg" version = "1.5.1" @@ -493,6 +507,12 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e7648175b45a9a48536d676f68d918270699102aa8dab5496df06904c914600" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + [[package]] name = "chacha20" version = "0.10.2" @@ -889,6 +909,15 @@ dependencies = [ "ctutils", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + [[package]] name = "dirs" version = "7.0.0" @@ -1280,6 +1309,7 @@ dependencies = [ "tauri", "tauri-build", "tauri-helper", + "tauri-plugin-autostart", "tauri-plugin-dialog", "tauri-plugin-opener", "tauri-plugin-prevent-default", @@ -2571,6 +2601,18 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.31.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" +dependencies = [ + "bitflags 2.13.2", + "cfg-if", + "cfg_aliases", + "libc", +] + [[package]] name = "ntapi" version = "0.4.3" @@ -2802,6 +2844,30 @@ dependencies = [ "objc2-foundation", ] +[[package]] +name = "objc2-security" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" +dependencies = [ + "bitflags 2.13.2", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-service-management" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b213642d6959cc6023ceb1217aa595eaaf09b8094ce95127c103cab611fe65e8" +dependencies = [ + "block2", + "objc2", + "objc2-core-foundation", + "objc2-foundation", + "objc2-security", +] + [[package]] name = "objc2-ui-kit" version = "0.3.2" @@ -2923,6 +2989,21 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "os_info" +version = "3.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf20a545b305cf1da722b236b5155c9bb35f1d5ceb28c048bd96ca842f41b5b" +dependencies = [ + "android_system_properties", + "log", + "nix", + "objc2", + "objc2-foundation", + "objc2-ui-kit", + "windows-sys 0.61.2", +] + [[package]] name = "osakit" version = "0.3.1" @@ -3988,6 +4069,18 @@ dependencies = [ "serde", ] +[[package]] +name = "smappservice-rs" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52703b97a53101cf5d4580e0737aaa634ce1fdcfc123c16b2a9658e358013488" +dependencies = [ + "objc2", + "objc2-foundation", + "objc2-service-management", + "thiserror 2.0.21", +] + [[package]] name = "socket2" version = "0.6.5" @@ -4494,7 +4587,7 @@ dependencies = [ "anyhow", "bytes", "cookie", - "dirs", + "dirs 7.0.0", "dunce", "embed_plist", "getrandom 0.3.4", @@ -4544,7 +4637,7 @@ checksum = "2eea0b6302f82c574b21af6fc6ae6e86183b9280853c22621d0abf0936911ffc" dependencies = [ "anyhow", "cargo_toml", - "dirs", + "dirs 7.0.0", "glob", "heck 0.5.0", "json-patch", @@ -4629,6 +4722,20 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-plugin-autostart" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bce56ceb0a99b8ab5eebc977ba9ffc62391b862648cb9ab76fc8bc7231b8f7e2" +dependencies = [ + "auto-launch", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "thiserror 2.0.21", +] + [[package]] name = "tauri-plugin-dialog" version = "2.8.2" @@ -4740,7 +4847,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "855a336eb389d2c1502244fd48fa2d8cb487a430f691bbaed025195f99a04489" dependencies = [ "base64 0.22.1", - "dirs", + "dirs 7.0.0", "flate2", "futures-util", "http", @@ -5277,7 +5384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2b9c52859a94554803ccd4a24b98f74148ebc73b90676d783f3490b1bff9d72" dependencies = [ "crossbeam-channel", - "dirs", + "dirs 7.0.0", "libappindicator", "muda", "objc2", @@ -6137,7 +6244,7 @@ dependencies = [ "block2", "cookie", "crossbeam-channel", - "dirs", + "dirs 7.0.0", "dom_query", "dpi", "dunce", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index f1dbfc7..99161d4 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -39,6 +39,7 @@ sysinfo = "0.39" tauri-plugin-dialog = "2.7.2" tauri-plugin-updater = "2.10.1" tauri-plugin-process = "2.3.1" +tauri-plugin-autostart = "2" tauri-plugin-prevent-default = "6.0.1" reqwest = { version = "0.12", features = ["json", "stream"] } futures-util = "0.3" diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index ed0013a..4c5b75b 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -8,6 +8,7 @@ "opener:default", "updater:default", "process:default", + "autostart:default", "core:window:allow-start-dragging", "core:window:allow-minimize", "core:window:allow-unminimize", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 300f05f..34c00a6 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -28,6 +28,11 @@ pub fn run() { .plugin(tauri_plugin_dialog::init()) // 对话框插件 .plugin(tauri_plugin_updater::Builder::new().build()) // 更新插件 .plugin(tauri_plugin_process::init()) // 进程插件(更新后重启) + // 开机自启插件:读写系统启动项(Windows 注册表 Run 键 / macOS LaunchAgent / Linux XDG autostart) + .plugin(tauri_plugin_autostart::init( + tauri_plugin_autostart::MacosLauncher::LaunchAgent, + None, + )) .plugin(tauri_plugin_prevent_default::Builder::new().build()) .setup(|app| { let pool = tauri::async_runtime::block_on(async { diff --git a/src/api/autostart.ts b/src/api/autostart.ts new file mode 100644 index 0000000..ec6a46e --- /dev/null +++ b/src/api/autostart.ts @@ -0,0 +1,23 @@ +import { isTauri } from "@/utils/window" + +/** + * 开机自启封装(Tauri 官方 autostart 插件)。 + * + * 自启状态由系统启动项决定(Windows 注册表 Run 键 / macOS LaunchAgent / + * Linux XDG autostart),这里只做读写,不在前端另行持久化,避免两端不一致。 + * 非 Tauri 环境(纯浏览器调试)下调用会被安全忽略。 + */ + +/** 读取系统启动项:本应用是否已设为开机自启 */ +export async function isAutostartEnabled(): Promise { + if (!isTauri()) return false + const { isEnabled } = await import("@tauri-apps/plugin-autostart") + return isEnabled() +} + +/** 开启 / 关闭开机自启(直接写入系统启动项) */ +export async function setAutostartEnabled(enabled: boolean): Promise { + if (!isTauri()) return + const { enable, disable } = await import("@tauri-apps/plugin-autostart") + await (enabled ? enable() : disable()) +} diff --git a/src/components/CardRadioGroup.vue b/src/components/CardRadioGroup.vue index c4de3d4..6ae1d74 100644 --- a/src/components/CardRadioGroup.vue +++ b/src/components/CardRadioGroup.vue @@ -29,7 +29,7 @@ const model = defineModel({ required: true }) .card-radio-group { display: flex; flex-direction: column; - gap: 10px; + gap: 6px; width: 100%; } @@ -38,8 +38,8 @@ const model = defineModel({ required: true }) align-items: flex-start; width: 100%; margin-inline-end: 0; - padding: 10px 12px; - border-radius: 10px; + padding: 7px 10px; + border-radius: 8px; border: 1px solid rgba(15, 23, 42, 0.1); transition: border-color 0.2s ease, background-color 0.2s ease; @@ -54,13 +54,13 @@ const model = defineModel({ required: true }) } :deep(.ant-radio) { - margin-top: 2px; + margin-top: 1px; } :deep(> span:last-child) { display: flex; flex-direction: column; - gap: 2px; + gap: 0; padding-inline-end: 0; } } @@ -75,12 +75,14 @@ const model = defineModel({ required: true }) } .card-radio-title { + font-size: 13px; font-weight: 500; + line-height: 1.5; } .card-radio-desc { - font-size: 12px; - line-height: 1.4; + font-size: 11.5px; + line-height: 1.35; opacity: 0.6; } diff --git a/src/components/CloseConfirmModal.vue b/src/components/CloseConfirmModal.vue index 1c25a7c..fe195b8 100644 --- a/src/components/CloseConfirmModal.vue +++ b/src/components/CloseConfirmModal.vue @@ -7,15 +7,16 @@ :mask-closable="false" :closable="!store.quitting" :keyboard="!store.quitting" + :body-style="{ paddingTop: '10px', paddingBottom: '4px' }" @cancel="store.cancelClose()" > - + -
{{ t("closeDialog.behavior") }}
+
{{ t("closeDialog.behavior") }}