Files
mixvideo-v2/apps/desktop/src-tauri/src/presentation/commands/system_commands.rs
imeepos 42c5dcef8e feat: 实现项目管理功能 v0.1.1
新功能:
- 项目创建:支持项目名称和本地路径绑定
- 项目列表:简洁大方的卡片式布局展示
- 项目编辑:支持项目信息修改
- 项目删除:支持项目软删除
- 路径选择:集成系统文件夹选择对话框
- 路径验证:实时验证项目路径有效性

 架构设计:
- 遵循 Tauri 开发规范的四层架构设计
- 基础设施层:数据库管理、文件系统操作
- 数据访问层:项目仓库模式、SQLite 集成
- 业务逻辑层:项目服务、数据验证
- 表示层:Tauri 命令、前端组件

 UI/UX:
- 使用 Tailwind CSS 实现简洁大方的设计风格
- 响应式布局适配不同屏幕尺寸
- 流畅的动画效果和交互反馈
- 完整的错误处理和用户提示

 技术栈:
- 后端:Rust + Tauri + SQLite + 四层架构
- 前端:React + TypeScript + Tailwind CSS + Zustand
- 测试:Rust 单元测试 + Vitest 前端测试
- 工具:pnpm 包管理 + 类型安全保证

 质量保证:
- Rust 单元测试覆盖核心业务逻辑
- 前端组件测试覆盖主要 UI 组件
- TypeScript 严格模式确保类型安全
- 遵循开发规范的代码质量标准

 核心特性:
- 项目管理:创建、查看、编辑、删除项目
- 路径管理:自动验证、绝对路径转换
- 数据持久化:SQLite 本地数据库存储
- 状态管理:Zustand 响应式状态管理
- 错误处理:完整的错误捕获和用户反馈
2025-07-13 18:46:58 +08:00

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()),
}
}