From 0883674877d26eba1511dc08ab22e9937455367e Mon Sep 17 00:00:00 2001 From: imeepos Date: Thu, 17 Jul 2025 21:01:37 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/desktop/src-tauri/src/data/models/mod.rs | 3 - .../src/data/models/outfit_analysis.rs | 206 --------------- .../src-tauri/src/data/models/outfit_item.rs | 237 ------------------ .../src/data/models/outfit_matching.rs | 237 ------------------ .../src-tauri/src/infrastructure/database.rs | 130 ---------- 5 files changed, 813 deletions(-) delete mode 100644 apps/desktop/src-tauri/src/data/models/outfit_analysis.rs delete mode 100644 apps/desktop/src-tauri/src/data/models/outfit_item.rs delete mode 100644 apps/desktop/src-tauri/src/data/models/outfit_matching.rs diff --git a/apps/desktop/src-tauri/src/data/models/mod.rs b/apps/desktop/src-tauri/src/data/models/mod.rs index 2c5c1ef..8be0d13 100644 --- a/apps/desktop/src-tauri/src/data/models/mod.rs +++ b/apps/desktop/src-tauri/src/data/models/mod.rs @@ -10,6 +10,3 @@ pub mod project_template_binding; pub mod template_matching_result; pub mod export_record; pub mod video_generation; -pub mod outfit_analysis; -pub mod outfit_item; -pub mod outfit_matching; diff --git a/apps/desktop/src-tauri/src/data/models/outfit_analysis.rs b/apps/desktop/src-tauri/src/data/models/outfit_analysis.rs deleted file mode 100644 index 85c5197..0000000 --- a/apps/desktop/src-tauri/src/data/models/outfit_analysis.rs +++ /dev/null @@ -1,206 +0,0 @@ -use serde::{Deserialize, Serialize}; -use chrono::{DateTime, Utc}; - -/// HSV颜色模型 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct ColorHSV { - pub hue: f64, // 色相 (0.0-1.0) - pub saturation: f64, // 饱和度 (0.0-1.0) - pub value: f64, // 明度 (0.0-1.0) -} - -impl ColorHSV { - pub fn new(hue: f64, saturation: f64, value: f64) -> Self { - Self { - hue: hue.clamp(0.0, 1.0), - saturation: saturation.clamp(0.0, 1.0), - value: value.clamp(0.0, 1.0), - } - } - - /// 转换为RGB十六进制字符串 - pub fn to_rgb_hex(&self) -> String { - let (r, g, b) = hsv_to_rgb(self.hue, self.saturation, self.value); - format!("#{:02x}{:02x}{:02x}", - (r * 255.0) as u8, - (g * 255.0) as u8, - (b * 255.0) as u8) - } - - /// 从RGB十六进制字符串创建 - pub fn from_rgb_hex(hex: &str) -> Result { - let hex = hex.trim_start_matches('#'); - if hex.len() != 6 { - return Err("Invalid hex color format".to_string()); - } - - let r = u8::from_str_radix(&hex[0..2], 16).map_err(|_| "Invalid red component")?; - let g = u8::from_str_radix(&hex[2..4], 16).map_err(|_| "Invalid green component")?; - let b = u8::from_str_radix(&hex[4..6], 16).map_err(|_| "Invalid blue component")?; - - let (h, s, v) = rgb_to_hsv(r as f64 / 255.0, g as f64 / 255.0, b as f64 / 255.0); - Ok(Self::new(h, s, v)) - } - - /// 计算与另一个颜色的相似度 (0.0-1.0) - pub fn similarity(&self, other: &ColorHSV) -> f64 { - let hue_diff = (self.hue - other.hue).abs().min(1.0 - (self.hue - other.hue).abs()); - let sat_diff = (self.saturation - other.saturation).abs(); - let val_diff = (self.value - other.value).abs(); - - // 加权计算相似度,色相权重最高 - let similarity = 1.0 - (hue_diff * 0.5 + sat_diff * 0.3 + val_diff * 0.2); - similarity.clamp(0.0, 1.0) - } -} - -/// 分析状态枚举 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum AnalysisStatus { - Pending, // 待分析 - Processing, // 分析中 - Completed, // 已完成 - Failed, // 分析失败 -} - -impl Default for AnalysisStatus { - fn default() -> Self { - Self::Pending - } -} - -/// 服装项目信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitProduct { - pub category: String, // 服装类别 (如: "牛仔裤", "T恤") - pub description: String, // 描述 - pub color_pattern: ColorHSV, // 主色调 - pub design_styles: Vec, // 设计风格标签 - pub color_pattern_match_dress: f64, // 与整体搭配的颜色匹配度 (0.0-1.0) - pub color_pattern_match_environment: f64, // 与环境的颜色匹配度 (0.0-1.0) -} - -/// 图像分析结果 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ImageAnalysisResult { - pub environment_tags: Vec, // 环境标签 - pub environment_color_pattern: ColorHSV, // 环境色调 - pub dress_color_pattern: ColorHSV, // 整体搭配色调 - pub style_description: String, // 风格描述 - pub products: Vec, // 识别到的服装项目 -} - -/// 服装分析记录 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitAnalysis { - pub id: String, - pub project_id: String, - pub image_path: String, // 原始图像路径 - pub image_name: String, // 图像名称 - pub analysis_status: AnalysisStatus, // 分析状态 - pub analysis_result: Option, // 分析结果 - pub error_message: Option, // 错误信息 - pub created_at: DateTime, - pub updated_at: DateTime, - pub analyzed_at: Option>, -} - -/// 创建分析请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateOutfitAnalysisRequest { - pub project_id: String, - pub image_path: String, - pub image_name: String, -} - -/// 更新分析请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UpdateOutfitAnalysisRequest { - pub analysis_status: Option, - pub analysis_result: Option, - pub error_message: Option, -} - -/// 分析查询选项 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitAnalysisQueryOptions { - pub project_id: Option, - pub status: Option, - pub limit: Option, - pub offset: Option, -} - -/// 分析统计信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitAnalysisStats { - pub total_count: u32, - pub pending_count: u32, - pub processing_count: u32, - pub completed_count: u32, - pub failed_count: u32, -} - -// HSV和RGB转换函数 -fn hsv_to_rgb(h: f64, s: f64, v: f64) -> (f64, f64, f64) { - let c = v * s; - let x = c * (1.0 - ((h * 6.0) % 2.0 - 1.0).abs()); - let m = v - c; - - let (r_prime, g_prime, b_prime) = match (h * 6.0) as i32 { - 0 => (c, x, 0.0), - 1 => (x, c, 0.0), - 2 => (0.0, c, x), - 3 => (0.0, x, c), - 4 => (x, 0.0, c), - 5 => (c, 0.0, x), - _ => (0.0, 0.0, 0.0), - }; - - (r_prime + m, g_prime + m, b_prime + m) -} - -fn rgb_to_hsv(r: f64, g: f64, b: f64) -> (f64, f64, f64) { - let max = r.max(g).max(b); - let min = r.min(g).min(b); - let delta = max - min; - - let h = if delta == 0.0 { - 0.0 - } else if max == r { - ((g - b) / delta) % 6.0 - } else if max == g { - (b - r) / delta + 2.0 - } else { - (r - g) / delta + 4.0 - } / 6.0; - - let s = if max == 0.0 { 0.0 } else { delta / max }; - let v = max; - - (h.abs(), s, v) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_color_hsv_conversion() { - let color = ColorHSV::new(0.5, 0.8, 0.9); - let hex = color.to_rgb_hex(); - let converted = ColorHSV::from_rgb_hex(&hex).unwrap(); - - assert!((color.hue - converted.hue).abs() < 0.01); - assert!((color.saturation - converted.saturation).abs() < 0.01); - assert!((color.value - converted.value).abs() < 0.01); - } - - #[test] - fn test_color_similarity() { - let color1 = ColorHSV::new(0.5, 0.8, 0.9); - let color2 = ColorHSV::new(0.52, 0.82, 0.88); - let similarity = color1.similarity(&color2); - - assert!(similarity > 0.8); // 应该很相似 - } -} diff --git a/apps/desktop/src-tauri/src/data/models/outfit_item.rs b/apps/desktop/src-tauri/src/data/models/outfit_item.rs deleted file mode 100644 index 4f0d74e..0000000 --- a/apps/desktop/src-tauri/src/data/models/outfit_item.rs +++ /dev/null @@ -1,237 +0,0 @@ -use serde::{Deserialize, Serialize}; -use chrono::{DateTime, Utc}; -use super::outfit_analysis::ColorHSV; - -/// 服装类别枚举 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] -pub enum OutfitCategory { - Top, // 上装 (T恤、衬衫、毛衣等) - Bottom, // 下装 (裤子、裙子等) - Dress, // 连衣裙 - Outerwear, // 外套 - Footwear, // 鞋类 - Accessory, // 配饰 - Other, // 其他 -} - -impl OutfitCategory { - pub fn from_string(category: &str) -> Self { - match category.to_lowercase().as_str() { - "上装" | "t恤" | "衬衫" | "毛衣" | "背心" | "top" => Self::Top, - "下装" | "裤子" | "牛仔裤" | "短裤" | "裙子" | "bottom" => Self::Bottom, - "连衣裙" | "长裙" | "dress" => Self::Dress, - "外套" | "夹克" | "大衣" | "outerwear" => Self::Outerwear, - "鞋子" | "运动鞋" | "高跟鞋" | "footwear" => Self::Footwear, - "配饰" | "帽子" | "包包" | "首饰" | "accessory" => Self::Accessory, - _ => Self::Other, - } - } - - pub fn to_chinese(&self) -> &'static str { - match self { - Self::Top => "上装", - Self::Bottom => "下装", - Self::Dress => "连衣裙", - Self::Outerwear => "外套", - Self::Footwear => "鞋类", - Self::Accessory => "配饰", - Self::Other => "其他", - } - } -} - -/// 服装风格枚举 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] -pub enum OutfitStyle { - Casual, // 休闲 - Formal, // 正式 - Business, // 商务 - Sporty, // 运动 - Vintage, // 复古 - Bohemian, // 波西米亚 - Minimalist, // 极简 - Streetwear, // 街头 - Elegant, // 优雅 - Trendy, // 时尚 - Other(String), // 其他自定义风格 -} - -impl OutfitStyle { - pub fn from_string(style: &str) -> Self { - match style.to_lowercase().as_str() { - "casual" | "休闲" => Self::Casual, - "formal" | "正式" => Self::Formal, - "business" | "商务" => Self::Business, - "sporty" | "运动" => Self::Sporty, - "vintage" | "复古" => Self::Vintage, - "bohemian" | "波西米亚" => Self::Bohemian, - "minimalist" | "极简" => Self::Minimalist, - "streetwear" | "街头" => Self::Streetwear, - "elegant" | "优雅" => Self::Elegant, - "trendy" | "时尚" => Self::Trendy, - _ => Self::Other(style.to_string()), - } - } - - pub fn to_string(&self) -> String { - match self { - Self::Casual => "休闲".to_string(), - Self::Formal => "正式".to_string(), - Self::Business => "商务".to_string(), - Self::Sporty => "运动".to_string(), - Self::Vintage => "复古".to_string(), - Self::Bohemian => "波西米亚".to_string(), - Self::Minimalist => "极简".to_string(), - Self::Streetwear => "街头".to_string(), - Self::Elegant => "优雅".to_string(), - Self::Trendy => "时尚".to_string(), - Self::Other(s) => s.clone(), - } - } -} - -/// 服装尺寸信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitSize { - pub size_label: String, // 尺码标签 (如: "M", "L", "XL") - pub measurements: Option, // 具体尺寸 -} - -/// 具体尺寸测量 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SizeMeasurements { - pub chest: Option, // 胸围 (cm) - pub waist: Option, // 腰围 (cm) - pub hip: Option, // 臀围 (cm) - pub length: Option, // 长度 (cm) - pub sleeve: Option, // 袖长 (cm) -} - -/// 服装材质信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitMaterial { - pub fabric_type: String, // 面料类型 (如: "棉", "聚酯纤维") - pub fabric_composition: Vec, // 面料成分 - pub care_instructions: Vec, // 护理说明 -} - -/// 面料成分 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct FabricComponent { - pub material: String, // 材料名称 - pub percentage: f64, // 百分比 -} - -/// 服装单品实体 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitItem { - pub id: String, - pub project_id: String, - pub analysis_id: Option, // 关联的分析记录ID - pub name: String, // 服装名称 - pub category: OutfitCategory, // 服装类别 - pub brand: Option, // 品牌 - pub model: Option, // 型号 - pub color_primary: ColorHSV, // 主色调 - pub color_secondary: Option, // 次要色调 - pub styles: Vec, // 风格标签 - pub design_elements: Vec, // 设计元素 (如: "条纹", "印花", "刺绣") - pub size: Option, // 尺寸信息 - pub material: Option, // 材质信息 - pub price: Option, // 价格 - pub purchase_date: Option>, // 购买日期 - pub image_urls: Vec, // 图片URL列表 - pub tags: Vec, // 自定义标签 - pub notes: Option, // 备注 - pub created_at: DateTime, - pub updated_at: DateTime, -} - -/// 创建服装单品请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateOutfitItemRequest { - pub project_id: String, - pub analysis_id: Option, - pub name: String, - pub category: OutfitCategory, - pub brand: Option, - pub model: Option, - pub color_primary: ColorHSV, - pub color_secondary: Option, - pub styles: Vec, - pub design_elements: Vec, - pub size: Option, - pub material: Option, - pub price: Option, - pub purchase_date: Option>, - pub image_urls: Vec, - pub tags: Vec, - pub notes: Option, -} - -/// 更新服装单品请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UpdateOutfitItemRequest { - pub name: Option, - pub category: Option, - pub brand: Option, - pub model: Option, - pub color_primary: Option, - pub color_secondary: Option, - pub styles: Option>, - pub design_elements: Option>, - pub size: Option, - pub material: Option, - pub price: Option, - pub purchase_date: Option>, - pub image_urls: Option>, - pub tags: Option>, - pub notes: Option, -} - -/// 服装单品查询选项 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitItemQueryOptions { - pub project_id: Option, - pub category: Option, - pub styles: Option>, - pub color_similarity_threshold: Option, // 颜色相似度阈值 - pub target_color: Option, // 目标颜色 - pub brand: Option, - pub tags: Option>, - pub limit: Option, - pub offset: Option, -} - -/// 服装单品统计信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitItemStats { - pub total_count: u32, - pub category_counts: std::collections::HashMap, - pub style_counts: std::collections::HashMap, - pub brand_counts: std::collections::HashMap, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_outfit_category_conversion() { - assert_eq!(OutfitCategory::from_string("T恤"), OutfitCategory::Top); - assert_eq!(OutfitCategory::from_string("牛仔裤"), OutfitCategory::Bottom); - assert_eq!(OutfitCategory::from_string("连衣裙"), OutfitCategory::Dress); - } - - #[test] - fn test_outfit_style_conversion() { - assert_eq!(OutfitStyle::from_string("休闲"), OutfitStyle::Casual); - assert_eq!(OutfitStyle::from_string("正式"), OutfitStyle::Formal); - - let custom_style = OutfitStyle::from_string("自定义风格"); - match custom_style { - OutfitStyle::Other(s) => assert_eq!(s, "自定义风格"), - _ => panic!("Expected Other variant"), - } - } -} diff --git a/apps/desktop/src-tauri/src/data/models/outfit_matching.rs b/apps/desktop/src-tauri/src/data/models/outfit_matching.rs deleted file mode 100644 index 1e630e3..0000000 --- a/apps/desktop/src-tauri/src/data/models/outfit_matching.rs +++ /dev/null @@ -1,237 +0,0 @@ -use serde::{Deserialize, Serialize}; -use chrono::{DateTime, Utc}; -use super::outfit_analysis::ColorHSV; -use super::outfit_item::{OutfitCategory, OutfitStyle}; - -/// 匹配类型枚举 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum MatchingType { - ColorHarmony, // 颜色和谐搭配 - StyleConsistent, // 风格一致搭配 - Complementary, // 互补搭配 - Seasonal, // 季节性搭配 - Occasion, // 场合搭配 - Trendy, // 时尚搭配 -} - -impl MatchingType { - pub fn to_chinese(&self) -> &'static str { - match self { - Self::ColorHarmony => "颜色和谐", - Self::StyleConsistent => "风格一致", - Self::Complementary => "互补搭配", - Self::Seasonal => "季节搭配", - Self::Occasion => "场合搭配", - Self::Trendy => "时尚搭配", - } - } -} - -/// 匹配置信度等级 -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub enum ConfidenceLevel { - Low, // 低 (0.0-0.4) - Medium, // 中 (0.4-0.7) - High, // 高 (0.7-0.9) - Excellent, // 极佳 (0.9-1.0) -} - -impl ConfidenceLevel { - pub fn from_score(score: f64) -> Self { - match score { - s if s >= 0.9 => Self::Excellent, - s if s >= 0.7 => Self::High, - s if s >= 0.4 => Self::Medium, - _ => Self::Low, - } - } - - pub fn to_chinese(&self) -> &'static str { - match self { - Self::Low => "低", - Self::Medium => "中", - Self::High => "高", - Self::Excellent => "极佳", - } - } -} - -/// 搭配评分详情 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MatchingScoreDetails { - pub color_harmony_score: f64, // 颜色和谐度评分 (0.0-1.0) - pub style_consistency_score: f64, // 风格一致性评分 (0.0-1.0) - pub proportion_score: f64, // 比例协调度评分 (0.0-1.0) - pub occasion_appropriateness: f64, // 场合适宜度评分 (0.0-1.0) - pub trend_factor: f64, // 时尚度评分 (0.0-1.0) - pub overall_score: f64, // 综合评分 (0.0-1.0) -} - -impl MatchingScoreDetails { - pub fn calculate_overall_score(&mut self) { - // 加权计算综合评分 - self.overall_score = ( - self.color_harmony_score * 0.3 + - self.style_consistency_score * 0.25 + - self.proportion_score * 0.2 + - self.occasion_appropriateness * 0.15 + - self.trend_factor * 0.1 - ).clamp(0.0, 1.0); - } - - pub fn get_confidence_level(&self) -> ConfidenceLevel { - ConfidenceLevel::from_score(self.overall_score) - } -} - -/// 搭配建议 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MatchingSuggestion { - pub suggestion_type: String, // 建议类型 (如: "颜色调整", "风格优化") - pub description: String, // 建议描述 - pub priority: u8, // 优先级 (1-5, 5最高) -} - -/// 搭配组合中的单品 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MatchingOutfitItem { - pub item_id: String, // 服装单品ID - pub item_name: String, // 服装名称 - pub category: OutfitCategory, // 类别 - pub color_primary: ColorHSV, // 主色调 - pub styles: Vec, // 风格 - pub role_in_outfit: String, // 在搭配中的角色 (如: "主角", "配角", "点缀") - pub image_url: Option, // 图片URL -} - -/// 搭配匹配结果 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitMatching { - pub id: String, - pub project_id: String, - pub matching_name: String, // 搭配名称 - pub matching_type: MatchingType, // 匹配类型 - pub items: Vec, // 搭配的服装单品 - pub score_details: MatchingScoreDetails, // 评分详情 - pub suggestions: Vec, // 搭配建议 - pub occasion_tags: Vec, // 适用场合标签 - pub season_tags: Vec, // 适用季节标签 - pub style_description: String, // 风格描述 - pub color_palette: Vec, // 色彩搭配方案 - pub is_favorite: bool, // 是否收藏 - pub wear_count: u32, // 穿着次数 - pub last_worn_date: Option>, // 最后穿着日期 - pub created_at: DateTime, - pub updated_at: DateTime, -} - -/// 创建搭配匹配请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateOutfitMatchingRequest { - pub project_id: String, - pub matching_name: String, - pub matching_type: MatchingType, - pub item_ids: Vec, // 服装单品ID列表 - pub occasion_tags: Vec, - pub season_tags: Vec, - pub style_description: Option, -} - -/// 更新搭配匹配请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UpdateOutfitMatchingRequest { - pub matching_name: Option, - pub matching_type: Option, - pub item_ids: Option>, - pub occasion_tags: Option>, - pub season_tags: Option>, - pub style_description: Option, - pub is_favorite: Option, -} - -/// 搭配搜索过滤条件 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitMatchingSearchFilters { - pub categories: Option>, // 包含的服装类别 - pub styles: Option>, // 风格过滤 - pub colors: Option>, // 颜色过滤 - pub color_similarity_threshold: Option, // 颜色相似度阈值 - pub occasions: Option>, // 场合过滤 - pub seasons: Option>, // 季节过滤 - pub min_score: Option, // 最低评分 - pub confidence_level: Option, // 置信度等级 - pub matching_types: Option>, // 匹配类型 -} - -/// 搭配匹配查询选项 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitMatchingQueryOptions { - pub project_id: Option, - pub filters: Option, - pub sort_by: Option, // 排序字段 ("score", "created_at", "wear_count") - pub sort_order: Option, // 排序方向 ("asc", "desc") - pub limit: Option, - pub offset: Option, -} - -/// 智能搭配推荐请求 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SmartMatchingRequest { - pub project_id: String, - pub base_item_id: Option, // 基础单品ID (可选) - pub target_occasion: Option, // 目标场合 - pub target_season: Option, // 目标季节 - pub preferred_styles: Option>, // 偏好风格 - pub color_preferences: Option>, // 颜色偏好 - pub exclude_item_ids: Option>, // 排除的单品ID - pub max_results: Option, // 最大结果数 -} - -/// 智能搭配推荐结果 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SmartMatchingResult { - pub recommended_matchings: Vec, // 推荐的搭配 - pub reasoning: String, // 推荐理由 - pub confidence_score: f64, // 推荐置信度 -} - -/// 搭配匹配统计信息 -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OutfitMatchingStats { - pub total_matchings: u32, - pub favorite_count: u32, - pub average_score: f64, - pub most_worn_matching_id: Option, - pub style_distribution: std::collections::HashMap, - pub occasion_distribution: std::collections::HashMap, - pub season_distribution: std::collections::HashMap, -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_confidence_level_from_score() { - assert_eq!(ConfidenceLevel::from_score(0.95), ConfidenceLevel::Excellent); - assert_eq!(ConfidenceLevel::from_score(0.8), ConfidenceLevel::High); - assert_eq!(ConfidenceLevel::from_score(0.5), ConfidenceLevel::Medium); - assert_eq!(ConfidenceLevel::from_score(0.2), ConfidenceLevel::Low); - } - - #[test] - fn test_matching_score_calculation() { - let mut score_details = MatchingScoreDetails { - color_harmony_score: 0.8, - style_consistency_score: 0.9, - proportion_score: 0.7, - occasion_appropriateness: 0.8, - trend_factor: 0.6, - overall_score: 0.0, - }; - - score_details.calculate_overall_score(); - assert!(score_details.overall_score > 0.7); - assert!(score_details.overall_score < 0.9); - } -} diff --git a/apps/desktop/src-tauri/src/infrastructure/database.rs b/apps/desktop/src-tauri/src/infrastructure/database.rs index 0f486b9..09aa9e9 100644 --- a/apps/desktop/src-tauri/src/infrastructure/database.rs +++ b/apps/desktop/src-tauri/src/infrastructure/database.rs @@ -808,77 +808,6 @@ impl Database { [], )?; - // 创建服装分析表 - conn.execute( - "CREATE TABLE IF NOT EXISTS outfit_analyses ( - id TEXT PRIMARY KEY, - project_id TEXT NOT NULL, - image_path TEXT NOT NULL, - image_name TEXT NOT NULL, - analysis_status TEXT NOT NULL DEFAULT 'Pending', - analysis_result TEXT, - error_message TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - analyzed_at DATETIME, - FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE - )", - [], - )?; - - // 创建服装单品表 - conn.execute( - "CREATE TABLE IF NOT EXISTS outfit_items ( - id TEXT PRIMARY KEY, - project_id TEXT NOT NULL, - analysis_id TEXT, - name TEXT NOT NULL, - category TEXT NOT NULL, - brand TEXT, - model TEXT, - color_primary TEXT NOT NULL, - color_secondary TEXT, - styles TEXT NOT NULL, - design_elements TEXT, - size_info TEXT, - material_info TEXT, - price REAL, - purchase_date DATETIME, - image_urls TEXT, - tags TEXT, - notes TEXT, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE, - FOREIGN KEY (analysis_id) REFERENCES outfit_analyses (id) ON DELETE SET NULL - )", - [], - )?; - - // 创建服装搭配表 - conn.execute( - "CREATE TABLE IF NOT EXISTS outfit_matchings ( - id TEXT PRIMARY KEY, - project_id TEXT NOT NULL, - matching_name TEXT NOT NULL, - matching_type TEXT NOT NULL, - items TEXT NOT NULL, - score_details TEXT NOT NULL, - suggestions TEXT, - occasion_tags TEXT, - season_tags TEXT, - style_description TEXT NOT NULL, - color_palette TEXT, - is_favorite BOOLEAN DEFAULT 0, - wear_count INTEGER DEFAULT 0, - last_worn_date DATETIME, - created_at DATETIME DEFAULT CURRENT_TIMESTAMP, - updated_at DATETIME DEFAULT CURRENT_TIMESTAMP, - FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE - )", - [], - )?; - // 创建索引 conn.execute( "CREATE INDEX IF NOT EXISTS idx_projects_name ON projects (name)", @@ -1021,65 +950,6 @@ impl Database { "CREATE INDEX IF NOT EXISTS idx_export_records_created_at ON export_records (created_at)", [], )?; - - // 创建服装分析表索引 - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_analyses_project_id ON outfit_analyses (project_id)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_analyses_status ON outfit_analyses (analysis_status)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_analyses_created_at ON outfit_analyses (created_at)", - [], - )?; - - // 创建服装单品表索引 - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_items_project_id ON outfit_items (project_id)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_items_analysis_id ON outfit_items (analysis_id)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_items_category ON outfit_items (category)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_items_brand ON outfit_items (brand)", - [], - )?; - - // 创建服装搭配表索引 - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_matchings_project_id ON outfit_matchings (project_id)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_matchings_type ON outfit_matchings (matching_type)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_matchings_favorite ON outfit_matchings (is_favorite)", - [], - )?; - - conn.execute( - "CREATE INDEX IF NOT EXISTS idx_outfit_matchings_created_at ON outfit_matchings (created_at)", - [], - )?; - // 添加新字段(如果不存在)- 数据库迁移 let _ = conn.execute( "ALTER TABLE template_materials ADD COLUMN file_exists BOOLEAN DEFAULT FALSE",