美化前端
Change-Id: I46437caf832dd8f18358354f024724f7e31524cb
diff --git a/src/pages/Torrent/torrentAudit.tsx b/src/pages/Torrent/torrentAudit.tsx
new file mode 100644
index 0000000..278a3cd
--- /dev/null
+++ b/src/pages/Torrent/torrentAudit.tsx
@@ -0,0 +1,160 @@
+import React, { useEffect, useState } from 'react';
+import { 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 } from '../../services/bt/index';
+
+// 状态映射
+const statusMap: Record<number, string> = {
+ 0: '审核中',
+ 1: '已发布',
+ 2: '审核不通过',
+ 3: '已上架修改重审中',
+ 10: '已下架',
+};
+
+const TorrentAudit: React.FC = () => {
+ const [searchParams] = useSearchParams();
+ const id = searchParams.get('id');
+ 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 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={{
+ 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;
\ No newline at end of file