import React, { useState, useCallback } from 'react'; import { ExternalLink, Tag, Image as ImageIcon, TrendingUp } from 'lucide-react'; import { SimilaritySearchCardProps } from '../../types/similaritySearch'; import SimilaritySearchService from '../../services/similaritySearchService'; /** * 相似度检索结果卡片组件 * 遵循设计系统规范,提供统一的结果展示界面 */ export const SimilaritySearchCard: React.FC = ({ result, onSelect, onExternalLinkClick, showScore = true, compact = false, }) => { const [imageLoaded, setImageLoaded] = useState(false); const [imageError, setImageError] = useState(false); // 处理卡片点击 const handleCardClick = useCallback((e: React.MouseEvent) => { // 如果点击的是按钮或其子元素,不触发卡片选择 const target = e.target as HTMLElement; if (target.closest('button')) { return; } if (onSelect) { onSelect(result); } }, [result, onSelect]); // 处理外部链接点击 const handleExternalClick = useCallback((e: React.MouseEvent) => { e.preventDefault(); e.stopPropagation(); if (result.image_url) { if (onExternalLinkClick) { onExternalLinkClick(result.image_url); } else { window.open(result.image_url, '_blank', 'noopener,noreferrer'); } } }, [result.image_url, onExternalLinkClick]); // 处理图片加载 const handleImageLoad = useCallback(() => { setImageLoaded(true); }, []); // 处理图片错误 const handleImageError = useCallback(() => { setImageError(true); setImageLoaded(true); }, []); // 获取相关性评分样式 const scoreColor = SimilaritySearchService.getRelevanceScoreColor(result.relevance_score); const formattedScore = SimilaritySearchService.formatRelevanceScore(result.relevance_score); return (
{/* 装饰性背景 */}
{/* 相关性评分 */} {showScore && (
{formattedScore}
)}
{/* 图片区域 */}
{result.image_url && !imageError ? ( <> {result.style_description} {!imageLoaded && (
)} ) : (
)} {/* 外部链接按钮 */} {result.image_url && ( )}
{/* 内容区域 */}
{/* 标题和描述 */}

{result.style_description || '未知风格'}

{/* 环境标签 */} {result.environment_tags && result.environment_tags.length > 0 && (
{result.environment_tags.slice(0, compact ? 2 : 3).map((tag: string, index: number) => ( {tag} ))} {result.environment_tags.length > (compact ? 2 : 3) && ( +{result.environment_tags.length - (compact ? 2 : 3)} )}
)} {/* 产品信息 */} {result.products && result.products.length > 0 && (
产品信息
{result.products.slice(0, compact ? 1 : 2).map((product: any, index: number) => (
{product.category} {product.description && ( {product.description} )}
))} {result.products.length > (compact ? 1 : 2) && (
还有 {result.products.length - (compact ? 1 : 2)} 个产品...
)}
)}
{/* 悬停效果 */}
); }; export default SimilaritySearchCard;