blob: e90af3ce96750c850639b7e174400488e2b2db41 [file] [log] [blame]
import React, { useEffect, useState } from 'react';
import { useParams,useSearchParams, useNavigate } from 'react-router-dom';
import { Card, Button, Spin, Tag, message, Input } from 'antd';
import { ArrowLeftOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons';
import { getTorrentInfo,auditTorrent,downloadTorrent } from '../../services/bt/index';
// 状态映射
const statusMap: Record<number, string> = {
0: '审核中',
1: '已发布',
2: '审核不通过',
3: '已上架修改重审中',
10: '已下架',
};
const TorrentAudit: React.FC = () => {
const { id } = useParams<{ id: string }>();
const navigate = useNavigate();
const [loading, setLoading] = useState(true);
const [torrent, setTorrent] = useState<any>(null);
const [auditLoading, setAuditLoading] = useState(false);
const [rejectReason, setRejectReason] = useState('');
useEffect(() => {
if (!id) {
message.error('未指定种子ID');
navigate(-1);
return;
}
setLoading(true);
getTorrentInfo({ id })
.then(res => setTorrent(res.data))
.finally(() => setLoading(false));
}, [id, navigate]);
const handleDownload = async () => {
try {
const res = await downloadTorrent({ id: id! });
const blob = new Blob([res], { type: 'application/x-bittorrent' });
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `${torrent?.title || 'torrent'}.torrent`;
a.click();
window.URL.revokeObjectURL(url);
} catch {
message.error('下载失败');
}
};
const handleAudit = async (status: 1 | 2) => {
if (status === 2 && !rejectReason.trim()) {
message.warning('请填写拒绝理由');
return;
}
setAuditLoading(true);
try {
await auditTorrent({
id: Number(id),
status,
remark: status === 2 ? rejectReason.trim() : undefined,
});
message.success(status === 1 ? '审核通过' : '审核拒绝');
navigate(-1);
} catch {
message.error('操作失败');
} finally {
setAuditLoading(false);
}
};
return (
<div style={{ minHeight: '100vh', background: '#f4f8ff', padding: 32 }}>
<div style={{ maxWidth: 800, margin: '0 auto' }}>
<Button
icon={<ArrowLeftOutlined />}
type="link"
onClick={() => navigate(-1)}
style={{ marginBottom: 16 }}
>
返回
</Button>
<Card
loading={loading}
title={
<span>
审核种子
{torrent && (
<Tag color={torrent.status === 0 ? 'orange' : torrent.status === 1 ? 'green' : 'red'} style={{ marginLeft: 16 }}>
{statusMap[torrent.status]}
</Tag>
)}
</span>
}
>
{loading ? (
<Spin />
) : !torrent ? (
<div>未找到种子信息</div>
) : (
<>
<h2>{torrent.title}</h2>
<div style={{ marginBottom: 8 }}>
<Tag color="blue">{torrent.categoryName || '未知分类'}</Tag>
{torrent.tags?.map((tag: string) => (
<Tag key={tag}>{tag}</Tag>
))}
</div>
<div style={{ color: '#888', marginBottom: 8 }}>
上传者:{torrent.owner} | 上传时间:{torrent.createdAt}
</div>
<div style={{ marginBottom: 16 }}>
<span>文件大小:{torrent.size}</span>
<span style={{ marginLeft: 24 }}>做种人数:{torrent.seeders}</span>
<span style={{ marginLeft: 24 }}>下载人数:{torrent.leechers}</span>
<span style={{ marginLeft: 24 }}>完成次数:{torrent.completed}</span>
</div>
<div style={{ marginBottom: 16 }}>
<Button
type="primary"
icon={<CheckOutlined />}
onClick={() => downloadTorrent(torrent.id)}
disabled={!torrent.infoHash}
>
下载种子
</Button>
</div>
<div
style={{
background: '#f6f8fa',
padding: 16,
borderRadius: 8,
marginBottom: 24,
minHeight: 80,
}}
dangerouslySetInnerHTML={{ __html: torrent.description || '' }}
/>
{torrent.status === 0 ? (
<>
<div style={{ display: 'flex', gap: 16, alignItems: 'center', marginBottom: 16 }}>
<Button
type="primary"
icon={<CheckOutlined />}
loading={auditLoading}
onClick={() => handleAudit(1)}
>
审核通过
</Button>
<Button
danger
icon={<CloseOutlined />}
loading={auditLoading}
onClick={() => handleAudit(2)}
>
审核拒绝
</Button>
<Input.TextArea
value={rejectReason}
onChange={e => setRejectReason(e.target.value)}
placeholder="拒绝理由(仅拒绝时填写)"
autoSize={{ minRows: 1, maxRows: 3 }}
style={{ width: 260 }}
disabled={auditLoading}
/>
</div>
</>
) : (
<div style={{ color: '#888', marginTop: 16 }}>
当前状态:{statusMap[torrent.status]}
{torrent.status === 2 && torrent.reason && (
<div style={{ color: '#d4380d', marginTop: 8 }}>拒绝理由:{torrent.reason}</div>
)}
</div>
)}
</>
)}
</Card>
</div>
</div>
);
};
export default TorrentAudit;