import { LinkIcon } from 'lucide-react'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; import React, { useMemo, useState } from 'react'; import { ImagePlaceholder } from '@/components/ImagePlaceholder'; // 聚合卡需要的基本字段,与搜索接口保持一致 interface SearchResult { id: string; title: string; poster: string; source: string; source_name: string; douban_id?: number; episodes: string[]; } interface AggregateCardProps { /** 同一标题下的多个搜索结果 */ year?: string; items: SearchResult[]; } function PlayCircleSolid({ className = '', fillColor = 'none', }: { className?: string; fillColor?: string; }) { return ( ); } /** * 与 `VideoCard` 基本一致,删除了来源标签、收藏等功能 * 点击播放按钮 -> 跳到第一个源播放 * 点击卡片其他区域 -> 跳到聚合详情页 (/aggregate) */ const AggregateCard: React.FC = ({ year = 0, items }) => { // 使用列表中的第一个结果做展示 & 播放 const first = items[0]; const [playHover, setPlayHover] = useState(false); const [isLoaded, setIsLoaded] = useState(false); const router = useRouter(); // 统计 items 中出现次数最多的(非 0) douban_id,用于跳转豆瓣页面 const mostFrequentDoubanId = useMemo(() => { const countMap = new Map(); items.forEach((item) => { if (item.douban_id && item.douban_id !== 0) { countMap.set(item.douban_id, (countMap.get(item.douban_id) || 0) + 1); } }); let selectedId: number | undefined; let maxCount = 0; countMap.forEach((cnt, id) => { if (cnt > maxCount) { maxCount = cnt; selectedId = id; } }); return selectedId; }, [items]); // 统计出现次数最多的集数(episodes.length),主要用于显示剧集数徽标 const mostFrequentEpisodes = useMemo(() => { const countMap = new Map(); items.forEach((item) => { const len = item.episodes?.length || 0; if (len > 0) { countMap.set(len, (countMap.get(len) || 0) + 1); } }); let selectedLen = 0; let maxCount = 0; countMap.forEach((cnt, len) => { if (cnt > maxCount) { maxCount = cnt; selectedLen = len; } }); return selectedLen; }, [items]); return (
{/* 封面图片 2:3 */}
{/* 图片占位符 - 骨架屏效果 */} {first.title} setIsLoaded(true)} referrerPolicy='no-referrer' priority={false} /> {/* Hover 效果层 */}
{/* 播放按钮 */}
{ e.preventDefault(); e.stopPropagation(); router.push( `/play?source=${first.source}&id=${ first.id }&title=${encodeURIComponent(first.title)}${ year ? `&year=${year}` : '' }` ); }} onMouseEnter={() => setPlayHover(true)} onMouseLeave={() => setPlayHover(false)} >
{/* 集数矩形展示框 */} {mostFrequentEpisodes && mostFrequentEpisodes > 1 && (
{mostFrequentEpisodes}
)} {/* 豆瓣链接按钮 */} {mostFrequentDoubanId && ( e.stopPropagation()} className='absolute top-2 left-2 scale-90 group-hover:scale-100 opacity-0 group-hover:opacity-100 transition-all duration-300 cubic-bezier(0.4,0,0.2,1)' >
)}
{/* 标题 */} {first.title}
); }; export default AggregateCard;