mixvideo-v2/apps/desktop/src-tauri/src/presentation/commands/similarity_search_commands.rs

150 lines
4.7 KiB
Rust

use tauri::{command, State};
use crate::app_state::AppState;
use crate::data::models::outfit_search::{SearchRequest, SearchResponse, SearchConfig, RelevanceThreshold};
use crate::presentation::commands::outfit_search_commands::search_similar_outfits;
/// 相似度检索工具命令
/// 遵循 Tauri 开发规范的命令设计模式
/// 基于现有的 search_similar_outfits 功能,提供简化的接口
/// 快速相似度搜索
/// 使用预设配置进行简化搜索
#[command]
pub async fn quick_similarity_search(
state: State<'_, AppState>,
query: String,
relevance_threshold: Option<String>,
) -> Result<SearchResponse, String> {
// 构建默认搜索配置
let threshold = match relevance_threshold.as_deref() {
Some("LOWEST") => RelevanceThreshold::Lowest,
Some("LOW") => RelevanceThreshold::Low,
Some("MEDIUM") => RelevanceThreshold::Medium,
Some("HIGH") => RelevanceThreshold::High,
_ => RelevanceThreshold::Medium, // 默认使用中等阈值
};
let config = SearchConfig {
relevance_threshold: threshold,
environments: Vec::new(),
categories: Vec::new(),
color_filters: std::collections::HashMap::new(),
design_styles: std::collections::HashMap::new(),
max_keywords: 10,
};
let request = SearchRequest {
query,
config,
page_size: 12, // 工具页面显示更多结果
page_offset: 0,
};
// 复用现有的搜索功能
search_similar_outfits(state, request).await
}
/// 获取搜索建议(简化版)
#[command]
pub async fn get_similarity_search_suggestions(
_state: State<'_, AppState>,
query: String,
) -> Result<Vec<String>, String> {
// 基础搜索建议
let base_suggestions = vec![
"休闲搭配".to_string(),
"正式搭配".to_string(),
"运动风格".to_string(),
"街头风格".to_string(),
"简约风格".to_string(),
"复古风格".to_string(),
"牛仔裤搭配".to_string(),
"连衣裙搭配".to_string(),
"外套搭配".to_string(),
"夏季搭配".to_string(),
"冬季搭配".to_string(),
"约会搭配".to_string(),
"工作搭配".to_string(),
"聚会搭配".to_string(),
];
if query.is_empty() {
return Ok(base_suggestions);
}
// 基于查询过滤建议
let filtered_suggestions: Vec<String> = base_suggestions
.iter()
.filter(|suggestion| {
suggestion.contains(&query) ||
query.chars().any(|c| suggestion.contains(c))
})
.cloned()
.collect();
// 如果没有匹配的建议,返回基础建议的前几个
if filtered_suggestions.is_empty() {
Ok(base_suggestions.into_iter().take(6).collect())
} else {
Ok(filtered_suggestions.into_iter().take(8).collect())
}
}
/// 获取相似度检索工具配置信息
#[command]
pub async fn get_similarity_search_config(
_state: State<'_, AppState>,
) -> Result<SimilaritySearchConfig, String> {
Ok(SimilaritySearchConfig {
available_thresholds: vec![
ThresholdOption {
value: "LOWEST".to_string(),
label: "最低 (0.3)".to_string(),
description: "显示更多相关结果".to_string(),
},
ThresholdOption {
value: "LOW".to_string(),
label: "较低 (0.5)".to_string(),
description: "包含较多相关结果".to_string(),
},
ThresholdOption {
value: "MEDIUM".to_string(),
label: "中等 (0.7)".to_string(),
description: "平衡相关性和数量".to_string(),
},
ThresholdOption {
value: "HIGH".to_string(),
label: "较高 (0.9)".to_string(),
description: "只显示高度相关结果".to_string(),
},
],
default_threshold: "MEDIUM".to_string(),
max_results_per_page: 12,
quick_search_tags: vec![
"休闲".to_string(),
"正式".to_string(),
"运动".to_string(),
"街头".to_string(),
"简约".to_string(),
"复古".to_string(),
],
})
}
/// 相似度检索工具配置
#[derive(serde::Serialize)]
pub struct SimilaritySearchConfig {
pub available_thresholds: Vec<ThresholdOption>,
pub default_threshold: String,
pub max_results_per_page: usize,
pub quick_search_tags: Vec<String>,
}
/// 阈值选项
#[derive(serde::Serialize)]
pub struct ThresholdOption {
pub value: String,
pub label: String,
pub description: String,
}