From faf181e67aa63fe8517269919891f749d55bcc01 Mon Sep 17 00:00:00 2001 From: Yuhang Wu Date: Wed, 29 Jul 2026 18:07:14 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E4=B8=BB=E9=A2=98?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E3=80=81=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=EF=BC=8C=E4=BC=98=E5=8C=96=E7=95=8C=E9=9D=A2?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=B8=8E=E7=99=BB=E5=BD=95=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增Pinia主题状态管理,支持明暗主题切换并持久化配置 2. 新增个人中心页面,支持用户信息编辑、密码修改与主题设置 3. 登录后缓存用户信息到localStorage,完善用户操作链路 4. 重构菜单命令注册逻辑,引入tauri-helper简化开发 5. 优化全局样式系统,使用CSS变量实现主题切换 6. 新增用户详情API接口,完善后端服务能力 7. 修复S3 SDK导入冗余依赖问题,优化菜单更新SQL执行逻辑 8. 调整侧边栏用户菜单,新增个人中心跳转入口 --- src-tauri/Cargo.lock | 82 +++++ src-tauri/Cargo.toml | 5 + src-tauri/build.rs | 3 +- src-tauri/src/commands/menu.rs | 2 +- src-tauri/src/lib.rs | 33 +- src-tauri/src/services/s3.rs | 2 +- src/App.vue | 30 +- src/api/system/user.ts | 4 + src/layout/Index.vue | 32 +- src/layout/components/LayoutHeader.vue | 13 +- src/layout/components/LayoutSider.vue | 4 +- src/router/index.ts | 6 + src/stores/theme.ts | 21 ++ src/views/dashboard/Dashboard.vue | 32 +- src/views/home/Login.vue | 1 + src/views/system/Profile.vue | 452 +++++++++++++++++++++++++ src/views/system/SysMenu.vue | 12 +- src/views/system/SysRole.vue | 14 +- src/views/system/SysUser.vue | 16 +- 19 files changed, 688 insertions(+), 76 deletions(-) create mode 100644 src/stores/theme.ts create mode 100644 src/views/system/Profile.vue diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 06c604f..1644c14 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -17,6 +17,7 @@ dependencies = [ "sysinfo", "tauri", "tauri-build", + "tauri-helper", "tauri-plugin-opener", ] @@ -1204,6 +1205,25 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-deque" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-queue" version = "0.3.13" @@ -3827,6 +3847,26 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" +[[package]] +name = "rayon" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -5044,6 +5084,21 @@ dependencies = [ "walkdir", ] +[[package]] +name = "tauri-helper" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b6ed54c4a04e658f8f1c57513abbeb5e2493c9db1d31987c9cc6db6c19a245c" +dependencies = [ + "rayon", + "serde", + "syn 2.0.119", + "tauri_helper_core", + "tauri_helper_macros", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + [[package]] name = "tauri-macros" version = "2.6.3" @@ -5196,6 +5251,33 @@ dependencies = [ "toml 1.1.3+spec-1.1.0", ] +[[package]] +name = "tauri_helper_core" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6da0ac433082491b94f3ba7f5087ee888608917bd371bb213ac16bc722547541" +dependencies = [ + "serde", + "toml 0.9.12+spec-1.1.0", +] + +[[package]] +name = "tauri_helper_macros" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6da533f4bd8a64d991a8ebca6abc2243d12eae7190c69ccdfa3483f82080b9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "serde", + "syn 2.0.119", + "tauri_helper_core", + "thiserror 2.0.19", + "toml 0.9.12+spec-1.1.0", + "walkdir", +] + [[package]] name = "tempfile" version = "3.27.0" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 57850a1..3641771 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -14,8 +14,12 @@ edition = "2021" name = "DevBox_lib" crate-type = ["staticlib", "cdylib", "rlib"] +[workspace] +members = ["."] + [build-dependencies] tauri-build = { version = "2", features = [] } +tauri-helper = "0.2.1" [dependencies] tauri = { version = "2", features = [] } @@ -34,3 +38,4 @@ aws-sdk-s3 = "1.140.0" aws-config = {version = "1.10.1", features = ["behavior-version-latest"] } aws-credential-types = "1.3.0" aws-types = "1.5.0" +tauri-helper = "0.2.1" diff --git a/src-tauri/build.rs b/src-tauri/build.rs index d860e1e..86fb009 100644 --- a/src-tauri/build.rs +++ b/src-tauri/build.rs @@ -1,3 +1,4 @@ fn main() { - tauri_build::build() + // tauri_build::build() + tauri_helper::generate_command_file(tauri_helper::TauriHelperOptions::default()); } diff --git a/src-tauri/src/commands/menu.rs b/src-tauri/src/commands/menu.rs index 7b648ee..eb6a7e0 100644 --- a/src-tauri/src/commands/menu.rs +++ b/src-tauri/src/commands/menu.rs @@ -188,7 +188,7 @@ pub async fn menu_update( pool: State<'_, MySqlPool>, params: MenuSaveReq, ) -> Result, String> { - let result = sqlx::query("UPDATE sys_menu SET parent_id = ?, name = ?, title = ?, path = ?, component = ?, icon = ?, perms = ?, menu_type = ?, sort = ?, visible = ?, status = ? WHERE id = ?") + sqlx::query("UPDATE sys_menu SET parent_id = ?, name = ?, title = ?, path = ?, component = ?, icon = ?, perms = ?, menu_type = ?, sort = ?, visible = ?, status = ? WHERE id = ?") .bind(params.parent_id) .bind(params.name) .bind(params.title) diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 5e33166..4abeb79 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -25,22 +25,23 @@ pub fn run() { app.manage(s3_client); Ok(()) }) - .invoke_handler(tauri::generate_handler![ - commands::user::login, - commands::user::get_user_page, - commands::user::register, - commands::user::del_user, - commands::user::update_user, - commands::user::get_user_by_id, - commands::role::role_save, - commands::role::role_page, - commands::role::role_update, - commands::role::role_del, - commands::menu::menu_list, - commands::menu::menu_save, - commands::menu::menu_update, - commands::menu::menu_del, - ]) + .invoke_handler(tauri_helper::tauri_collect_commands!()) + // .invoke_handler(tauri::generate_handler![ + // commands::user::login, + // commands::user::get_user_page, + // commands::user::register, + // commands::user::del_user, + // commands::user::update_user, + // commands::user::get_user_by_id, + // commands::role::role_save, + // commands::role::role_page, + // commands::role::role_update, + // commands::role::role_del, + // commands::menu::menu_list, + // commands::menu::menu_save, + // commands::menu::menu_update, + // commands::menu::menu_del, + // ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/src-tauri/src/services/s3.rs b/src-tauri/src/services/s3.rs index 2dfe27b..2b38afb 100644 --- a/src-tauri/src/services/s3.rs +++ b/src-tauri/src/services/s3.rs @@ -1,6 +1,6 @@ use aws_credential_types::Credentials as AwsCreds; use aws_sdk_s3::{ - config::{BehaviorVersion, Credentials, Region}, + config::{BehaviorVersion, Region}, Client, }; diff --git a/src/App.vue b/src/App.vue index bdc3025..68120f7 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,14 +1,30 @@ diff --git a/src/views/system/SysMenu.vue b/src/views/system/SysMenu.vue index 8ed4aa3..53b7adc 100644 --- a/src/views/system/SysMenu.vue +++ b/src/views/system/SysMenu.vue @@ -344,21 +344,21 @@ function handleDelete(row: MenuInfo) { font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 22px; font-weight: 700; - color: #1D2129; + color: var(--color-text, #1D2129); letter-spacing: -0.3px; } .search-bar { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; padding: 14px 18px; margin-bottom: 16px; } .table-card { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; overflow: hidden; } @@ -367,8 +367,6 @@ function handleDelete(row: MenuInfo) { --n-th-padding: 12px 16px; --n-td-padding: 10px 16px; --n-th-font-weight: 600; - --n-th-color: #F7F8FA; - --n-td-color-striped: #FAFBFC; } @media (max-width: 768px) { diff --git a/src/views/system/SysRole.vue b/src/views/system/SysRole.vue index d76a2ed..21c1b89 100644 --- a/src/views/system/SysRole.vue +++ b/src/views/system/SysRole.vue @@ -230,21 +230,21 @@ function handleDelete(row: RoleInfo) { font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 22px; font-weight: 700; - color: #1D2129; + color: var(--color-text, #1D2129); letter-spacing: -0.3px; } .search-bar { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; padding: 14px 18px; margin-bottom: 16px; } .table-card { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; overflow: hidden; } @@ -253,8 +253,6 @@ function handleDelete(row: RoleInfo) { --n-th-padding: 12px 16px; --n-td-padding: 10px 16px; --n-th-font-weight: 600; - --n-th-color: #F7F8FA; - --n-td-color-striped: #FAFBFC; } .table-footer { @@ -262,7 +260,7 @@ function handleDelete(row: RoleInfo) { align-items: center; justify-content: space-between; padding: 14px 20px; - border-top: 1px solid #E5E6EB; + border-top: 1px solid var(--color-border, #E5E6EB); } .total-hint { diff --git a/src/views/system/SysUser.vue b/src/views/system/SysUser.vue index 79fd562..af1faa3 100644 --- a/src/views/system/SysUser.vue +++ b/src/views/system/SysUser.vue @@ -345,21 +345,21 @@ function handleDelete(row: UserInfo) { font-family: 'Space Grotesk', system-ui, sans-serif; font-size: 22px; font-weight: 700; - color: #1D2129; + color: var(--color-text, #1D2129); letter-spacing: -0.3px; } .search-bar { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; padding: 14px 18px; margin-bottom: 16px; } .table-card { - background: #fff; - border: 1px solid #E5E6EB; + background: var(--color-surface, #fff); + border: 1px solid var(--color-border, #E5E6EB); border-radius: 10px; overflow: hidden; } @@ -368,8 +368,6 @@ function handleDelete(row: UserInfo) { --n-th-padding: 12px 16px; --n-td-padding: 10px 16px; --n-th-font-weight: 600; - --n-th-color: #F7F8FA; - --n-td-color-striped: #FAFBFC; } .table-footer { @@ -377,12 +375,12 @@ function handleDelete(row: UserInfo) { align-items: center; justify-content: space-between; padding: 14px 20px; - border-top: 1px solid #E5E6EB; + border-top: 1px solid var(--color-border, #E5E6EB); } .total-hint { font-size: 13px; - color: #86909C; + color: var(--color-text-secondary, #86909C); } @media (max-width: 768px) {