blob: 278a3cdc260bcd8fa3a31f410390802d322585d9 [file] [log] [blame]
Jiarenxiang24d681b2025-06-08 19:27:05 +08001import React, { useEffect, useState } from 'react';
2import { useSearchParams, useNavigate } from 'react-router-dom';
3import { Card, Button, Spin, Tag, message, Input } from 'antd';
4import { ArrowLeftOutlined, CheckOutlined, CloseOutlined } from '@ant-design/icons';
5import { getTorrentInfo,auditTorrent } from '../../services/bt/index';
6
7// 状态映射
8const statusMap: Record<number, string> = {
9 0: '审核中',
10 1: '已发布',
11 2: '审核不通过',
12 3: '已上架修改重审中',
13 10: '已下架',
14};
15
16const TorrentAudit: React.FC = () => {
17 const [searchParams] = useSearchParams();
18 const id = searchParams.get('id');
19 const navigate = useNavigate();
20
21 const [loading, setLoading] = useState(true);
22 const [torrent, setTorrent] = useState<any>(null);
23 const [auditLoading, setAuditLoading] = useState(false);
24 const [rejectReason, setRejectReason] = useState('');
25
26 useEffect(() => {
27 if (!id) {
28 message.error('未指定种子ID');
29 navigate(-1);
30 return;
31 }
32 setLoading(true);
33 getTorrentInfo({ id })
34 .then(res => setTorrent(res.data))
35 .finally(() => setLoading(false));
36 }, [id, navigate]);
37
38 const handleAudit = async (status: 1 | 2) => {
39 if (status === 2 && !rejectReason.trim()) {
40 message.warning('请填写拒绝理由');
41 return;
42 }
43 setAuditLoading(true);
44 try {
45 await auditTorrent({
46 id: Number(id),
47 status,
48 remark: status === 2 ? rejectReason.trim() : undefined,
49 });
50 message.success(status === 1 ? '审核通过' : '审核拒绝');
51 navigate(-1);
52 } catch {
53 message.error('操作失败');
54 } finally {
55 setAuditLoading(false);
56 }
57 };
58
59 return (
60 <div style={{ minHeight: '100vh', background: '#f4f8ff', padding: 32 }}>
61 <div style={{ maxWidth: 800, margin: '0 auto' }}>
62 <Button
63 icon={<ArrowLeftOutlined />}
64 type="link"
65 onClick={() => navigate(-1)}
66 style={{ marginBottom: 16 }}
67 >
68 返回
69 </Button>
70 <Card
71 loading={loading}
72 title={
73 <span>
74 审核种子
75 {torrent && (
76 <Tag color={torrent.status === 0 ? 'orange' : torrent.status === 1 ? 'green' : 'red'} style={{ marginLeft: 16 }}>
77 {statusMap[torrent.status]}
78 </Tag>
79 )}
80 </span>
81 }
82 >
83 {loading ? (
84 <Spin />
85 ) : !torrent ? (
86 <div>未找到种子信息</div>
87 ) : (
88 <>
89 <h2>{torrent.title}</h2>
90 <div style={{ marginBottom: 8 }}>
91 <Tag color="blue">{torrent.categoryName || '未知分类'}</Tag>
92 {torrent.tags?.map((tag: string) => (
93 <Tag key={tag}>{tag}</Tag>
94 ))}
95 </div>
96 <div style={{ color: '#888', marginBottom: 8 }}>
97 上传者:{torrent.owner} | 上传时间:{torrent.createdAt}
98 </div>
99 <div style={{ marginBottom: 16 }}>
100 <span>文件大小:{torrent.size}</span>
101 <span style={{ marginLeft: 24 }}>做种人数:{torrent.seeders}</span>
102 <span style={{ marginLeft: 24 }}>下载人数:{torrent.leechers}</span>
103 <span style={{ marginLeft: 24 }}>完成次数:{torrent.completed}</span>
104 </div>
105 <div
106 style={{
107 background: '#f6f8fa',
108 padding: 16,
109 borderRadius: 8,
110 marginBottom: 24,
111 minHeight: 80,
112 }}
113 dangerouslySetInnerHTML={{ __html: torrent.description || '' }}
114 />
115 {torrent.status === 0 ? (
116 <>
117 <div style={{ display: 'flex', gap: 16, alignItems: 'center', marginBottom: 16 }}>
118 <Button
119 type="primary"
120 icon={<CheckOutlined />}
121 loading={auditLoading}
122 onClick={() => handleAudit(1)}
123 >
124 审核通过
125 </Button>
126 <Button
127 danger
128 icon={<CloseOutlined />}
129 loading={auditLoading}
130 onClick={() => handleAudit(2)}
131 >
132 审核拒绝
133 </Button>
134 <Input.TextArea
135 value={rejectReason}
136 onChange={e => setRejectReason(e.target.value)}
137 placeholder="拒绝理由(仅拒绝时填写)"
138 autoSize={{ minRows: 1, maxRows: 3 }}
139 style={{ width: 260 }}
140 disabled={auditLoading}
141 />
142 </div>
143 </>
144 ) : (
145 <div style={{ color: '#888', marginTop: 16 }}>
146 当前状态:{statusMap[torrent.status]}
147 {torrent.status === 2 && torrent.reason && (
148 <div style={{ color: '#d4380d', marginTop: 8 }}>拒绝理由:{torrent.reason}</div>
149 )}
150 </div>
151 )}
152 </>
153 )}
154 </Card>
155 </div>
156 </div>
157 );
158};
159
160export default TorrentAudit;