美化前端

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