From 50eb7a15bcbe145007854baf034c2d52fe5e537d Mon Sep 17 00:00:00 2001 From: mtvpls Date: Fri, 22 May 2026 00:33:58 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BD=91=E7=9B=98=E6=90=9C=E7=B4=A2=EF=BC=8C?= =?UTF-8?q?=E7=A3=81=E9=93=BE=E7=B1=BB=E5=9E=8B=E5=A2=9E=E5=8A=A0=E5=AD=98?= =?UTF-8?q?=E5=88=B0=E7=A7=81=E4=BA=BA=E5=BD=B1=E5=BA=93=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PansouSearch.tsx | 141 ++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+) diff --git a/src/components/PansouSearch.tsx b/src/components/PansouSearch.tsx index e2d222a..e86c5f6 100644 --- a/src/components/PansouSearch.tsx +++ b/src/components/PansouSearch.tsx @@ -4,6 +4,7 @@ import { AlertCircle, Copy, + Download, ExternalLink, Loader2, RefreshCw, @@ -21,6 +22,14 @@ interface PansouSearchProps { onError?: (error: string) => void; } +type DownloadTool = 'aria2' | 'Transmission' | 'qBittorrent'; + +const downloadToolOptions: Array<{ value: DownloadTool; label: string }> = [ + { value: 'aria2', label: 'aria2' }, + { value: 'qBittorrent', label: 'qBittorrent' }, + { value: 'Transmission', label: 'Transmission' }, +]; + // 网盘类型映射 const CLOUD_TYPE_NAMES: Record = { baidu: '百度网盘', @@ -154,6 +163,12 @@ export default function PansouSearch({ const typeDragScrollLeftRef = useRef(0); const [transferingUrl, setTransferingUrl] = useState(null); const [playingUrl, setPlayingUrl] = useState(null); + const [downloadingUrl, setDownloadingUrl] = useState(null); + const [showNameDialog, setShowNameDialog] = useState(false); + const [selectedDownloadLink, setSelectedDownloadLink] = + useState(null); + const [customName, setCustomName] = useState(''); + const [downloadTool, setDownloadTool] = useState('aria2'); const [toast, setToast] = useState(null); const [cooldownRemainingMs, setCooldownRemainingMs] = useState(0); const [checkStatesByType, setCheckStatesByType] = useState< @@ -335,6 +350,64 @@ export default function PansouSearch({ } }; + const handleOpenDownloadDialog = (link: PansouLink) => { + setSelectedDownloadLink(link); + setCustomName(keyword.trim() || link.note || ''); + setShowNameDialog(true); + }; + + const handleCloseDownloadDialog = () => { + setShowNameDialog(false); + setSelectedDownloadLink(null); + setCustomName(''); + setDownloadTool('aria2'); + }; + + const handleConfirmDownload = async () => { + if (!selectedDownloadLink || !customName.trim()) { + return; + } + + setDownloadingUrl(selectedDownloadLink.url); + setShowNameDialog(false); + + try { + const response = await fetch('/api/acg/download', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + url: selectedDownloadLink.url, + name: customName.trim(), + tool: downloadTool, + }), + }); + + const data = await response.json(); + if (!response.ok) { + throw new Error(data.error || '添加下载任务失败'); + } + + setToast({ + message: data.message || '已添加到离线下载队列', + type: 'success', + onClose: () => setToast(null), + }); + } catch (err: any) { + setToast({ + message: err?.message || '添加下载任务失败', + type: 'error', + onClose: () => setToast(null), + }); + } finally { + setDownloadingUrl(null); + setSelectedDownloadLink(null); + setCustomName(''); + setDownloadTool('aria2'); + } + }; + const handleNetdiskInstantPlay = async ( cloudType: string, link: PansouLink @@ -798,6 +871,28 @@ export default function PansouSearch({ )} )} + {cloudType === 'magnet' && ( + + )} + + + + + )} {toast && } );