/* eslint-disable @typescript-eslint/no-explicit-any,no-console */ 'use client'; import { AlertCircle, Copy, ExternalLink, Loader2 } from 'lucide-react'; import { useEffect, useState } from 'react'; import { PansouLink, PansouSearchResult } from '@/lib/pansou.client'; interface PansouSearchProps { keyword: string; triggerSearch?: boolean; // 触发搜索的标志 onError?: (error: string) => void; } // 网盘类型映射 const CLOUD_TYPE_NAMES: Record = { baidu: '百度网盘', aliyun: '阿里云盘', quark: '夸克网盘', tianyi: '天翼云盘', uc: 'UC网盘', mobile: '移动云盘', '115': '115网盘', pikpak: 'PikPak', xunlei: '迅雷网盘', '123': '123网盘', magnet: '磁力链接', ed2k: '电驴链接', others: '其他', }; // 网盘类型颜色 const CLOUD_TYPE_COLORS: Record = { baidu: 'bg-blue-100 text-blue-800 dark:bg-blue-900/40 dark:text-blue-200', aliyun: 'bg-orange-100 text-orange-800 dark:bg-orange-900/40 dark:text-orange-200', quark: 'bg-purple-100 text-purple-800 dark:bg-purple-900/40 dark:text-purple-200', tianyi: 'bg-red-100 text-red-800 dark:bg-red-900/40 dark:text-red-200', uc: 'bg-green-100 text-green-800 dark:bg-green-900/40 dark:text-green-200', mobile: 'bg-pink-100 text-pink-800 dark:bg-pink-900/40 dark:text-pink-200', '115': 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900/40 dark:text-yellow-200', pikpak: 'bg-indigo-100 text-indigo-800 dark:bg-indigo-900/40 dark:text-indigo-200', xunlei: 'bg-cyan-100 text-cyan-800 dark:bg-cyan-900/40 dark:text-cyan-200', '123': 'bg-teal-100 text-teal-800 dark:bg-teal-900/40 dark:text-teal-200', magnet: 'bg-gray-100 text-gray-800 dark:bg-gray-700/40 dark:text-gray-200', ed2k: 'bg-gray-100 text-gray-800 dark:bg-gray-700/40 dark:text-gray-200', others: 'bg-gray-100 text-gray-800 dark:bg-gray-700/40 dark:text-gray-200', }; export default function PansouSearch({ keyword, triggerSearch, onError, }: PansouSearchProps) { const [loading, setLoading] = useState(false); const [results, setResults] = useState(null); const [error, setError] = useState(null); const [copiedUrl, setCopiedUrl] = useState(null); const [selectedType, setSelectedType] = useState('all'); // 'all' 表示显示全部 useEffect(() => { // triggerSearch 变化时触发搜索(无论是 true 还是 false) if (triggerSearch === undefined) { return; } const currentKeyword = keyword.trim(); if (!currentKeyword) { return; } const searchPansou = async () => { setLoading(true); setError(null); setResults(null); try { const response = await fetch('/api/pansou/search', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ keyword: currentKeyword, }), }); if (!response.ok) { const errorData = await response.json(); throw new Error(errorData.error || '搜索失败'); } const data: PansouSearchResult = await response.json(); setResults(data); } catch (err: any) { const errorMsg = err.message || '搜索失败,请检查配置'; setError(errorMsg); onError?.(errorMsg); } finally { setLoading(false); } }; searchPansou(); }, [triggerSearch, onError]); // 移除 keyword 依赖,只依赖 triggerSearch const handleCopy = async (text: string, url: string) => { try { await navigator.clipboard.writeText(text); setCopiedUrl(url); setTimeout(() => setCopiedUrl(null), 2000); } catch (err) { console.error('复制失败:', err); } }; const handleOpenLink = (url: string) => { window.open(url, '_blank', 'noopener,noreferrer'); }; if (loading) { return (

正在搜索网盘资源...

); } if (error) { return (

{error}

); } if (!results || results.total === 0 || !results.merged_by_type) { return (

未找到相关资源

); } const cloudTypes = Object.keys(results.merged_by_type || {}); // 过滤显示的网盘类型 const filteredCloudTypes = selectedType === 'all' ? cloudTypes : cloudTypes.filter(type => type === selectedType); // 计算每种网盘类型的数量 const typeStats = cloudTypes.map(type => ({ type, count: results.merged_by_type?.[type]?.length || 0, })); return (
{/* 搜索结果统计 */}
找到 {results.total} 个资源
{/* 网盘类型过滤器 */}
{typeStats.map(({ type, count }) => { const typeName = CLOUD_TYPE_NAMES[type] || type; const typeColor = CLOUD_TYPE_COLORS[type] || CLOUD_TYPE_COLORS.others; return ( ); })}
{/* 按网盘类型分类显示 */} {filteredCloudTypes.map((cloudType) => { const links = results.merged_by_type?.[cloudType]; if (!links || links.length === 0) return null; const typeName = CLOUD_TYPE_NAMES[cloudType] || cloudType; const typeColor = CLOUD_TYPE_COLORS[cloudType] || CLOUD_TYPE_COLORS.others; return (
{/* 网盘类型标题 */}
{typeName} {links.length} 个链接
{/* 链接列表 */}
{links.map((link: PansouLink, index: number) => (
{/* 资源标题 */} {link.note && (
{link.note}
)} {/* 链接和密码 */}
{link.url}
{link.password && (
提取码: {link.password}
)}
{/* 操作按钮 */}
{/* 来源和时间 */}
{link.source && ( 来源: {link.source} )} {link.datetime && ( {new Date(link.datetime).toLocaleDateString()} )}
{/* 图片预览 */} {link.images && link.images.length > 0 && (
{link.images.map((img, imgIndex) => ( ))}
)}
))}
); })}
); }