新功能: - 项目创建:支持项目名称和本地路径绑定 - 项目列表:简洁大方的卡片式布局展示 - 项目编辑:支持项目信息修改 - 项目删除:支持项目软删除 - 路径选择:集成系统文件夹选择对话框 - 路径验证:实时验证项目路径有效性 架构设计: - 遵循 Tauri 开发规范的四层架构设计 - 基础设施层:数据库管理、文件系统操作 - 数据访问层:项目仓库模式、SQLite 集成 - 业务逻辑层:项目服务、数据验证 - 表示层:Tauri 命令、前端组件 UI/UX: - 使用 Tailwind CSS 实现简洁大方的设计风格 - 响应式布局适配不同屏幕尺寸 - 流畅的动画效果和交互反馈 - 完整的错误处理和用户提示 技术栈: - 后端:Rust + Tauri + SQLite + 四层架构 - 前端:React + TypeScript + Tailwind CSS + Zustand - 测试:Rust 单元测试 + Vitest 前端测试 - 工具:pnpm 包管理 + 类型安全保证 质量保证: - Rust 单元测试覆盖核心业务逻辑 - 前端组件测试覆盖主要 UI 组件 - TypeScript 严格模式确保类型安全 - 遵循开发规范的代码质量标准 核心特性: - 项目管理:创建、查看、编辑、删除项目 - 路径管理:自动验证、绝对路径转换 - 数据持久化:SQLite 本地数据库存储 - 状态管理:Zustand 响应式状态管理 - 错误处理:完整的错误捕获和用户反馈
69 lines
1.9 KiB
Rust
69 lines
1.9 KiB
Rust
use tauri::{command, AppHandle};
|
|
use serde::{Deserialize, Serialize};
|
|
|
|
/// 应用信息结构
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
pub struct AppInfo {
|
|
pub name: String,
|
|
pub version: String,
|
|
pub platform: String,
|
|
}
|
|
|
|
/// 选择目录命令
|
|
/// 遵循 Tauri 开发规范的系统集成设计
|
|
#[command]
|
|
pub fn select_directory(app: AppHandle) -> Result<Option<String>, String> {
|
|
use tauri_plugin_dialog::DialogExt;
|
|
|
|
// 使用同步方式打开文件夹选择对话框
|
|
let dialog = app.dialog().file().set_title("选择项目目录");
|
|
|
|
// 创建一个简单的阻塞实现
|
|
let (tx, rx) = std::sync::mpsc::channel();
|
|
|
|
dialog.pick_folder(move |folder_path| {
|
|
let _ = tx.send(folder_path);
|
|
});
|
|
|
|
// 等待结果,设置超时
|
|
match rx.recv_timeout(std::time::Duration::from_secs(30)) {
|
|
Ok(Some(path)) => {
|
|
let path_str = path.to_string();
|
|
Ok(Some(path_str))
|
|
}
|
|
Ok(None) => Ok(None),
|
|
Err(_) => Err("对话框操作超时或失败".to_string()),
|
|
}
|
|
}
|
|
|
|
/// 获取应用信息命令
|
|
#[command]
|
|
pub async fn get_app_info() -> Result<AppInfo, String> {
|
|
Ok(AppInfo {
|
|
name: "MixVideo Desktop".to_string(),
|
|
version: env!("CARGO_PKG_VERSION").to_string(),
|
|
platform: std::env::consts::OS.to_string(),
|
|
})
|
|
}
|
|
|
|
/// 验证目录是否存在命令
|
|
#[command]
|
|
pub async fn validate_directory(path: String) -> Result<bool, String> {
|
|
use std::path::Path;
|
|
|
|
let path = Path::new(&path);
|
|
Ok(path.exists() && path.is_dir())
|
|
}
|
|
|
|
/// 获取目录名称命令
|
|
#[command]
|
|
pub async fn get_directory_name(path: String) -> Result<String, String> {
|
|
use std::path::Path;
|
|
|
|
let path = Path::new(&path);
|
|
match path.file_name() {
|
|
Some(name) => Ok(name.to_string_lossy().to_string()),
|
|
None => Err("无效的目录路径".to_string()),
|
|
}
|
|
}
|