- 弹窗使用 Tabs 切换两种下载方式 - 浏览器下载保留逐条触发逻辑 - 下载工具页提供 aria2 / wget 命令示例与复制全部链接
This commit is contained in:
+110
-32
@@ -13,6 +13,7 @@ import {
|
||||
Image,
|
||||
Popconfirm,
|
||||
Typography,
|
||||
Tabs,
|
||||
} from 'antd';
|
||||
import { DownloadOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
|
||||
import dayjs from 'dayjs';
|
||||
@@ -128,20 +129,20 @@ export default function VideosPage() {
|
||||
const [downloadResults, setDownloadResults] = useState<DownloadResult[]>([]);
|
||||
const [downloadModalOpen, setDownloadModalOpen] = useState(false);
|
||||
|
||||
const handleBatchDownload = async () => {
|
||||
const ids = selectedRows.map((v) => v.videoId);
|
||||
try {
|
||||
const results = await batchDownload(ids);
|
||||
const valid = results.filter((r) => r.urls.length > 0);
|
||||
setDownloadResults(valid);
|
||||
setDownloadModalOpen(true);
|
||||
setSelectedRows([]);
|
||||
} catch (error) {
|
||||
message.error('获取下载地址失败');
|
||||
}
|
||||
const allDownloadUrls = downloadResults.flatMap((item) =>
|
||||
item.urls.map((u) => u.url)
|
||||
);
|
||||
|
||||
const wgetCommand = allDownloadUrls.map((url) => `wget "${url}"`).join('\n');
|
||||
const aria2Command = allDownloadUrls.map((url) => `aria2c "${url}"`).join('\n');
|
||||
|
||||
const copyAllUrls = () => {
|
||||
navigator.clipboard.writeText(allDownloadUrls.join('\n')).then(() => {
|
||||
message.success('已复制全部链接');
|
||||
});
|
||||
};
|
||||
|
||||
const startDownloads = () => {
|
||||
const startBrowserDownloads = () => {
|
||||
let count = 0;
|
||||
downloadResults.forEach((item) => {
|
||||
item.urls.forEach((urlInfo) => {
|
||||
@@ -161,6 +162,19 @@ export default function VideosPage() {
|
||||
message.success(`已尝试触发 ${count} 个下载任务`);
|
||||
};
|
||||
|
||||
const handleBatchDownload = async () => {
|
||||
const ids = selectedRows.map((v) => v.videoId);
|
||||
try {
|
||||
const results = await batchDownload(ids);
|
||||
const valid = results.filter((r) => r.urls.length > 0);
|
||||
setDownloadResults(valid);
|
||||
setDownloadModalOpen(true);
|
||||
setSelectedRows([]);
|
||||
} catch (error) {
|
||||
message.error('获取下载地址失败');
|
||||
}
|
||||
};
|
||||
|
||||
const handleRowClick = (record: VideoItem) => {
|
||||
setDetail(record);
|
||||
setDrawerOpen(true);
|
||||
@@ -295,34 +309,98 @@ export default function VideosPage() {
|
||||
/>
|
||||
|
||||
<Modal
|
||||
title="批量下载地址"
|
||||
title="批量下载"
|
||||
open={downloadModalOpen}
|
||||
width={800}
|
||||
width={820}
|
||||
onCancel={() => setDownloadModalOpen(false)}
|
||||
footer={[
|
||||
<Button key="download" type="primary" onClick={startDownloads}>
|
||||
开始下载
|
||||
</Button>,
|
||||
<Button key="close" onClick={() => setDownloadModalOpen(false)}>
|
||||
关闭
|
||||
</Button>,
|
||||
]}
|
||||
>
|
||||
<div style={{ maxHeight: 400, overflow: 'auto' }}>
|
||||
{downloadResults.map((item) => (
|
||||
<div key={item.videoId} style={{ marginBottom: 12 }}>
|
||||
<Text strong>{item.title || item.videoId}</Text>
|
||||
<ul style={{ margin: 4, paddingLeft: 20 }}>
|
||||
{item.urls.map((url, idx) => (
|
||||
<li key={idx}>
|
||||
<Text copyable>{url.url}</Text>
|
||||
<Tag style={{ marginLeft: 8 }}>{url.definition}</Tag>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Tabs
|
||||
items={[
|
||||
{
|
||||
key: 'browser',
|
||||
label: '浏览器下载',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Button type="primary" onClick={startBrowserDownloads}>
|
||||
开始浏览器下载
|
||||
</Button>
|
||||
<Text type="secondary">
|
||||
将逐个创建下载任务,间隔 300ms,降低被浏览器拦截的概率。若被拦截,请使用「下载工具」方式。
|
||||
</Text>
|
||||
<div style={{ maxHeight: 320, overflow: 'auto' }}>
|
||||
{downloadResults.map((item) => (
|
||||
<div key={item.videoId} style={{ marginBottom: 12 }}>
|
||||
<Text strong>{item.title || item.videoId}</Text>
|
||||
<ul style={{ margin: 4, paddingLeft: 20 }}>
|
||||
{item.urls.map((url, idx) => (
|
||||
<li key={idx}>
|
||||
<Text copyable>{url.url}</Text>
|
||||
<Tag style={{ marginLeft: 8 }}>{url.definition}</Tag>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'tools',
|
||||
label: '下载工具',
|
||||
children: (
|
||||
<Space direction="vertical" style={{ width: '100%' }}>
|
||||
<Button onClick={copyAllUrls}>复制全部链接</Button>
|
||||
<div style={{ background: '#f6f8fa', padding: 16, borderRadius: 8 }}>
|
||||
<Text strong>推荐方式</Text>
|
||||
<ul>
|
||||
<li>
|
||||
<Text>
|
||||
复制全部链接后,使用 <Text code>aria2</Text> 或{' '}
|
||||
<Text code>wget</Text> 等工具批量下载。
|
||||
</Text>
|
||||
</li>
|
||||
<li>
|
||||
<Text>aria2 支持断点续传、多线程,适合下载大文件。</Text>
|
||||
</li>
|
||||
</ul>
|
||||
<Text strong>aria2 示例</Text>
|
||||
<pre
|
||||
style={{
|
||||
background: '#1e1e1e',
|
||||
color: '#d4d4d4',
|
||||
padding: 12,
|
||||
borderRadius: 4,
|
||||
overflow: 'auto',
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
{aria2Command || '# 暂无下载链接'}
|
||||
</pre>
|
||||
<Text strong>wget 示例</Text>
|
||||
<pre
|
||||
style={{
|
||||
background: '#1e1e1e',
|
||||
color: '#d4d4d4',
|
||||
padding: 12,
|
||||
borderRadius: 4,
|
||||
overflow: 'auto',
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
{wgetCommand || '# 暂无下载链接'}
|
||||
</pre>
|
||||
</div>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Modal>
|
||||
|
||||
<Drawer
|
||||
|
||||
Reference in New Issue
Block a user