feat: 新增设置页面及外观设置功能

添加了设置页面路由、外观设置子页面,支持主题模式切换和自定义窗口背景图片,新增相关 Rust 后端模块、数据库初始化、多语言文案及配置项,更新 Tauri 配置和项目描述。
This commit is contained in:
Yuhang Wu
2026-10-13 11:15:58 +08:00
parent d4257481f4
commit fd47adea1e
24 changed files with 6673 additions and 38 deletions
+6224
View File
File diff suppressed because it is too large Load Diff
+19 -3
View File
@@ -1,8 +1,8 @@
[package]
name = "frpilot"
version = "0.1.0"
description = "A Tauri App"
authors = ["you"]
description = "一个基于 Tauri 2 + Vue 3 + TypeScript 的 [frp](https://github.com/fatedier/frp) 可视化客户端,帮助用户快速配置 frpc 版本、服务器与隧道。"
authors = ["SparksFly"]
edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,15 +14,31 @@ edition = "2024"
name = "frpilot_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 = [] }
tauri-plugin-opener = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-store = "2.4.4"
tauri-helper = "0.2.1"
sqlx = { version = "0.9.0", features = [
"runtime-tokio",
"sqlite",
"tls-native-tls",
"chrono",
] }
chrono = { version = "0.4.45", features = ["serde"] }
tauri-plugin-dialog = "2.7.2"
tauri-plugin-updater = "2.10.1"
tauri-plugin-process = "2.3.1"
tauri-plugin-prevent-default = "6.0.1"
# Read the optimization guideline for more details: https://tauri.app/concept/size/#cargo-configuration
[profile.release]
+1
View File
@@ -1,3 +1,4 @@
fn main() {
tauri_helper::generate_command_file(tauri_helper::TauriHelperOptions::default());
tauri_build::build()
}
+2
View File
@@ -0,0 +1,2 @@
pub mod tunnel;
pub mod server;
+11
View File
@@ -0,0 +1,11 @@
use sqlx::SqlitePool;
use tauri::State;
use tauri_helper::auto_collect_command;
use crate::models::{ApiResponse};
#[tauri::command]
#[auto_collect_command]
pub async fn get_server_list(state: State<'_, SqlitePool>) -> Result<ApiResponse<()>, String> {
Ok(ApiResponse::success_empty())
}
View File
+25 -6
View File
@@ -1,14 +1,33 @@
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
mod commands;
mod models;
mod services;
use tauri::Manager;
use crate::commands::server::get_server_list;
use crate::services::db::init_pool;
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.invoke_handler(tauri::generate_handler![greet])
.plugin(tauri_plugin_dialog::init()) // 对话框插件
.plugin(tauri_plugin_updater::Builder::new().build()) // 更新插件
.plugin(tauri_plugin_process::init()) // 进程插件(更新后重启)
.plugin(tauri_plugin_prevent_default::Builder::new().build())
.setup(|app| {
let pool = tauri::async_runtime::block_on(async {
init_pool(app.handle())
.await
.expect("sqlite数据库连接池初始化失败!")
});
app.manage(pool);
Ok(())
})
.plugin(tauri_plugin_store::Builder::default().build())
// .invoke_handler(tauri::generate_handler![greet])
.invoke_handler(tauri_helper::tauri_collect_commands!())
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
+50
View File
@@ -0,0 +1,50 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct PageResult<T> {
pub total: i64,
pub list: Vec<T>,
pub page: i32,
pub page_size: i32,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ApiResponse<T> {
success: bool,
code: i32,
msg: String,
data: Option<T>,
}
impl<T> ApiResponse<T> {
// 成功响应
pub fn success(data: T) -> Self {
Self {
success: true,
code: 0,
msg: "操作成功".to_string(),
data: Some(data),
}
}
// 错误响应
pub fn error(code: i32, message: &str) -> Self {
Self {
success: false,
code,
msg: message.to_string(),
data: None,
}
}
}
impl ApiResponse<()> {
// 成功响应,数据为空
pub fn success_empty() -> Self {
Self {
success: true,
code: 0,
msg: "操作成功".to_string(),
data: None,
}
}
}
+20
View File
@@ -0,0 +1,20 @@
use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions};
use tauri::{AppHandle, Manager};
pub async fn init_pool(app: &AppHandle) -> Result<SqlitePool, sqlx::Error> {
// 数据库文件路径
let app_dir = app.path().app_data_dir().expect("无法获取APP数据目录");
std::fs::create_dir_all(&app_dir).unwrap();
let db_path = app_dir.join("reader.db");
// 初始化数据库连接池
let options = SqliteConnectOptions::new()
.filename(&db_path)
.create_if_missing(true);
let pool = SqlitePoolOptions::new()
.max_connections(5)
.min_connections(1)
.connect_with(options)
.await?;
Ok(pool)
}
+1
View File
@@ -0,0 +1 @@
pub mod db;
+9 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "frpilot",
"version": "0.1.0",
"version": "../package.json",
"identifier": "frpilot",
"build": {
"beforeDevCommand": "pnpm dev",
@@ -35,5 +35,13 @@
"icons/icon.icns",
"icons/icon.ico"
]
},
"plugins": {
"updater": {
"active": true,
"dialog": true,
"endpoints": ["https://ghproxy.net/https://github.com/SparksFly91/Frpilot/releases/latest/download/latest.json"],
"pubkey": ""
}
}
}