235 lines
8.0 KiB
Rust
235 lines
8.0 KiB
Rust
use tauri::{command, State};
|
||
use crate::app_state::AppState;
|
||
use crate::business::services::video_generation_service::{VideoGenerationService, VideoGenerationStatistics};
|
||
use crate::data::models::video_generation::{
|
||
VideoGenerationTask, VideoGenerationQueryParams, CreateVideoGenerationRequest
|
||
};
|
||
|
||
/// 创建视频生成任务命令
|
||
/// 遵循 Tauri 开发规范的命令设计模式
|
||
#[command]
|
||
pub async fn create_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
request: CreateVideoGenerationRequest,
|
||
) -> Result<VideoGenerationTask, String> {
|
||
// 克隆仓库引用以避免跨await边界的Send问题
|
||
let (video_gen_repo, model_repo) = {
|
||
let video_gen_repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let video_gen_repository = video_gen_repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
let model_repository_guard = state.get_model_repository()
|
||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
||
|
||
let model_repository = model_repository_guard.as_ref()
|
||
.ok_or("模特仓库未初始化")?;
|
||
|
||
// 这里我们需要克隆仓库,但由于仓库包含Arc,这应该是轻量级的
|
||
(video_gen_repository.clone(), model_repository.clone())
|
||
};
|
||
|
||
VideoGenerationService::create_task(&video_gen_repo, &model_repo, request)
|
||
.await
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 执行视频生成任务命令
|
||
#[command]
|
||
pub async fn execute_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
task_id: String,
|
||
) -> Result<VideoGenerationTask, String> {
|
||
let (video_gen_repo, model_repo) = {
|
||
let video_gen_repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let video_gen_repository = video_gen_repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
let model_repository_guard = state.get_model_repository()
|
||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
||
|
||
let model_repository = model_repository_guard.as_ref()
|
||
.ok_or("模特仓库未初始化")?;
|
||
|
||
(video_gen_repository.clone(), model_repository.clone())
|
||
};
|
||
|
||
VideoGenerationService::execute_task(&video_gen_repo, &model_repo, &task_id)
|
||
.await
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 获取视频生成任务命令
|
||
#[command]
|
||
pub async fn get_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
task_id: String,
|
||
) -> Result<Option<VideoGenerationTask>, String> {
|
||
let repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
VideoGenerationService::get_task(repository, &task_id)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 获取视频生成任务列表命令
|
||
#[command]
|
||
pub async fn get_video_generation_tasks(
|
||
state: State<'_, AppState>,
|
||
params: VideoGenerationQueryParams,
|
||
) -> Result<Vec<VideoGenerationTask>, String> {
|
||
let repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
VideoGenerationService::get_tasks(repository, ¶ms)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 取消视频生成任务命令
|
||
#[command]
|
||
pub async fn cancel_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
task_id: String,
|
||
) -> Result<VideoGenerationTask, String> {
|
||
let repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
VideoGenerationService::cancel_task(repository, &task_id)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 删除视频生成任务命令
|
||
#[command]
|
||
pub async fn delete_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
task_id: String,
|
||
) -> Result<(), String> {
|
||
let repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
VideoGenerationService::delete_task(repository, &task_id)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 重试视频生成任务命令
|
||
#[command]
|
||
pub async fn retry_video_generation_task(
|
||
state: State<'_, AppState>,
|
||
task_id: String,
|
||
) -> Result<VideoGenerationTask, String> {
|
||
let (video_gen_repo, model_repo) = {
|
||
let video_gen_repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let video_gen_repository = video_gen_repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
let model_repository_guard = state.get_model_repository()
|
||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
||
|
||
let model_repository = model_repository_guard.as_ref()
|
||
.ok_or("模特仓库未初始化")?;
|
||
|
||
(video_gen_repository.clone(), model_repository.clone())
|
||
};
|
||
|
||
VideoGenerationService::retry_task(&video_gen_repo, &model_repo, &task_id)
|
||
.await
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 获取模特视频生成统计命令
|
||
#[command]
|
||
pub async fn get_model_video_generation_statistics(
|
||
state: State<'_, AppState>,
|
||
model_id: String,
|
||
) -> Result<VideoGenerationStatistics, String> {
|
||
let repository_guard = state.get_video_generation_repository()
|
||
.map_err(|e| format!("获取视频生成仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("视频生成仓库未初始化")?;
|
||
|
||
VideoGenerationService::get_model_statistics(repository, &model_id)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 获取模特详情(包含照片)命令
|
||
#[command]
|
||
pub async fn get_model_detail_with_photos(
|
||
state: State<'_, AppState>,
|
||
model_id: String,
|
||
) -> Result<Option<crate::data::models::model::Model>, String> {
|
||
let repository_guard = state.get_model_repository()
|
||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("模特仓库未初始化")?;
|
||
|
||
// 使用完整的get_by_id方法获取包含照片的模特信息
|
||
repository.get_by_id(&model_id)
|
||
.map_err(|e| e.to_string())
|
||
}
|
||
|
||
/// 批量上传模特照片命令(上传到云端)
|
||
#[command]
|
||
pub async fn batch_upload_model_photos(
|
||
state: State<'_, AppState>,
|
||
model_id: String,
|
||
file_paths: Vec<String>,
|
||
photo_type: crate::data::models::model::PhotoType,
|
||
description: Option<String>,
|
||
tags: Option<Vec<String>>,
|
||
) -> Result<Vec<crate::data::models::model::ModelPhoto>, String> {
|
||
// 克隆仓库引用以避免跨await边界的Send问题
|
||
let repository = {
|
||
let repository_guard = state.get_model_repository()
|
||
.map_err(|e| format!("获取模特仓库失败: {}", e))?;
|
||
|
||
let repository = repository_guard.as_ref()
|
||
.ok_or("模特仓库未初始化")?;
|
||
|
||
repository.clone()
|
||
};
|
||
|
||
let mut uploaded_photos = Vec::new();
|
||
|
||
for file_path in file_paths {
|
||
match crate::business::services::model_service::ModelService::add_model_photo_with_cloud_upload(
|
||
&repository,
|
||
&model_id,
|
||
file_path,
|
||
photo_type.clone(),
|
||
description.clone(),
|
||
tags.clone(),
|
||
).await {
|
||
Ok(photo) => uploaded_photos.push(photo),
|
||
Err(e) => {
|
||
println!("⚠️ 上传照片失败: {}", e);
|
||
// 继续上传其他照片,不中断整个过程
|
||
}
|
||
}
|
||
}
|
||
|
||
if uploaded_photos.is_empty() {
|
||
return Err("没有成功上传任何照片".to_string());
|
||
}
|
||
|
||
Ok(uploaded_photos)
|
||
}
|