前端简单界面

Change-Id: I7df9774daf4df8d92b13e659effe426ab0b6180b
diff --git a/pt--frontend/src/components/ActivityFullList.jsx b/pt--frontend/src/components/ActivityFullList.jsx
new file mode 100644
index 0000000..02b3ebd
--- /dev/null
+++ b/pt--frontend/src/components/ActivityFullList.jsx
@@ -0,0 +1,36 @@
+// src/components/ActivityFullList.jsx
+import React, { useEffect, useState } from 'react';
+import { getFullActivities } from '../api/activity';
+
+const ActivityFullList = () => {
+    const [activities, setActivities] = useState([]);
+
+    useEffect(() => {
+        getFullActivities()
+            .then(res => setActivities(res.data))
+            .catch(err => console.error('获取完整活动失败:', err));
+    }, []);
+
+    return (
+        <div>
+            <h2>完整活动信息</h2>
+            <div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
+                {activities.map(activity => (
+                    <div key={activity.activityid} style={{ borderBottom: '1px solid #ddd', paddingBottom: '16px' }}>
+                        <h3>{activity.title}</h3>
+                        <img
+                            src={activity.photo}
+                            alt={activity.title}
+                            style={{ width: '300px', height: 'auto', borderRadius: '4px' }}
+                        />
+                        <p><strong>内容:</strong>{activity.content}</p>
+                        <p><strong>时间:</strong>{activity.time}</p>
+                        <p><strong>奖励:</strong>{activity.award}</p>
+                    </div>
+                ))}
+            </div>
+        </div>
+    );
+};
+
+export default ActivityFullList;
diff --git a/pt--frontend/src/components/ActivityPreview.jsx b/pt--frontend/src/components/ActivityPreview.jsx
new file mode 100644
index 0000000..05050df
--- /dev/null
+++ b/pt--frontend/src/components/ActivityPreview.jsx
@@ -0,0 +1,33 @@
+// src/components/ActivityPreview.jsx
+import React, { useEffect, useState } from 'react';
+import { getActivityPreviews } from '../api/activity';
+
+const ActivityPreview = () => {
+    const [activities, setActivities] = useState([]);
+
+    useEffect(() => {
+        getActivityPreviews()
+            .then(res => setActivities(res.data))
+            .catch(err => console.error('获取活动预览失败:', err));
+    }, []);
+
+    return (
+        <div>
+            <h2>活动预览</h2>
+            <div style={{ display: 'flex', flexWrap: 'wrap', gap: '16px' }}>
+                {activities.map(activity => (
+                    <div key={activity.activityid} style={{ border: '1px solid #ccc', padding: '12px', borderRadius: '8px' }}>
+                        <h3>{activity.title}</h3>
+                        <img
+                            src={activity.photo}
+                            alt={activity.title}
+                            style={{ width: '200px', height: 'auto', borderRadius: '4px' }}
+                        />
+                    </div>
+                ))}
+            </div>
+        </div>
+    );
+};
+
+export default ActivityPreview;
diff --git a/pt--frontend/src/components/ChatBox.jsx b/pt--frontend/src/components/ChatBox.jsx
new file mode 100644
index 0000000..aec406a
--- /dev/null
+++ b/pt--frontend/src/components/ChatBox.jsx
@@ -0,0 +1,155 @@
+import React, { useState, useEffect, useRef } from 'react';
+import { getMessagesByUserIds, sendMessage } from '../api/chat'; // 替换为新API
+
+const ChatBox = ({ senderId, receiverId }) => { // 不再接收relationId
+  const [messages, setMessages] = useState([]);
+  const [inputContent, setInputContent] = useState('');
+  const messagesEndRef = useRef(null);
+
+  // 加载历史消息(改为通过用户ID获取)
+  const loadMessages = async () => {
+    try {
+      if (!senderId || !receiverId) return;
+      const data = await getMessagesByUserIds(senderId, receiverId);
+
+      // 格式化消息:同时处理friend1(chatimformation1)和friend2(chatimformation2)的消息
+      const formattedMessages = data.flatMap(msg => {
+        const messages = [];
+        // 处理friend1的消息(chatimformation1)
+        if (msg.chatimformation1) {
+          messages.push({
+            content: msg.chatimformation1,
+            isSelf: msg.friend1 === senderId,  // 发送方是friend1,判断是否是当前用户
+            talkTime: msg.talkTime  // 保留时间用于排序和唯一key
+          });
+        }
+        // 处理friend2的消息(chatimformation2)
+        if (msg.chatimformation2) {
+          messages.push({
+            content: msg.chatimformation2,
+            isSelf: msg.friend2 === senderId,  // 发送方是friend2,判断是否是当前用户
+            talkTime: msg.talkTime  // 保留时间用于排序和唯一key
+          });
+        }
+        return messages;
+      }).sort((a, b) => new Date(a.talkTime) - new Date(b.talkTime)); // 按时间升序排列
+
+      setMessages(formattedMessages);
+    } catch (error) {
+      console.error('加载消息失败:', error.message);
+    }
+  };
+
+  // 发送消息(不再需要relationId)
+  const handleSend = async () => {
+    if (!inputContent.trim()) return;
+    if (!senderId || !receiverId) { // 新增:校验用户ID有效性
+      console.error('未获取到有效的用户ID');
+      return;
+    }
+
+    try {
+      const newMessage = await sendMessage({
+        senderId,
+        receiverId,
+        content: inputContent
+      });
+      setMessages(prev => [...prev, { content: inputContent, isSelf: true }]);
+      setInputContent('');
+      scrollToBottom();
+    } catch (error) {
+      console.error('发送消息失败:', error.message);
+    }
+  };
+
+  // 依赖改为用户ID变化时重新加载
+  useEffect(() => {
+    if (senderId && receiverId) loadMessages();
+  }, [senderId, receiverId]);
+
+  const scrollToBottom = () => {
+    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
+  };
+
+  return (
+    <div className="chat-box" style={{
+      width: '400px',
+      height: '600px',
+      border: '1px solid #e5e7eb',
+      borderRadius: '8px',
+      display: 'flex',
+      flexDirection: 'column'
+    }}>
+      {/* 消息列表 */}
+      <div style={{
+        flex: 1,
+        padding: '16px',
+        overflowY: 'auto',
+        backgroundColor: '#f3f4f6'
+      }}>
+        {/* 消息列表渲染(使用数据库唯一ID作为key) */}
+        {messages.map((msg) => (
+          <div
+            key={msg.informationid}
+            style={{
+              marginBottom: '12px',
+              display: 'flex',
+              justifyContent: msg.isSelf ? 'flex-end' : 'flex-start'
+            }}
+          >
+            <div
+              style={{
+                maxWidth: '70%',
+                padding: '8px 12px',
+                borderRadius: '12px',
+                backgroundColor: msg.isSelf ? '#2563eb' : '#ffffff',
+                color: msg.isSelf ? 'white' : 'black'
+              }}
+            >
+              {msg.content}
+            </div>
+          </div>
+        ))}
+        <div ref={messagesEndRef} />
+      </div>
+
+      {/* 输入区域 */}
+      <div style={{
+        padding: '16px',
+        display: 'flex',
+        gap: '8px',
+        borderTop: '1px solid #e5e7eb'
+      }}>
+        <input
+          type="text"
+          value={inputContent}
+          onChange={(e) => setInputContent(e.target.value)}
+          onKeyPress={(e) => e.key === 'Enter' && handleSend()}
+          placeholder="输入消息..."
+          style={{
+            flex: 1,
+            padding: '8px 12px',
+            borderRadius: '6px',
+            border: '1px solid #d1d5db',
+            fontSize: '14px'
+          }}
+        />
+        <button
+          onClick={handleSend}
+          style={{
+            padding: '8px 16px',
+            backgroundColor: '#2563eb',
+            color: 'white',
+            border: 'none',
+            borderRadius: '6px',
+            cursor: 'pointer'
+          }}
+        >
+          发送
+        </button>
+      </div>
+    </div>
+  );
+};
+
+export default ChatBox;
\ No newline at end of file
diff --git a/pt--frontend/src/components/Comment.jsx b/pt--frontend/src/components/Comment.jsx
new file mode 100644
index 0000000..9708566
--- /dev/null
+++ b/pt--frontend/src/components/Comment.jsx
@@ -0,0 +1,94 @@
+// src/components/Comment.jsx
+import React, { useState, useEffect } from 'react';
+import {
+    getCommentsByPostId,
+    createComment,
+    deleteComment,
+    likeComment,
+    unlikeComment,
+} from '../api/comment';
+
+const Comment = ({ postId, currentUser }) => {
+    const [comments, setComments] = useState([]);
+    const [newContent, setNewContent] = useState('');
+
+    useEffect(() => {
+        loadComments();
+    }, [postId]);
+
+    const loadComments = async () => {
+        const data = await getCommentsByPostId(postId);
+        setComments(data);
+    };
+
+    const handleCreate = async () => {
+        if (!newContent.trim()) return;
+
+        const commentData = {
+            postid: postId,
+            userid: currentUser.id,
+            postCommentcontent: newContent,
+            commenttime: new Date().toISOString()
+        };
+
+        await createComment(commentData);
+        setNewContent('');
+        loadComments();
+    };
+
+    const handleDelete = async (commentid) => {
+        await deleteComment(commentid);
+        loadComments();
+    };
+
+    const handleLike = async (commentid) => {
+        await likeComment(commentid);
+        loadComments();
+    };
+
+    const handleUnlike = async (commentid) => {
+        await unlikeComment(commentid);
+        loadComments();
+    };
+
+    return (
+        <div>
+            <h4 className="font-semibold text-gray-700 mb-2">评论</h4>
+            <div className="mb-2">
+                <textarea
+                    value={newContent}
+                    onChange={(e) => setNewContent(e.target.value)}
+                    placeholder="写下你的评论..."
+                    className="w-full border rounded p-2"
+                />
+                <button
+                    onClick={handleCreate}
+                    className="mt-2 bg-blue-500 text-white px-3 py-1 rounded hover:bg-blue-600"
+                >
+                    发布评论
+                </button>
+            </div>
+
+            <div className="space-y-2 mt-4">
+                {comments.map((comment) => (
+                    <div key={comment.commentid} className="border rounded p-2">
+                        <div className="text-sm text-gray-800 font-medium">用户ID:{comment.userid}</div>
+                        <div className="text-gray-700">{comment.postCommentcontent}</div>
+                        <div className="text-xs text-gray-500 mt-1">
+                            {comment.commenttime || '暂无时间'} | 👍 {comment.likes}
+                        </div>
+                        <div className="flex gap-2 mt-1 text-sm">
+                            <button onClick={() => handleLike(comment.commentid)} className="text-blue-500 hover:underline">点赞</button>
+                            <button onClick={() => handleUnlike(comment.commentid)} className="text-yellow-500 hover:underline">取消点赞</button>
+                            {comment.userid === currentUser.id && (
+                                <button onClick={() => handleDelete(comment.commentid)} className="text-red-500 hover:underline">删除</button>
+                            )}
+                        </div>
+                    </div>
+                ))}
+            </div>
+        </div>
+    );
+};
+
+export default Comment;
diff --git a/pt--frontend/src/components/FriendManager.jsx b/pt--frontend/src/components/FriendManager.jsx
new file mode 100644
index 0000000..d28f93d
--- /dev/null
+++ b/pt--frontend/src/components/FriendManager.jsx
@@ -0,0 +1,156 @@
+import React, { useState, useEffect } from 'react';
+import { addFriend, deleteFriend, getFriendsByUserId } from '../api/friends';
+
+const FriendManager = ({ currentUser, onSelectRelation }) => {
+    const [friendId, setFriendId] = useState('');
+    const [friends, setFriends] = useState([]);
+    const [isLoading, setIsLoading] = useState(false);
+    const [isRefreshing, setIsRefreshing] = useState(false);
+
+    useEffect(() => {
+        if (currentUser?.id) loadFriends(currentUser.id);
+    }, [currentUser]);
+
+    const loadFriends = async (userid) => {
+        setIsRefreshing(true);
+        try {
+            const res = await getFriendsByUserId(userid);
+            setFriends(res.data);
+        } catch (err) {
+            console.error('加载好友失败', err);
+            alert('加载好友失败,请稍后重试');
+        }
+        setIsRefreshing(false);
+    };
+
+    const handleFriendIdChange = (e) => {
+        const value = e.target.value;
+        if (/^\d*$/.test(value)) setFriendId(value);
+    };
+
+    const handleAddFriend = async () => {
+        if (!friendId) return alert('请输入好友ID');
+
+        const newFriendId = parseInt(friendId, 10);
+        if (newFriendId === currentUser.id) return alert('不能添加自己为好友');
+
+        if (friends.some(f => f.friend1 === newFriendId || f.friend2 === newFriendId)) {
+            return alert('该用户已是您的好友');
+        }
+
+        setIsLoading(true);
+        try {
+            const res = await addFriend({ friend1: currentUser.id, friend2: newFriendId });
+            if (res.data) {
+                alert('添加成功');
+                setFriendId('');
+                loadFriends(currentUser.id);
+            } else {
+                alert('添加失败');
+            }
+        } catch (err) {
+            alert('添加好友失败');
+            console.error(err);
+        }
+        setIsLoading(false);
+    };
+
+    /* ---------- 这里开始:删除好友逻辑改为 friend1 + friend2 ---------- */
+    const handleDelete = async (friend1, friend2) => {
+        if (!window.confirm('确认删除该好友吗?')) return;
+        setIsLoading(true);
+        try {
+            const res = await deleteFriend(friend1, friend2);
+            if (res.data) {
+                alert('删除成功');
+                loadFriends(currentUser.id);
+            } else {
+                alert('删除失败');
+            }
+        } catch (err) {
+            alert('删除好友失败');
+            console.error(err);
+        }
+        setIsLoading(false);
+    };
+    /* ------------------------------------------------------------------- */
+
+    return (
+        <div className="max-w-xl mx-auto p-4">
+            <h2 className="text-2xl font-bold mb-4">好友管理</h2>
+
+            {/* 添加好友区域 */}
+            <div className="mb-6 space-y-2">
+                <input
+                    type="text"
+                    placeholder="输入好友的用户ID"
+                    value={friendId}
+                    onChange={handleFriendIdChange}
+                    className="border p-2 rounded w-full"
+                />
+                <button
+                    onClick={handleAddFriend}
+                    disabled={isLoading}
+                    className={`bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600 ${isLoading ? 'opacity-50 cursor-not-allowed' : ''}`}
+                >
+                    {isLoading ? '添加中…' : '添加好友'}
+                </button>
+            </div>
+
+            {/* 好友列表 */}
+            <div className="flex justify-between items-center mb-3">
+                <h3 className="text-xl font-semibold">我的好友列表</h3>
+                <button
+                    onClick={() => loadFriends(currentUser.id)}
+                    disabled={isRefreshing}
+                    className="text-sm text-blue-500 hover:underline disabled:text-gray-400"
+                >
+                    {isRefreshing ? '刷新中…' : '刷新'}
+                </button>
+            </div>
+
+            {friends.length === 0 ? (
+                <p className="text-gray-500">暂无好友</p>
+            ) : (
+                <ul className="space-y-3">
+                    {friends.map((f) => {
+                        const friendUserId =
+                            f.friend1 === currentUser.id ? f.friend2 : f.friend1;
+                        return (
+                            <li
+                                key={f.relationid}
+                                className="border p-3 rounded flex justify-between items-center hover:bg-gray-100 cursor-pointer"
+                                onClick={() =>
+                                    onSelectRelation({
+                                        relationid: f.relationid,
+                                        friendId: friendUserId,
+                                    })
+                                }
+                            >
+                                <div>
+                                    <p>好友用户ID:{friendUserId}</p>
+                                    <p className="text-sm text-gray-500">
+                                        添加时间:{new Date(f.requestTime).toLocaleString()}
+                                    </p>
+                                </div>
+                                <button
+                                    onClick={(e) => {
+                                        e.stopPropagation();
+                                        /* ------- 传入正确的 friend1 & friend2 -------- */
+                                        handleDelete(f.friend1, f.friend2);
+                                    }}
+                                    className="text-red-500 hover:underline"
+                                    disabled={isLoading}
+                                >
+                                    删除
+                                </button>
+                            </li>
+                        );
+                    })}
+                </ul>
+            )}
+        </div>
+    );
+};
+
+export default FriendManager;
diff --git a/pt--frontend/src/components/Post.jsx b/pt--frontend/src/components/Post.jsx
new file mode 100644
index 0000000..10a4840
--- /dev/null
+++ b/pt--frontend/src/components/Post.jsx
@@ -0,0 +1,200 @@
+import React, { useState, useEffect } from 'react';
+import {
+    createPost,
+    findPinnedPosts,
+    likePost,
+    unlikePost,
+    searchPosts,
+    getAllPostsSorted,
+    findPostsByUserId,
+} from '../api/post';
+import Comment from './Comment';
+
+const Post = () => {
+    const [title, setTitle] = useState('');
+    const [content, setContent] = useState('');
+    const [tags, setTags] = useState('');
+    const [photo, setPhoto] = useState(null);
+    const [posts, setPosts] = useState([]);
+    const [searchKeyword, setSearchKeyword] = useState('');
+
+    const currentUser = { id: 1, username: '测试用户' };
+
+    useEffect(() => {
+        loadPinnedPosts();  // 初始加载置顶帖子
+    }, []);
+
+    const loadPinnedPosts = async () => {
+        const data = await findPinnedPosts();
+        setPosts(data);
+    };
+
+    const loadAllPosts = async () => {
+        const data = await getAllPostsSorted();
+        setPosts(data);
+    };
+
+    const loadMyPosts = async () => {
+        const data = await findPostsByUserId(currentUser.id);
+        setPosts(data);
+    };
+
+    const handleCreate = async () => {
+        const formData = new FormData();
+        formData.append('userid', currentUser.id);
+        formData.append('post_title', title);
+        formData.append('post_content', content);
+        formData.append('is_pinned', true);
+        formData.append('tags', tags);
+        formData.append('rannge', 'public');
+        if (photo) {
+            formData.append('photo', photo);
+        }
+
+        const success = await createPost(formData);
+        if (success) {
+            alert('帖子创建成功');
+            loadPinnedPosts();
+            setTitle('');
+            setContent('');
+            setTags('');
+            setPhoto(null);
+        } else {
+            alert('创建失败');
+        }
+    };
+
+    const handleLike = async (postid) => {
+        await likePost(postid);
+        loadPinnedPosts();
+    };
+
+    const handleUnlike = async (postid) => {
+        await unlikePost(postid);
+        loadPinnedPosts();
+    };
+
+    const handleSearch = async () => {
+        const result = await searchPosts(searchKeyword);
+        setPosts(result);
+    };
+
+    return (
+        <div className="p-4 max-w-3xl mx-auto">
+            <h1 className="text-2xl font-bold mb-4">创建帖子</h1>
+            <div className="space-y-3 mb-6">
+                <input
+                    type="text"
+                    placeholder="标题"
+                    value={title}
+                    onChange={(e) => setTitle(e.target.value)}
+                    className="w-full border p-2 rounded"
+                />
+                <textarea
+                    placeholder="内容"
+                    value={content}
+                    onChange={(e) => setContent(e.target.value)}
+                    className="w-full border p-2 rounded"
+                />
+                <input
+                    type="text"
+                    placeholder="标签(用逗号分隔,如 学习,编程)"
+                    value={tags}
+                    onChange={(e) => setTags(e.target.value)}
+                    className="w-full border p-2 rounded"
+                />
+                <input
+                    type="file"
+                    onChange={(e) => setPhoto(e.target.files[0])}
+                />
+                <button
+                    onClick={handleCreate}
+                    className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
+                >
+                    发布
+                </button>
+            </div>
+
+            <div className="mb-6 flex gap-3">
+                <input
+                    type="text"
+                    placeholder="搜索关键词"
+                    value={searchKeyword}
+                    onChange={(e) => setSearchKeyword(e.target.value)}
+                    className="border p-2 rounded flex-grow"
+                />
+                <button
+                    onClick={handleSearch}
+                    className="bg-green-500 text-white px-4 py-2 rounded hover:bg-green-600"
+                >
+                    搜索
+                </button>
+            </div>
+
+            {/* 新增三个展示按钮 */}
+            <div className="mb-6 flex gap-3">
+                <button
+                    onClick={loadPinnedPosts}
+                    className="bg-yellow-500 text-white px-4 py-2 rounded hover:bg-yellow-600"
+                >
+                    置顶帖子
+                </button>
+                <button
+                    onClick={loadAllPosts}
+                    className="bg-purple-500 text-white px-4 py-2 rounded hover:bg-purple-600"
+                >
+                    所有帖子
+                </button>
+                <button
+                    onClick={loadMyPosts}
+                    className="bg-indigo-500 text-white px-4 py-2 rounded hover:bg-indigo-600"
+                >
+                    我的帖子
+                </button>
+            </div>
+
+            <h2 className="text-xl font-semibold mb-3">帖子列表</h2>
+            <div className="space-y-6">
+                {posts.map((post) => (
+                    <div key={post.postid} className="border rounded p-4 shadow bg-white">
+                        <h3 className="text-lg font-bold">{post.postTitle}</h3>
+                        <p className="text-gray-700">{post.postContent}</p>
+                        {post.photo && (
+                            <img
+                                src={`http://localhost:8080${post.photo}`}
+                                alt="post"
+                                className="w-64 h-auto mt-2"
+                            />
+                        )}
+                        <div className="mt-2 text-sm text-gray-500">
+                            发布时间:{post.postCreatedTime}
+                        </div>
+                        <div className="mt-2 text-sm text-gray-500">
+                            标签:{post.tags || '无'}
+                        </div>
+                        <div className="mt-2 flex items-center gap-4">
+                            <span>👍 {post.likes}</span>
+                            <button
+                                onClick={() => handleLike(post.postid)}
+                                className="text-blue-500 hover:underline"
+                            >
+                                点赞
+                            </button>
+                            <button
+                                onClick={() => handleUnlike(post.postid)}
+                                className="text-red-500 hover:underline"
+                            >
+                                取消点赞
+                            </button>
+                        </div>
+                        <div className="mt-4 border-t pt-4">
+                            <Comment postId={post.postid} currentUser={currentUser} />
+                        </div>
+                    </div>
+                ))}
+            </div>
+        </div>
+    );
+};
+
+export default Post;
diff --git a/pt--frontend/src/components/RequestBoard.jsx b/pt--frontend/src/components/RequestBoard.jsx
new file mode 100644
index 0000000..f90f2fb
--- /dev/null
+++ b/pt--frontend/src/components/RequestBoard.jsx
@@ -0,0 +1,300 @@
+import React, { useState, useEffect } from 'react';
+import {
+    createRequest,
+    deleteRequest,
+    updateMoney,
+    findByUserid,
+    findByName,
+    getTotalMoneyByName,
+    updateLoaduserByName,
+} from '../api/request';
+
+const RequestBoard = ({ currentUserId }) => {
+    const [requests, setRequests] = useState([]); // 始终存储当前用户的求助帖
+    const [searchedRequests, setSearchedRequests] = useState([]); // 存储搜索结果
+    const [formData, setFormData] = useState({
+        userid: currentUserId,
+        name: '',
+        plot: '',
+        money: '',
+        year: '',
+        country: '',
+        photo: null,
+    });
+    const [searchName, setSearchName] = useState('');
+    const [totalMoney, setTotalMoney] = useState(null);
+
+    // 获取当前用户求助帖
+    const loadUserRequests = async () => {
+        const data = await findByUserid(currentUserId);
+        setRequests(data);
+    };
+
+    useEffect(() => {
+        loadUserRequests();
+    }, []);
+
+    // 表单变更处理
+    const handleChange = (e) => {
+        const { name, value, files } = e.target;
+        setFormData((prev) => ({
+            ...prev,
+            [name]: files ? files[0] : value,
+        }));
+    };
+
+    // 提交创建
+    const handleCreate = async (e) => {
+        e.preventDefault();
+        const fd = new FormData();
+        Object.entries(formData).forEach(([key, value]) => {
+            if (value !== '' && value !== null) fd.append(key, value);
+        });
+
+        const res = await createRequest(fd);
+        if (res.data === true) {
+            alert('创建成功');
+            setFormData(prev => ({
+                ...prev,
+                name: '',
+                plot: '',
+                money: '',
+                year: '',
+                country: '',
+                photo: null,
+            }));
+            loadUserRequests(); // 创建成功后刷新当前用户帖子
+        } else {
+            alert('创建失败');
+        }
+    };
+
+    // 删除
+    const handleDelete = async (id) => {
+        await deleteRequest(id);
+        loadUserRequests(); // 删除后刷新当前用户帖子
+    };
+
+    // 更新金额
+    const handleUpdateMoney = async (id, newMoney) => {
+        if (!newMoney) return;
+        await updateMoney(id, newMoney);
+        loadUserRequests(); // 更新金额后刷新当前用户帖子
+    };
+
+    // 按名称搜索并计算总金额
+    const handleSearch = async () => {
+        const data = await findByName(searchName);
+        const total = await getTotalMoneyByName(searchName);
+        setSearchedRequests(data); // 搜索结果存储到独立状态
+        setTotalMoney(total);
+    };
+
+    // 上传更新被协助用户 ID(批量更新同名求助帖)
+    const handleUploadLoaduser = async (name) => {
+        try {
+            await updateLoaduserByName(name, currentUserId);
+            alert('更新成功');
+            loadUserRequests(); // 更新后刷新当前用户帖子
+            setSearchedRequests([]); // 同步清空搜索结果(可选)
+        } catch (error) {
+            alert('更新失败,请稍后重试');
+            console.error(error);
+        }
+    };
+
+    return (
+        <div className="p-4 max-w-4xl mx-auto">
+            <h2 className="text-2xl font-bold mb-4">发布求助帖</h2>
+            <form className="grid grid-cols-2 gap-4 mb-6" onSubmit={handleCreate}>
+                <input
+                    name="name"
+                    placeholder="标题/名称"
+                    className="border p-2"
+                    value={formData.name}
+                    onChange={handleChange}
+                />
+                <textarea
+                    name="plot"
+                    placeholder="内容/情节"
+                    className="border p-2 col-span-2"
+                    value={formData.plot}
+                    onChange={handleChange}
+                />
+                <input
+                    name="money"
+                    type="number"
+                    placeholder="金额"
+                    className="border p-2"
+                    value={formData.money}
+                    onChange={handleChange}
+                />
+                <input
+                    name="year"
+                    type="number"
+                    placeholder="年份"
+                    className="border p-2"
+                    value={formData.year}
+                    onChange={handleChange}
+                />
+                <input
+                    name="country"
+                    placeholder="国家"
+                    className="border p-2"
+                    value={formData.country}
+                    onChange={handleChange}
+                />
+                <input
+                    name="photo"
+                    type="file"
+                    className="border p-2 col-span-2"
+                    onChange={handleChange}
+                />
+                <button
+                    type="submit"
+                    className="bg-blue-500 text-white p-2 col-span-2 rounded"
+                >
+                    发布
+                </button>
+            </form>
+
+            <div className="mb-6">
+                <h3 className="text-xl font-semibold mb-2">查找求助帖</h3>
+                <div className="flex gap-2 mb-2">
+                    <input
+                        type="text"
+                        placeholder="输入标题"
+                        value={searchName}
+                        onChange={(e) => setSearchName(e.target.value)}
+                        className="border p-2 flex-1"
+                    />
+                    <button
+                        onClick={handleSearch}
+                        className="bg-green-500 text-white p-2 rounded"
+                    >
+                        查找
+                    </button>
+                </div>
+                {totalMoney !== null && (
+                    <p className="text-gray-700">
+                        该名称对应的总金额:<strong>{totalMoney}</strong>
+                    </p>
+                )}
+            </div>
+
+            {/* 搜索结果展示(有搜索结果时显示) */}
+            {searchedRequests.length > 0 && (
+                <div className="mb-6">
+                    <h3 className="text-xl font-semibold mb-2">搜索结果</h3>
+                    <button
+                        onClick={() => {
+                            setSearchedRequests([]);
+                            setSearchName('');
+                            setTotalMoney(null);
+                        }}
+                        className="bg-gray-500 text-white p-1 px-2 rounded mb-2"
+                    >
+                        ← 返回我的求助帖
+                    </button>
+                    {searchedRequests.length === 0 ? (
+                        <p className="text-gray-500">无匹配的求助帖</p>
+                    ) : (
+                        <div className="grid grid-cols-1 gap-4">
+                            {searchedRequests.map((request) => (
+                                <div key={request.requestid} className="border p-3 rounded shadow">
+                                    <h4 className="text-lg font-semibold">{request.name}</h4>
+                                    <p className="text-gray-600 mb-2">{request.plot}</p>
+                                    <div className="flex gap-2 mb-2">
+                                        <span>金额:{request.money}</span>
+                                        <span>年份:{request.year || '未填写'}</span>
+                                        <span>国家:{request.country || '未填写'}</span>
+                                    </div>
+                                    {request.photo && (
+                                        <img
+                                            src={`http://localhost:8080${request.photo}`}
+                                            alt="求助帖"
+                                            className="w-32 h-auto mb-2"
+                                        />
+                                    )}
+                                    <div className="flex gap-2">
+                                        <input
+                                            type="number"
+                                            placeholder="新金额"
+                                            onChange={(e) => handleUpdateMoney(request.requestid, e.target.value)}
+                                            className="border p-1 flex-1"
+                                        />
+                                        <button
+                                            onClick={() => handleDelete(request.requestid)}
+                                            className="bg-red-500 text-white p-1 px-2 rounded"
+                                        >
+                                            删除
+                                        </button>
+                                        <button
+                                            onClick={() => handleUploadLoaduser(request.name)}
+                                            className="bg-blue-500 text-white p-1 px-2 rounded"
+                                        >
+                                            上传更新loaduser
+                                        </button>
+                                    </div>
+                                </div>
+                            ))}
+                        </div>
+                    )}
+                </div>
+            )}
+
+            {/* 我的求助帖展示(无搜索结果时显示) */}
+            {searchedRequests.length === 0 && (
+                <div className="mb-6">
+                    <h3 className="text-xl font-semibold mb-2">我的求助帖</h3>
+                    {requests.length === 0 ? (
+                        <p className="text-gray-500">暂无求助帖</p>
+                    ) : (
+                        <div className="grid grid-cols-1 gap-4">
+                            {requests.map((request) => (
+                                <div key={request.requestid} className="border p-3 rounded shadow">
+                                    <h4 className="text-lg font-semibold">{request.name}</h4>
+                                    <p className="text-gray-600 mb-2">{request.plot}</p>
+                                    <div className="flex gap-2 mb-2">
+                                        <span>金额:{request.money}</span>
+                                        <span>年份:{request.year || '未填写'}</span>
+                                        <span>国家:{request.country || '未填写'}</span>
+                                    </div>
+                                    {request.photo && (
+                                        <img
+                                            src={`http://localhost:8080${request.photo}`}
+                                            alt="求助帖"
+                                            className="w-32 h-auto mb-2"
+                                        />
+                                    )}
+                                    <div className="flex gap-2">
+                                        <input
+                                            type="number"
+                                            placeholder="新金额"
+                                            onChange={(e) => handleUpdateMoney(request.requestid, e.target.value)}
+                                            className="border p-1 flex-1"
+                                        />
+                                        <button
+                                            onClick={() => handleDelete(request.requestid)}
+                                            className="bg-red-500 text-white p-1 px-2 rounded"
+                                        >
+                                            删除
+                                        </button>
+                                        <button
+                                            onClick={() => handleUploadLoaduser(request.name)}
+                                            className="bg-blue-500 text-white p-1 px-2 rounded"
+                                        >
+                                            上传更新loaduser
+                                        </button>
+                                    </div>
+                                </div>
+                            ))}
+                        </div>
+                    )}
+                </div>
+            )}
+        </div>
+    );
+};
+
+export default RequestBoard;
diff --git a/pt--frontend/src/components/torrentlist.jsx b/pt--frontend/src/components/torrentlist.jsx
new file mode 100644
index 0000000..be4b76b
--- /dev/null
+++ b/pt--frontend/src/components/torrentlist.jsx
@@ -0,0 +1,1319 @@
+// import { useState, useEffect } from 'react';
+// import { Link } from 'react-router-dom';
+// import axios from 'axios';
+
+// function TorrentList() {
+//   const [torrents, setTorrents] = useState([]);
+//   const [categories, setCategories] = useState([]);
+//   const [selectedCategory, setSelectedCategory] = useState('');
+
+//   // 获取所有分类
+//   useEffect(() => {
+//     axios.get('http://localhost:8080/categories') // 假设这个接口返回所有分类
+//       .then(res => setCategories(res.data))
+//       .catch(err => console.error('获取分类失败', err));
+//   }, []);
+
+//   // 获取种子(根据分类筛选)
+//   useEffect(() => {
+//     const url = selectedCategory
+//       ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
+//       : 'http://localhost:8080/torrent/list';
+
+//     axios.get(url)
+//       .then(res => setTorrents(res.data))
+//       .catch(err => console.error('获取种子失败', err));
+//   }, [selectedCategory]);
+//   console.log(torrents);
+  
+
+//   return (
+//     <div className="p-4">
+//       <div className="mb-4">
+//         <label className="mr-2 font-medium">选择分类:</label>
+//         <select
+//           value={selectedCategory}
+//           onChange={e => setSelectedCategory(e.target.value)}
+//           className="border rounded px-2 py-1"
+//         >
+//           <option value="">全部</option>
+//           {categories.map(cat => (
+//             <option key={cat.categoryid} value={cat.categoryid}>
+//               {cat.category_name}
+//             </option>
+//           ))}
+//         </select>
+//       </div>
+//       <table className="w-full border-collapse">
+//         <thead>
+//           <tr className="bg-gray-200">
+//             <th className="p-2 border">名称</th>
+//             <th className="p-2 border">上传者</th>
+//             <th className="p-2 border">描述</th>
+//             <th className="p-2 border">上传时间</th>
+//             <th className="p-2 border">下载次数</th>
+//             <th className="p-2 border">促销方式</th>
+//             <th className="p-2 border">操作</th>
+//           </tr>
+//         </thead>
+//         <tbody>
+//           {torrents.map(t => (
+//             <tr key={t.torrentid} className="border-t hover:bg-gray-100">
+//               <td className="p-2 border">{t.filename}</td>
+//               <td className="p-2 border">{t.uploader_id}</td>
+//               <td className="p-2 border">{t.description}</td>
+//               <td className="p-2 border">{new Date(t.uploadTime).toLocaleString()}</td>
+//               <td className="p-2 border">{t.downloadCount}</td>
+//               <td className="p-2 border">
+//           {(() => {
+//             switch(t.promotionid) {
+//               case 1: return '上传加倍';
+//               case 2: return '下载免费';
+//               case 3: return '下载减半';
+//               case 0: return '没有促销';
+//               default: return '没有促销';
+//             }
+//           })()}
+//         </td>
+//               <td className="p-2 border">
+//                 <a
+//                   href={`http://localhost:8080/torrent/download/${t.torrentid}`}
+//                   className="text-blue-500 hover:underline"
+//                   target="_blank"
+//                   rel="noreferrer"
+//                 >
+//                   下载
+//                 </a>
+//               </td>
+//               <Link
+//          to={`/torrent/${t.torrentid}`}
+//           className="text-green-600 hover:underline"
+//        >
+//         查看详情
+//        </Link>
+//             </tr>
+//           ))}
+//         </tbody>
+//       </table>
+//     </div>
+//   );
+// }
+
+// export default TorrentList;
+// import { useState, useEffect } from 'react';
+// import axios from 'axios';
+
+// function TorrentList() {
+//   const [torrents, setTorrents] = useState([]);
+//   const [categories, setCategories] = useState([]);
+//   const [selectedCategory, setSelectedCategory] = useState('');
+//   const [filters, setFilters] = useState({});
+//   const [showSuccess, setShowSuccess] = useState(false);
+//   const softwaregenres = [
+//     { value: '系统软件', label: '系统软件' },
+//     { value: '应用软件', label: '应用软件' },
+//     { value: '游戏软件', label: '游戏软件' },
+//     { value: '驱动程序', label: '驱动程序' },
+//     { value: '办公软件', label: '办公软件' },
+//     { value: '其他', label: '其他' },
+//   ]
+//   const softwareplatforms = [
+//     { value: 'Windows', label: 'Windows' },
+//     { value: 'Mac', label: 'Mac' },
+//     { value: 'Linux', label: 'Linux' },
+//     { value: 'Android', label: 'Android' },
+//     { value: 'iOS', label: 'iOS' },
+//     { value: '其他', label: '其他' },
+//   ]
+//   const softwareformats = [
+//     { value: 'EXE', label: 'EXE' }, 
+//     { value: 'DMG', label: 'DMG' },
+//     { value: '光盘镜像', label: '光盘镜像' },
+//     { value: 'APK', label: 'APK' },
+//     { value: 'IPA', label: 'IPA' },
+//     { value: '其他', label: '其他' },
+//   ]
+//    const sourceTypes = [
+//     { value: 'CCTV', label: 'CCTV' },
+//     { value: '卫视', label: '卫视' },
+//     { value: '国家地理', label: '国家地理' },
+//     { value: 'BBC', label: 'BBC' },
+//     { value: 'Discovery', label: 'Discovery' },
+//     { value: '其他', label: '其他' },
+//   ]
+//   const othergenres = [
+//     { value: '电子书', label: '电子书' },
+//     { value: '视频', label: '视频' },
+//     { value: 'MP3', label: 'MP3' },
+//     { value: '图片', label: '图片' },
+//     { value: '其他', label: '其他' },
+//   ]
+// const resolutions = [
+//     { value: '720p', label: '720p' },
+//     { value: '1080p', label: '1080p' },
+//     { value: '2K', label: '2K' },
+//     { value: '4K', label: '4K' },
+//     { value: '8K', label: '8K' },
+//     { value: '其他', label: '其他' },
+//   ];
+
+//   // 每个分类的筛选字段配置
+//   const categoryFiltersConfig = {
+//     1: [ // Movie 电影
+//       { id: 'resolution', label: '分辨率', type: 'select', options: ['1080p', '4K', '720p', '其他'] },
+//       { id: 'codecFormat', label: '编码格式', type: 'select', options: ['H.264', 'H.265', 'AV1', 'VC1', 'X264', '其他'] },
+//       { id: 'region', label: '地区', type: 'select', options: ['大陆', '港台', '欧美', '日韩', '其他'] },
+//       { id: 'genre', label: '类型', type: 'select', options: ['动作', '喜剧', '爱情', '科幻', '恐怖','动作', '冒险', '历史', '悬疑', '其他'] },
+//     ],
+//     2: [ // TV 剧集
+//       { id: 'region', label: '地区', type: 'select', options: ['大陆', '港台', '欧美', '日韩', '其他'] },
+//       { id: 'format', label: '格式', type: 'select', options: resolutions },
+//       { id: 'genre', label: '类型', type: 'select', options: ['动作', '喜剧', '爱情', '科幻', '恐怖','动作', '冒险', '历史', '悬疑', '其他'] },
+//     ],
+//     3: [ // Music 音乐
+//       { id: 'genre', label: '类型', type: 'select', options: ['专辑', '单曲', 'EP', '现场', '其他'] },
+//       { id: 'style', label: '风格', type: 'select', options: ['流行', '摇滚', '电子', '古典', '爵士', '民谣', '说唱', '其他'] },
+//     ],
+//     4: [ // Anime 动漫
+//       { id: 'genre', label: '类型', type: 'select', options: ['新番连载', '剧场版', 'OVA', '完结动漫', '其他'] },
+//       { id: 'format', label: '格式', type: 'select', options: ['ZIP', 'RAR', '7Z', 'MKV', 'MP4', '其他'] },
+//       { id: 'resolution', label: '分辨率', type: 'select', options: ['720P', '1080P', '4K', '其他'] },
+//     ],
+//     5: [ // Game 游戏
+//       { id: 'platform', label: '平台', type: 'select', options: ['PC', 'PS5', 'Xbox', 'Switch', '手机', '其他'] },
+//       { id: 'genre', label: '类型', type: 'select', options: ['角色扮演', '射击', '冒险', '策略', '体育', '桌面游戏', '其他'] },
+//       { id: 'language', label: '语言', type: 'select', options: ['中文', '英文', '日文', '其他'] },
+//       { id: 'dataType', label: '数据类型', type: 'select', options: ['压缩包', '补丁', '安装包', 'nds', '其他'] },
+//     ],
+//     6: [ // 综艺
+//       { id: 'isMainland', label: '是否为大陆综艺', type: 'select', options: ['是','不是'] },
+//       { id: 'format', label: '格式', type: 'select', options: ['1080P', '4K', 'HD', '其他'] },
+//       { id: 'genre', label: '类型', type: 'select', options: ['真人秀', '选秀','访谈', '音乐', '游戏', '其他'] },
+//     ],
+//     7: [ // 学习
+//       { id: 'genre', label: '类型', type: 'select', options: ['计算机','软件','人文','外语','理工科','其他'] },
+//       { id: 'learningformat', label: '格式', type: 'select', options: ['PDF','EPUB','视频','音频','PPT','其他'] },
+//     ],
+//     8: [ // 体育
+//       { id: 'eventType', label: '赛事类型', type: 'select', options: ['足球', '篮球', '网球', '乒乓球', '羽毛球', '其他'] },
+//       { id: 'region', label: '地区', type: 'select', options: ['亚洲', '欧洲', '美洲', '其他'] },
+//     ],
+//     9: [ // 其他
+//       { id: 'otherGenre', label: '类型', type: 'select', options: othergenres },
+//     ],
+//     10: [ // 纪录片
+//       { id: 'source', label: '来源', type: 'select', options: sourceTypes },
+//       { id: 'resolution', label: '分辨率', type: 'select', options: resolutions },
+//     ],
+//     11: [ // 软件
+//       { id: 'softwsreplatform', label: '平台', type: 'select', options: softwareplatforms },
+//       { id: 'softwareGenre', label: '软件类型', type: 'select', options: softwaregenres },
+//       { id: 'softwareFormat', label: '软件格式', type: 'select', options: softwareformats },
+//     ],
+//     // 其他分类...
+//   };
+
+//   // 获取所有分类
+//   useEffect(() => {
+//     axios.get('http://localhost:8080/categories')
+//       .then(res => setCategories(res.data))
+//       .catch(err => console.error('加载分类失败', err));
+//   }, []);
+
+//   // 根据选择的分类显示不同的表单字段
+//   useEffect(() => {
+//     setFilters({}); // 清空筛选条件
+//   }, [selectedCategory]);
+
+//   const handleFilterChange = (e) => {
+//     const { name, value } = e.target;
+//     setFilters(prev => ({ ...prev, [name]: value }));
+//   };
+
+//   const filteredTorrents = (torrents) => {
+//     return torrents.filter(torrent => {
+//       if (!selectedCategory) return true; // 如果没有选择分类,显示所有
+//       if (torrent.categoryid !== parseInt(selectedCategory)) return false;
+
+//       // 根据筛选条件过滤
+//       for (const [key, value] of Object.entries(filters)) {
+//         if (value && torrent[key] !== value) {
+//           return false;
+//         }
+//       }
+//       return true;
+//     });
+//   };
+
+//   // 获取种子(根据分类筛选)
+//   useEffect(() => {
+//     let url = selectedCategory
+//       ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
+//       : 'http://localhost:8080/torrent/list';
+
+//     // 添加筛选条件到 URL
+//     Object.entries(filters).forEach(([key, value]) => {
+//       if (value) {
+//         url += `&${key}=${encodeURIComponent(value)}`;
+//       }
+//     });
+
+//     axios.get(url)
+//       .then(res => {
+//         setTorrents(res.data);
+//       })
+//       .catch(err => console.error('获取种子失败', err));
+//   }, [selectedCategory, filters]);
+
+//   const handleDownload = (torrentId) => {
+//     window.open(`http://localhost:8080/torrent/download/${torrentId}`, '_blank');
+//   };
+
+//   return (
+//     <div className="p-4">
+//       {/* 分类选择 */}
+//       <div className="mb-4">
+//         <label className="mr-2 font-medium">选择分类:</label>
+//         <select
+//           value={selectedCategory}
+//           onChange={(e) => setSelectedCategory(e.target.value)}
+//           className="border rounded px-2 py-1 mr-4"
+//         >
+//           <option value="">全部</option>
+//           {categories.map(cat => (
+//             <option key={cat.categoryid} value={cat.categoryid}>
+//               {cat.category_name}
+//             </option>
+//           ))}
+//         </select>
+
+//         {/* 动态渲染筛选表单 */}
+//         {selectedCategory && categoryFiltersConfig[selectedCategory] && (
+//           <div className="flex flex-wrap gap-2">
+//             {categoryFiltersConfig[selectedCategory].map(filter => {
+//               if (filter.type === 'select') {
+//                 // 根据筛选字段选择对应的选项列表
+//                 let options;
+//                 switch (filter.id) {
+//                   case 'softwareplatform':
+//                     options = softwareplatforms;
+//                     break;
+//                   case 'softwareGenre':
+//                     options = softwaregenres;
+//                     break;
+//                   case 'softwareFormat':
+//                     options = softwareformats;
+//                     break;
+//                   case 'resolution':
+//                     options = [
+//                       { value: '720p', label: '720p' },
+//                       { value: '1080p', label: '1080p' },
+//                       { value: '2K', label: '2K' },
+//                       { value: '4K', label: '4K' },
+//                       { value: '8K', label: '8K' },
+//                       { value: '其他', label: '其他' },
+//                     ];
+//                     break;
+//                   case 'region':
+//                     if (selectedCategory === '1' || selectedCategory === '2') { // Movie or TV
+//                     options = [
+//                       { value: '大陆', label: '大陆' },
+//                       { value: '港台', label: '港台' },
+//                       { value: '欧美', label: '欧美' },
+//                       { value: '日韩', label: '日韩' },
+//                       { value: '其他', label: '其他' },
+//                     ];
+//                     }
+//                     else if (selectedCategory === '8') { // Sports
+//                       options = [
+//                         { value: '亚洲', label: '亚洲' },
+//                         { value: '欧洲', label: '欧洲' },
+//                         { value: '美洲', label: '美洲' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     }
+//                     break;
+//                   case 'isMainland':
+//                     options = [ 
+//                       { value: 'true', label: '是' },
+//                       { value: 'false', label: '不是' },
+//                     ];
+//                     break;
+//                   case 'codecFormat':
+//                     options = [
+//                       { value: 'H.264', label: 'H.264' },
+//                       { value: 'H.265', label: 'H.265' },
+//                       { value: 'AV1', label: 'AV1' },
+//                       { value: 'VC1', label: 'VC1' },
+//                       { value: 'X264', label: 'X264' },
+//                       { value: '其他', label: '其他' },
+//                     ];
+//                     break;
+//                   case 'platform':
+//                     options = [
+//                       { value: 'PC', label: 'PC' },
+//                       { value: 'PS5', label: 'PS5' },
+//                       { value: 'Xbox', label: 'Xbox' },
+//                       { value: 'Switch', label: 'Switch' },
+//                       { value: '手机', label: '手机' },
+//                       { value: '其他', label: '其他' },
+//                     ];
+//                     break;
+//                   case 'language':
+//                       options = [
+//                         { value: '中文', label: '中文' },
+//                         { value: '英文', label: '英文' },
+//                         { value: '日文', label: '日文' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                       break;
+//                   case'EventType':
+//                     options = [
+//                       { value: '足球', label: '足球' },
+//                       { value: '篮球', label: '篮球' },
+//                       { value: '网球', label: '网球' },
+//                       { value: '乒乓球', label: '乒乓球' },
+//                       { value: '羽毛球', label: '羽毛球' },
+//                       { value: '其他', label: '其他' },
+//                     ];
+//                     break;
+//                   case 'genre':
+//                     if (selectedCategory === '3') { // Music
+//                       options = [
+//                         { value: '专辑', label: '专辑' },
+//                         { value: '单曲', label: '单曲' },
+//                         { value: 'EP', label: 'EP' },
+//                         { value: '现场', label: '现场' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else if (selectedCategory === '4') { // Anime
+//                       options = [
+//                         { value: '新番连载', label: '新番连载' },
+//                         { value: '剧场版', label: '剧场版' },
+//                         { value: 'OVA', label: 'OVA' },
+//                         { value: '完结动漫', label: '完结动漫' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else if (selectedCategory === '5') { // Game
+//                       options = [
+//                         { value: '角色扮演', label: '角色扮演' },
+//                         { value: '射击', label: '射击' },
+//                         { value: '冒险', label: '冒险' },
+//                         { value: '策略', label: '策略' },
+//                         { value: '体育', label: '体育' },
+//                         { value: '桌面游戏', label: '桌面游戏' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else if (selectedCategory === '1') { // TV
+//                       options = [
+//                         { value: '动作', label: '动作' },
+//                         { value: '喜剧', label: '喜剧' },
+//                         { value: '爱情', label: '爱情' },
+//                         { value: '科幻', label: '科幻' },
+//                         { value: '恐怖', label: '恐怖' },
+//                         { value: '动作', label: '动作' },
+//                         { value: '冒险', label: '冒险' },
+//                         { value: '历史', label: '历史' },
+//                         { value: '悬疑', label: '悬疑' },
+//                         { value: '其他', label: '其他' },
+//                       ]; 
+//                     }
+//                     else if(selectedCategory === '2') {
+//                        options = [
+//                         { value: '动作', label: '动作' },
+//                         { value: '喜剧', label: '喜剧' },
+//                         { value: '爱情', label: '爱情' },
+//                         { value: '科幻', label: '科幻' },
+//                         { value: '恐怖', label: '恐怖' },
+//                         { value: '动作', label: '动作' },
+//                         { value: '冒险', label: '冒险' },
+//                         { value: '历史', label: '历史' },
+//                         { value: '悬疑', label: '悬疑' },
+//                         { value: '其他', label: '其他' },
+//                       ]; // Movie
+//                     }
+//                     else if(selectedCategory === '6') {
+//                       options = [
+//                         { value: '真人秀', label: '真人秀' },
+//                         { value: '选秀', label: '选秀' },
+//                         { value: '访谈', label: '访谈' },
+//                         { value: '音乐', label: '音乐' },
+//                         { value: '游戏', label: '游戏' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     }
+//                     break;
+//                   case 'style':
+//                     if (selectedCategory === '3') { // Music
+//                       options = [
+//                         { value: '流行', label: '流行' },
+//                         { value: '摇滚', label: '摇滚' },
+//                         { value: '电子', label: '电子' },
+//                         { value: '古典', label: '古典' },
+//                         { value: '爵士', label: '爵士' },
+//                         { value: '民谣', label: '民谣' },
+//                         { value: '说唱', label: '说唱' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else {
+//                       options = []; // 根据需要定义
+//                     }
+//                     break;
+//                   case 'dataType':
+//                     if (selectedCategory === '5') { // Game
+//                       options = [
+//                         { value: '压缩包', label: '压缩包' },
+//                         { value: '补丁', label: '补丁' },
+//                         { value: '安装包', label: '安装包' },
+//                         { value: 'nds', label: 'nds' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else {
+//                       options = []; // 根据需要定义
+//                     }
+//                     break;
+//                   case 'format': if(selectedCategory === '4') {
+//                       options = [
+//                         { value: 'ZIP', label: 'ZIP' }, 
+//                         { value: 'RAR', label: 'RAR' },
+//                         { value: '7Z', label: '7Z' },
+//                         { value: 'MKV', label: 'MKV' },
+//                         { value: 'MP4', label: 'MP4' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else if(selectedCategory === '6') {
+//                       options = [
+//                         { value: '1080P', label: '1080P' },
+//                         { value: '4K', label: '4K' },
+//                         { value: 'HD', label: 'HD' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else if(selectedCategory === '2') {
+//                       options = [ { value: '720p', label: '720p' },
+//                                    { value: '1080p', label: '1080p' },
+//                                  { value: '2K', label: '2K' },
+//                                   { value: '4K', label: '4K' },
+//                                    { value: '8K', label: '8K' },
+//                                     { value: '其他', label: '其他' },
+//                       ];
+//                     } else {
+//                       options = []; // 根据需要定义
+//                     }
+//                     break;
+//                   case 'eventType':
+//                     if (selectedCategory === '7') { // Sports
+//                       options = [
+//                         { value: '足球', label: '足球' },
+//                         { value: '篮球', label: '篮球' },
+//                         { value: '网球', label: '网球' },
+//                         { value: '乒乓球', label: '乒乓球' },
+//                         { value: '羽毛球', label: '羽毛球' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else {
+//                       options = []; // 根据需要定义
+//                     }
+//                     break;
+//                   case 'source':
+//                     if (selectedCategory === '10') { // Documentary
+//                       options = [
+//                         { value: 'CCTV', label: 'CCTV' },
+//                         { value: '卫视', label: '卫视' },
+//                         { value: '国家地理', label: '国家地理' },
+//                         { value: 'BBC', label: 'BBC' },
+//                         { value: 'Discovery', label: 'Discovery' },
+//                         { value: '其他', label: '其他' },
+//                       ];
+//                     } else {
+//                       options = []; // 根据需要定义
+//                     }
+//                     break;
+//                   default:
+//                     options = []; // 默认无选项
+//                 }
+
+//                 return (
+//                   <select
+//                     key={filter.id}
+//                     name={filter.id}
+//                     value={filters[filter.id] || ''}
+//                     onChange={handleFilterChange}
+//                     className="border rounded px-2 py-1"
+//                   >
+//                     <option value="">全部</option>
+//                     {options.map(option => (
+//                       <option key={option.value} value={option.value}>
+//                         {option.label}
+//                       </option>
+//                     ))}
+//                   </select>
+//                 );
+//               }
+//               // 其他类型(如输入框)可以类似实现
+//               return null;
+//             })}
+//           </div>
+//         )}
+//       </div>
+
+//       {/* 筛选按钮 */}
+//       <button
+//         onClick={() => {
+//           // 这里可以根据需要添加额外的筛选逻辑
+//           // 例如,如果某些筛选需要联动,可以在这里处理
+//         }}
+//         className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600 ml-4"
+//       >
+//         应用筛选
+//       </button>
+
+//       {/* 种子列表 */}
+//       <table className="w-full border-collapse mt-4">
+//         <thead>
+//           <tr className="bg-gray-200">
+//             <th className="p-2 border">名称</th>
+//             <th className="p-2 border">上传者</th>
+//             <th className="p-2 border">描述</th>
+//             <th className="p-2 border">上传时间</th>
+//             <th className="p-2 border">下载次数</th>
+//             <th className="p-2 border">促销方式</th>
+//             <th className="p-2 border">操作</th>
+//           </tr>
+//         </thead>
+//         <tbody>
+//           {torrents.map(t => (
+//             <tr key={t.torrentid} className="border-t hover:bg-gray-100">
+//               <td className="p-2 border">{t.filename}</td>
+//               <td className="p-2 border">{t.uploader_id}</td>
+//               <td className="p-2 border">{t.description}</td>
+//               <td className="p-2 border">{new Date(t.uploadTime).toLocaleString()}</td>
+//               <td className="p-2 border">{t.downloadCount}</td>
+//               <td className="p-2 border">
+//                 {(() => {
+//                   switch(t.promotionid) {
+//                     case 1: return '上传加倍';
+//                     case 2: return '下载免费';
+//                     case 3: return '下载减半';
+//                     case 0: return '没有促销';
+//                     default: return '没有促销';
+//                   }
+//                 })()}
+//               </td>
+//               <td className="p-2 border">
+//                 <button
+//                   onClick={() => handleDownload(t.torrentid)}
+//                   className="text-blue-500 hover:underline mr-2"
+//                 >
+//                   下载
+//                 </button>
+//                 <a
+//                   href={`/torrent/${t.torrentid}`}
+//                   className="text-green-600 hover:underline"
+//                 >
+//                   查看详情
+//                 </a>
+//               </td>
+//             </tr>
+//           ))}
+//         </tbody>
+//       </table>
+
+//       {/* 成功提示 */}
+//       {showSuccess && (
+//         <div className="mt-4 p-3 bg-green-100 text-green-800 border border-green-300 rounded">
+//           上传成功!
+//         </div>
+//       )}
+//     </div>
+//   );
+// }
+
+// export default TorrentList;
+import { useState, useEffect } from 'react';
+import axios from 'axios';
+
+// 常量配置集中管理
+const FILTER_OPTIONS = {
+  // 通用选项
+  common: {
+    resolution: [
+      { value: '720p', label: '720p' },
+      { value: '1080p', label: '1080p' },
+      { value: '2K', label: '2K' },
+      { value: '4K', label: '4K' },
+      { value: '8K', label: '8K' },
+      { value: '其他', label: '其他' },
+    ],
+    region: {
+      movie: [
+        { value: '大陆', label: '大陆' },
+        { value: '港台', label: '港台' },
+        { value: '欧美', label: '欧美' },
+        { value: '日韩', label: '日韩' },
+        { value: '其他', label: '其他' },
+      ],
+      variety: [
+        { value: '大陆', label: '大陆' },
+        { value: '港台', label: '港台' },
+        { value: '欧美', label: '欧美' },
+        { value: '日韩', label: '日韩' },
+        { value: '其他', label: '其他' },
+      ],
+      sports: [
+        { value: '亚洲', label: '亚洲' },
+        { value: '欧洲', label: '欧洲' },
+        { value: '美洲', label: '美洲' },
+        { value: '其他', label: '其他' },
+      ]
+    },
+    genre: {
+      movie: [
+        { value: '动作', label: '动作' },
+        { value: '喜剧', label: '喜剧' },
+        { value: '爱情', label: '爱情' },
+        { value: '科幻', label: '科幻' },
+        { value: '恐怖', label: '恐怖' },
+        { value: '冒险', label: '冒险' },
+        { value: '历史', label: '历史' },
+        { value: '悬疑', label: '悬疑' },
+        { value: '其他', label: '其他' },
+      ],
+      music: [
+        { value: '流行', label: '流行' },
+        { value: '摇滚', label: '摇滚' },
+        { value: '电子', label: '电子' },
+        { value: '古典', label: '古典' },
+        { value: '爵士', label: '爵士' },
+        { value: '民谣', label: '民谣' },
+        { value: '说唱', label: '说唱' },
+        { value: '其他', label: '其他' },
+      ],
+      anime: [
+        { value: '新番连载', label: '新番连载' },
+        { value: '剧场版', label: '剧场版' },
+        { value: 'OVA', label: 'OVA' },
+        { value: '完结动漫', label: '完结动漫' },
+        { value: '其他', label: '其他' },
+      ],
+      game: [
+        { value: '角色扮演', label: '角色扮演' },
+        { value: '射击', label: '射击' },
+        { value: '冒险', label: '冒险' },
+        { value: '策略', label: '策略' },
+        { value: '体育', label: '体育' },
+        { value: '桌面游戏', label: '桌面游戏' },
+        { value: '其他', label: '其他' },
+      ],
+      variety: [
+        { value: '真人秀', label: '真人秀' },
+        { value: '选秀', label: '选秀' },
+        { value: '访谈', label: '访谈' },
+        { value: '音乐', label: '音乐' },
+        { value: '游戏', label: '游戏' },
+        { value: '其他', label: '其他' },
+      ],
+      learning: [
+        { value: '计算机', label: '计算机' },
+        { value: '软件', label: '软件' },
+        { value: '人文', label: '人文' },
+        { value: '外语', label: '外语' },
+        { value: '理工科', label: '理工科' },
+        { value: '其他', label: '其他' },
+      ],
+      sports: [
+        { value: '足球', label: '足球' },
+        { value: '篮球', label: '篮球' },
+        { value: '网球', label: '网球' },
+        { value: '乒乓球', label: '乒乓球' },
+        { value: '羽毛球', label: '羽毛球' },
+        { value: '其他', label: '其他' },
+      ],
+      // 其他类型...
+    }
+  },
+  
+  // 分类特定选项
+  categories: {
+    1: { // 电影
+      name: '电影',
+      filters: [
+        { id: 'resolution', label: '分辨率', type: 'select' },
+        { id: 'codec_format', label: '编码格式', type: 'select', 
+          options: [
+            { value: 'H.264', label: 'H.264' },
+            { value: 'H.265', label: 'H.265' },
+            { value: 'AV1', label: 'AV1' },
+            { value: 'VC1', label: 'VC1' },
+            { value: 'X264', label: 'X264' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'region', label: '地区', type: 'select' },
+        { id: 'genre', label: '类型', type: 'select' }
+      ]
+    },
+    2: { // 电视剧
+      name: '剧集',
+      filters: [
+        { id: 'region', label: '地区', type: 'select',
+          options: [
+            { value: '大陆', label: '大陆' },
+            { value: '港台', label: '港台' },
+            { value: '欧美', label: '欧美' },
+            { value: '日韩', label: '日韩' },
+            { value: '其他', label: '其他' },
+          ]
+         },
+        { id: 'format', label: '分辨率', type: 'select',
+          options: [
+            { value: '720p', label: '720p' },
+            { value: '1080p', label: '1080p' },
+            { value: '2K', label: '2K' },
+            { value: '4K', label: '4K' },
+            { value: '8K', label: '8K' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'genre', label: '类型', type: 'select' ,
+          options:[
+            { value: '真人秀', label: '真人秀' },
+            { value: '选秀', label: '选秀' },
+            { value: '访谈', label: '访谈' },
+            { value: '游戏', label: '游戏' },
+            { value: '音乐', label: '音乐' },
+            { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    3: { // 音乐
+      name: '音乐',
+      filters: [
+        { id: 'genre', label: '类型', type: 'select', 
+          options: [
+            { value: '专辑', label: '专辑' },
+            { value: '单曲', label: '单曲' },
+            { value: 'EP', label: 'EP' },
+            { value: '现场', label: '现场' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'style', label: '风格', type: 'select',
+          options: [
+            { value: '流行', label: '流行' },
+            { value: '摇滚', label: '摇滚' },
+            { value: '电子', label: '电子' },
+            { value: '古典', label: '古典' },
+            { value: '爵士', label: '爵士' },
+            { value: '民谣', label: '民谣' },
+            { value: '说唱', label: '说唱' },
+            { value: '其他', label: '其他' },
+          ]
+         },
+         {id:'format', label: '格式', type: 'select',
+          options:[
+            { value: 'MP3', label: 'MP3' },
+            { value: 'FLAC', label: 'FLAC' },
+            { value: 'WAV', label: 'WAV' },
+            { value: 'AAC', label: 'AAC' },
+            { value: 'OGG', label: 'OGG' },
+            { value: '其他', label: '其他' },
+          ]
+         }
+      ]
+    },
+    4: { // 动漫
+      name: '动漫',
+      filters: [
+        { id: 'genre', label: '类型', type: 'select' ,
+          options: [
+            { value: '新番连载', label: '新番连载' },
+            { value: '剧场版', label: '剧场版' },
+            { value: 'OVA', label: 'OVA' },
+            { value: '完结动漫', label: '完结动漫' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'format', label: '格式', type: 'select' ,
+          options:[
+            { value: 'ZIP', label: 'ZIP' },
+    { value: 'RAR', label: 'RAR' },
+    { value: '7Z', label: '7Z' },
+    { value: 'MKV', label: 'MKV' },
+    { value: 'MP4', label: 'MP4' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'resolution', label: '分辨率', type: 'select',
+          options:[
+             { value: '720p', label: '720p' },
+      { value: '1080p', label: '1080p' },
+      { value: '2K', label: '2K' },
+      { value: '4K', label: '4K' },
+      { value: '8K', label: '8K' },
+      { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    5: { // 游戏
+      name: '游戏',
+      filters: [
+        { id: 'platform', label: '平台', type: 'select', 
+          options: [
+            { value: 'PC', label: 'PC' },
+            { value: 'PS5', label: 'PS5' },
+            { value: 'Xbox', label: 'Xbox' },
+            { value: 'Switch', label: 'Switch' },
+            { value: '手机', label: '手机' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'genre', label: '类型', type: 'select', 
+          options: [
+            { value: '角色扮演', label: '角色扮演' },
+            { value: '射击', label: '射击' },
+            { value: '冒险', label: '冒险' },
+            { value: '策略', label: '策略' },
+            { value: '体育', label: '体育' },
+            { value: '桌面游戏', label: '桌面游戏' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'data_format', label: '数据类型', type: 'select' ,
+          options: [
+            { value: '压缩包', label: '压缩包' },
+            { value: '补丁', label: '补丁' },
+            { value: '安装包', label: '安装包' },
+            { value: 'nds', label: 'nds' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'language', label: '语言', type: 'select',
+          options: [
+            { value: '中文', label: '中文' },
+            { value: '英文', label: '英文' },
+            { value: '日文', label: '日文' },
+            { value: '其他', label: '其他' },
+          ]
+         }
+      ]
+    },
+    6: { // 综艺
+      name: '综艺',
+      filters: [
+        { id: 'is_mainland', label: '是否大陆综艺', type: 'select' ,
+          options:[
+            { value: 'true', label: '是' },
+            { value: 'false', label: ' 不是' },
+          ]
+        },
+        { id: 'format', label: '分辨率', type: 'select',
+          options:[
+              { value: '720p', label: '720p' },
+      { value: '1080p', label: '1080p' },
+      { value: '2K', label: '2K' },
+      { value: '4K', label: '4K' },
+      { value: '8K', label: '8K' },
+      { value: '其他', label: '其他' },
+          ]
+        },
+        {id: 'genre', label: '类型', type: 'select',
+          options:[
+            { value: '真人秀', label: '真人秀' },
+    { value: '选秀', label: '选秀' },
+    { value: '访谈', label: '访谈' },
+    { value: '游戏', label: '游戏' },
+    { value: '音乐', label: '音乐' },
+    { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    7: { // 体育
+      name: '体育',
+      filters: [
+        { id: 'genre', label: '体育类型', type: 'select' ,
+          options:[
+             { value: '足球', label: '足球' },
+    { value: '篮球', label: '篮球' },
+    { value: '网球', label: '网球' },
+    { value: '乒乓球', label: '乒乓球' },
+    { value: '羽毛球', label: '羽毛球' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'event_type', label: '赛事类型', type: 'select',
+          options:[
+            { value: '足球', label: '足球' },
+    { value: '篮球', label: '篮球' },
+    { value: '网球', label: '网球' },
+    { value: '乒乓球', label: '乒乓球' },
+    { value: '羽毛球', label: '羽毛球' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'format', label: '分辨率', type: 'select',
+          options:[
+              { value: '720p', label: '720p' },
+      { value: '1080p', label: '1080p' },
+      { value: '2K', label: '2K' },
+      { value: '4K', label: '4K' },
+      { value: '8K', label: '8K' },
+      { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    8: { // 软件
+      name: '软件',
+      filters: [
+        { id: 'platform', label: '平台', type: 'select' ,
+          options:[
+            { value: 'Windows', label: 'Windows' },
+    { value: 'Mac', label: 'Mac' },
+    { value: 'Linux', label: 'Linux' },
+    { value: 'Android', label: 'Android' },
+    { value: 'iOS', label: 'iOS' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'format', label: '格式', type: 'select',
+          options:[
+          { value: 'EXE', label: 'EXE' }, 
+    { value: 'DMG', label: 'DMG' },
+    { value: '光盘镜像', label: '光盘镜像' },
+    { value: 'APK', label: 'APK' },
+    { value: 'IPA', label: 'IPA' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'genre', label: '类型', type: 'select',
+          options:[
+           { value: '系统软件', label: '系统软件' },
+    { value: '应用软件', label: '应用软件' },
+    { value: '游戏软件', label: '游戏软件' },
+    { value: '驱动程序', label: '驱动程序' },
+    { value: '办公软件', label: '办公软件' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+      ]
+    },
+    9: { // 学习
+      name: '学习',
+      filters: [
+        { id: 'genre', label: '类型', type: 'select' ,
+          options:[
+            { value: '计算机', label: '计算机' },
+            { value: '软件', label: '软件' },
+            { value: '人文', label: '人文' },
+            { value: '外语', label: '外语' },
+            { value: '理工科', label: '理工科' },
+            { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'format', label: '格式', type: 'select',
+          options:[
+             { value: 'PDF', label: 'PDF' },
+    { value: 'EPUB', label: 'EPUB' },
+    { value: '视频', label: '视频' },
+    { value: '音频', label: '音频' },
+    { value: 'PPT', label: 'PPT' },
+    { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    10: { // 纪录片
+      name: '纪录片',
+      filters: [
+        { id: 'source', label: '视频源', type: 'select',
+          options:[
+             { value: 'CCTV', label: 'CCTV' },
+    { value: '卫视', label: '卫视' },
+    { value: '国家地理', label: '国家地理' },
+    { value: 'BBC', label: 'BBC' },
+    { value: 'Discovery', label: 'Discovery' },
+    { value: '其他', label: '其他' },
+          ]
+        },
+        { id: 'format', label: '格式', type: 'select',
+          options:[
+             { value: '720p', label: '720p' },
+    { value: '1080p', label: '1080p' },
+    { value: '2K', label: '2K' },
+    { value: '4K', label: '4K' },
+    { value: '8K', label: '8K' },
+    { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    },
+    11: { // 其他
+      name: '其他',
+      filters: [
+        { id: 'gener', label: '类型', type: 'select',
+          options:[
+           { value: '电子书', label: '电子书' },
+    { value: '视频', label: '视频' },
+    { value: 'MP3', label: 'MP3' },
+    { value: '图片', label: '图片' },
+    { value: '其他', label: '其他' },
+          ]
+        }
+      ]
+    }
+    // 其他分类配置...
+  }
+};
+
+// 获取分类筛选配置
+const getCategoryFilters = (categoryId) => {
+  const category = FILTER_OPTIONS.categories[categoryId];
+  if (!category) return [];
+  
+  return category.filters.map(filter => {
+    // 自动填充通用选项
+    if (filter.id === 'resolution' && !filter.options) {
+      return { ...filter, options: FILTER_OPTIONS.common.resolution };
+    }
+    if (filter.id === 'region' && !filter.options) {
+      const regionType = categoryId === 8 ? 'sports' : 'movie';
+      return { ...filter, options: FILTER_OPTIONS.common.region[regionType] };
+    }
+    if (filter.id === 'genre' && !filter.options) {
+      const genreType = categoryId === 3 ? 'music' : 'movie';
+      return { ...filter, options: FILTER_OPTIONS.common.genre[genreType] };
+    }
+    return filter;
+  });
+};
+
+// 格式化日期显示
+const formatDate = (dateString) => {
+  const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' };
+  return new Date(dateString).toLocaleString('zh-CN', options);
+};
+
+// 获取促销方式名称
+const getPromotionName = (promotionId) => {
+  switch(promotionId) {
+    case 1: return '上传加倍';
+    case 2: return '下载免费';
+    case 3: return '下载减半';
+    default: return '没有促销';
+  }
+};
+
+function TorrentList() {
+  const [torrents, setTorrents] = useState([]);
+  const [categories, setCategories] = useState([]);
+  const [selectedCategory, setSelectedCategory] = useState('');
+  const [filters, setFilters] = useState({});
+  const [isLoading, setIsLoading] = useState(false);
+  const [error, setError] = useState(null);
+  
+  // 获取所有分类
+  useEffect(() => {
+    const fetchCategories = async () => {
+      try {
+        const res = await axios.get('http://localhost:8080/categories');
+        setCategories(res.data);
+      } catch (err) {
+        console.error('加载分类失败', err);
+        setError('加载分类失败,请稍后重试');
+      }
+    };
+    fetchCategories();
+  }, []);
+
+  // 获取种子数据
+  useEffect(() => {
+    const fetchTorrents = async () => {
+      setIsLoading(true);
+      setError(null);
+      try {
+        let url = selectedCategory
+          // ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
+          ? `http://localhost:8080/torrent/listByCategorywithfilter?categoryid=${selectedCategory}`
+          : 'http://localhost:8080/torrent/list';
+        
+        // 添加筛选参数
+        const params = new URLSearchParams();
+        Object.entries(filters).forEach(([key, value]) => {
+          if (value) params.append(key, value);
+        });
+        
+        const res = await axios.get(`${url}&${params.toString()}`);
+        setTorrents(res.data);
+        console.log('torrents:', torrents);
+      } catch (err) {
+        console.error('获取种子失败', err);
+        setError('获取种子列表失败,请稍后重试');
+      } finally {
+        setIsLoading(false);
+      }
+    };
+    console.log('Fetching torrents with filters:', filters);
+    console.log('Selected category:', selectedCategory);
+    console.log(torrents);
+    const timer = setTimeout(fetchTorrents, 300); // 防抖
+    return () => clearTimeout(timer);
+  }, [selectedCategory, filters]);
+
+  // 切换分类时重置筛选条件
+  const handleCategoryChange = (categoryId) => {
+    setSelectedCategory(categoryId);
+    setFilters({});
+  };
+
+  // 处理筛选条件变化
+  const handleFilterChange = (e) => {
+    const { name, value } = e.target;
+    setFilters(prev => ({ ...prev, [name]: value }));
+  };
+
+  // 下载种子
+  const handleDownload = (torrentId) => {
+    window.open(`http://localhost:8080/torrent/download/${torrentId}`, '_blank');
+  };
+
+  // 获取当前分类的筛选配置
+  const currentFilters = getCategoryFilters(selectedCategory);
+
+  return (
+    <div className="p-4 max-w-7xl mx-auto">
+      <h1 className="text-2xl font-bold mb-6">种子列表</h1>
+      
+      {/* 分类选择 */}
+      <div className="mb-6 bg-white p-4 rounded-lg shadow">
+        <div className="flex flex-wrap items-center gap-4">
+          <div className="flex items-center">
+            <label className="mr-2 font-medium whitespace-nowrap">选择分类:</label>
+            <select
+              value={selectedCategory}
+              onChange={(e) => handleCategoryChange(e.target.value)}
+              className="border rounded px-3 py-2 min-w-[150px]"
+            >
+              <option value="">全部分类</option>
+              {categories.map(cat => (
+                <option key={cat.categoryid} value={cat.categoryid}>
+                  {cat.category_name}
+                </option>
+              ))}
+            </select>
+          </div>
+
+          {/* 动态筛选表单 */}
+          {currentFilters.length > 0 && (
+            <div className="flex flex-wrap gap-4">
+              {currentFilters.map(filter => (
+                <div key={filter.id} className="flex items-center">
+                  <label className="mr-2 text-sm whitespace-nowrap">{filter.label}:</label>
+                  <select
+                    name={filter.id}
+                    value={filters[filter.id] || ''}
+                    onChange={handleFilterChange}
+                    className="border rounded px-3 py-2 min-w-[120px]"
+                  >
+                    <option value="">全部</option>
+                    {filter.options.map(option => (
+                      <option key={option.value} value={option.value}>
+                        {option.label}
+                      </option>
+                    ))}
+                  </select>
+                </div>
+              ))}
+            </div>
+          )}
+        </div>
+      </div>
+      
+
+      {/* 错误提示 */}
+      {error && (
+        <div className="mb-4 p-3 bg-red-100 text-red-700 rounded border border-red-200">
+          {error}
+        </div>
+      )}
+      
+     
+      {/* 加载状态 */}
+      {isLoading ? (
+        <div className="flex justify-center items-center h-64">
+          <div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
+        </div>
+      ) : (
+        /* 种子列表 */
+        <div className="bg-white rounded-lg shadow overflow-hidden">
+          <div className="overflow-x-auto">
+            <table className="w-full">
+              <thead className="bg-gray-50">
+                <tr>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">名称</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">大小</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">上传者</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">上传时间</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">下载次数</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">促销</th>
+                  <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th>
+                </tr>
+              </thead>
+              <tbody className="bg-white divide-y divide-gray-200">
+                {torrents.length > 0 ? (
+                  torrents.map(torrent => (
+                    <tr key={torrent.torrentid} className="hover:bg-gray-50">
+                      <td className="px-6 py-4 whitespace-nowrap">
+                        <div className="text-sm font-medium text-gray-900">{torrent.filename}</div>
+                        <div className="text-sm text-gray-500">{torrent.description}</div>
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                        {torrent.torrentSize} B
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                        {torrent.uploader_id}
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                        {new Date(torrent.uploadTime).toLocaleString()}
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                        {torrent.downloadCount}
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
+                        {getPromotionName(torrent.promotionid)}
+                      </td>
+                      <td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
+                        <button
+                          onClick={() => handleDownload(torrent.torrentid)}
+                          className="text-blue-600 hover:text-blue-900 mr-4"
+                        >
+                          下载
+                        </button>
+                        <a
+                          href={`/torrent/${torrent.torrentid}`}
+                          className="text-green-600 hover:text-green-900"
+                        >
+                          详情
+                        </a>
+                      </td>
+                    </tr>
+                  ))
+                ) : (
+                  <tr>
+                    <td colSpan="7" className="px-6 py-4 text-center text-sm text-gray-500">
+                      没有找到符合条件的种子
+                    </td>
+                  </tr>
+                )}
+              </tbody>
+            </table>
+          </div>
+        </div>
+      )}
+    </div>
+  );
+}
+
+export default TorrentList;
\ No newline at end of file
diff --git a/pt--frontend/src/components/upload.jsx b/pt--frontend/src/components/upload.jsx
new file mode 100644
index 0000000..c2cdc76
--- /dev/null
+++ b/pt--frontend/src/components/upload.jsx
@@ -0,0 +1,1461 @@
+// // import React, { useState, useEffect } from 'react';
+// // import axios from 'axios';
+
+// // function UploadTorrent() {
+// //   const [title, setTitle] = useState('');
+// //   const [description, setDescription] = useState('');
+// //   const [categoryId, setCategoryId] = useState('');
+// //   const [dpi, setDpi] = useState('');  // 可选字段
+// //   const [caption, setCaption] = useState('');  // 可选字段
+// //   const [file, setFile] = useState(null);
+// //   const [categories, setCategories] = useState([]);
+// //   const [showSuccess, setShowSuccess] = useState(false);
+
+// //   useEffect(() => {
+// //     axios.get('http://localhost:8080/categories')
+// //       .then(res => setCategories(res.data))
+// //       .catch(err => console.error('加载分类失败', err));
+// //   }, []);
+
+// //   const handleSubmit = async (e) => {
+// //     e.preventDefault();
+// //     if (!file) {
+// //       alert('请选择一个 .torrent 文件');
+// //       return;
+// //     }
+
+// //     if (!categoryId) {
+// //       alert('请选择分类');
+// //       return;
+// //     }
+
+// //     const formData = new FormData();
+// //     formData.append('file', file);
+// //     formData.append('title', title);
+// //     formData.append('description', description);
+// //     formData.append('categoryId', categoryId);
+// //     if (dpi) formData.append('dpi', dpi);  // 只有当 dpi 有值时才添加
+// //     if (caption) formData.append('caption', caption);  // 只有当 caption 有值时才添加
+
+// //     try {
+// //       await axios.post('http://localhost:8080/torrent/upload', formData, {
+// //         headers: { 'Content-Type': 'multipart/form-data' },
+// //         responseType: 'blob', // 关键:指定响应类型为 blob
+// //       });
+     
+// //       // 创建下载链接
+// //       const url = window.URL.createObjectURL(new Blob([response.data]));
+// //       const link = document.createElement('a');
+// //       link.href = url;
+// //       link.setAttribute('download', file.name); // 使用原文件名
+// //       document.body.appendChild(link);
+// //       link.click();
+// //       link.remove();
+// //       // 清空表单
+// //       setShowSuccess(true);
+// //       setTitle('');
+// //       setDescription('');
+// //       setCategoryId('');
+// //       setDpi('');
+// //       setCaption('');
+// //       setFile(null);
+// //     } catch (err) {
+// //       console.error('上传失败', err.response?.data || err.message);
+// //       alert(err.response?.data || '上传失败,请检查后端是否启动');
+// //     }
+// //   };
+
+// //   return (
+// //     <div className="max-w-xl mx-auto mt-10 p-6 bg-white shadow rounded">
+// //       <h2 className="text-2xl font-bold mb-4">上传种子</h2>
+// //       <form onSubmit={handleSubmit} className="space-y-4">
+// //         <input type="file" accept=".torrent" onChange={(e) => setFile(e.target.files[0])} />
+// //         <input
+// //           type="text"
+// //           placeholder="标题"
+// //           value={title}
+// //           onChange={(e) => setTitle(e.target.value)}
+// //           className="w-full p-2 border rounded"
+// //           required
+// //         />
+// //         <textarea
+// //           placeholder="描述"
+// //           value={description}
+// //           onChange={(e) => setDescription(e.target.value)}
+// //           className="w-full p-2 border rounded"
+// //         />
+// //         <select
+// //           value={categoryId}
+// //           onChange={(e) => setCategoryId(e.target.value)}
+// //           className="w-full p-2 border rounded"
+// //           required
+// //         >
+// //           <option value="">请选择分类</option>
+// //           {categories.map(cat => (
+// //             <option key={cat.categoryid} value={cat.categoryid}>{cat.category_name}</option>
+// //           ))}
+// //         </select>
+// //         <input
+// //           type="text"
+// //           placeholder="DPI(可选)"
+// //           value={dpi}
+// //           onChange={(e) => setDpi(e.target.value)}
+// //           className="w-full p-2 border rounded"
+// //         />
+// //         <input
+// //           type="text"
+// //           placeholder="字幕(可选)"
+// //           value={caption}
+// //           onChange={(e) => setCaption(e.target.value)}
+// //           className="w-full p-2 border rounded"
+// //         />
+// //         <button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
+// //           上传
+// //         </button>
+// //       </form>
+
+// //       {showSuccess && (
+// //         <div className="mt-4 p-3 bg-green-100 text-green-800 border border-green-300 rounded">
+// //           上传成功!
+// //         </div>
+// //       )}
+// //     </div>
+// //   );
+// // }
+
+// // export default UploadTorrent;
+// import React, { useState, useEffect } from 'react';;
+// import axios from 'axios';
+
+// function UploadTorrent() {
+//   const [title, setTitle] = useState('');
+//   const [description, setDescription] = useState('');
+//   const [categoryId, setCategoryId] = useState('');
+//   const [dpi, setDpi] = useState('');
+//   const [caption, setCaption] = useState('');
+//   const [file, setFile] = useState(null);
+//   const [categories, setCategories] = useState([]);
+//   const [showSuccess, setShowSuccess] = useState(false);
+
+//   useEffect(() => {
+//     axios.get('http://localhost:8080/categories')
+//       .then(res => setCategories(res.data))
+//       .catch(err => console.error('加载分类失败', err));
+//   }, []);
+
+//   const handleSubmit = async (e) => {
+//     e.preventDefault();
+//     if (!file) {
+//       alert('请选择一个 .torrent 文件');
+//       return;
+//     }
+
+//     if (!categoryId) {
+//       alert('请选择分类');
+//       return;
+//     }
+
+//     const formData = new FormData();
+//     formData.append('file', file);
+//     formData.append('title', title);
+//     formData.append('description', description);
+//     formData.append('categoryId', categoryId);
+//     if (dpi) formData.append('dpi', dpi);
+//     if (caption) formData.append('caption', caption);
+
+//     try {
+//       // 发送上传请求
+//       const response = await axios.post('http://localhost:8080/torrent/upload', formData, {
+//         headers: { 'Content-Type': 'multipart/form-data' },
+//         responseType: 'blob', // 关键:指定响应类型为 blob
+//       });
+
+//       // 创建下载链接
+//       const url = window.URL.createObjectURL(new Blob([response.data]));
+//       const link = document.createElement('a');
+//       link.href = url;
+//       link.setAttribute('download', file.name); // 使用原文件名
+//       document.body.appendChild(link);
+//       link.click();
+//       link.remove();
+
+//       // 显示成功提示
+//       setShowSuccess(true);
+//       setTitle('');
+//       setDescription('');
+//       setCategoryId('');
+//       setDpi('');
+//       setCaption('');
+//       setFile(null);
+//     } catch (err) {
+//       console.error('上传失败', err.response?.data || err.message);
+//       alert(err.response?.data || '上传失败,请检查后端是否启动');
+//     }
+//   };
+
+//   return (
+//     <div className="max-w-xl mx-auto mt-10 p-6 bg-white shadow rounded">
+//       <h2 className="text-2xl font-bold mb-4">上传种子</h2>
+//       <form onSubmit={handleSubmit} className="space-y-4">
+//         <input type="file" accept=".torrent" onChange={(e) => setFile(e.target.files[0])} />
+//         <input
+//           type="text"
+//           placeholder="标题"
+//           value={title}
+//           onChange={(e) => setTitle(e.target.value)}
+//           className="w-full p-2 border rounded"
+//           required
+//         />
+//         <textarea
+//           placeholder="描述"
+//           value={description}
+//           onChange={(e) => setDescription(e.target.value)}
+//           className="w-full p-2 border rounded"
+//         />
+//         <select
+//           value={categoryId}
+//           onChange={(e) => setCategoryId(e.target.value)}
+//           className="w-full p-2 border rounded"
+//           required
+//         >
+//           <option value="">请选择分类</option>
+//           {categories.map(cat => (
+//             <option key={cat.categoryid} value={cat.categoryid}>{cat.category_name}</option>
+//           ))}
+//         </select>
+//         <input
+//           type="text"
+//           placeholder="DPI(可选)"
+//           value={dpi}
+//           onChange={(e) => setDpi(e.target.value)}
+//           className="w-full p-2 border rounded"
+//         />
+//         <input
+//           type="text"
+//           placeholder="字幕/说明(可选)"
+//           value={caption}
+//           onChange={(e) => setCaption(e.target.value)}
+//           className="w-full p-2 border rounded"
+//         />
+//         <button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
+//           上传
+//         </button>
+//       </form>
+
+//       {showSuccess && (
+//         <div className="mt-4 p-3 bg-green-100 text-green-800 border border-green-300 rounded">
+//           上传成功!
+//         </div>
+//       )}
+//     </div>
+//   );
+// }
+
+// export default UploadTorrent;
+import React, { useState, useEffect } from 'react';
+import axios from 'axios';
+
+function UploadTorrent() {
+  const [title, setTitle] = useState('');
+  const [description, setDescription] = useState('');
+  const [categoryId, setCategoryId] = useState('');
+  const [file, setFile] = useState(null);
+  const [categories, setCategories] = useState([]);
+  const [showSuccess, setShowSuccess] = useState(false);
+  
+  // 通用参数
+  const [dpi, setDpi] = useState('');
+  const [caption, setCaption] = useState('');
+  const [region, setRegion] = useState('');
+  const [year, setYear] = useState('');
+  const [genre, setGenre] = useState('');
+  const [format, setFormat] = useState('');
+  const [resolution, setResolution] = useState('');
+  
+  // 特殊参数
+  const [codecFormat, setCodecFormat] = useState('');
+  const [platform, setPlatform] = useState('');
+  const [language, setLanguage] = useState('');
+  const [eventType, setEventType] = useState('');
+  const [source, setSource] = useState('');
+  const [style, setStyle] = useState('');
+  const [dataType, setdataType] = useState('');
+  const [isMainland, setIsMainland] = useState(false);
+
+  // 根据分类显示不同的表单字段
+  const [showMovieFields, setShowMovieFields] = useState(false);
+  const [showMusicFields, setShowMusicFields] = useState(false);
+  const [showGameFields, setShowGameFields] = useState(false);
+  const [showTvFields, setShowTvFields] = useState(false);
+  const [showAnimeFields, setShowAnimeFields] = useState(false);
+  const [showlearningFields, setShowlearningFields] = useState(false);
+  const [showsoftwareFields, setShowsoftwareFields] = useState(false);
+  const [showvarietyFields, setShowvarietyFields] = useState(false);
+  const [showsportsFields, setShowsportsFields] = useState(false);
+  const [showdocFields, setShowdocFields] = useState(false);
+  const [showotherFields, setShowotherFields] = useState(false);
+  // 其他分类字段...
+  // 编码格式选项
+  const codecFormats = [
+    { value: 'H.264', label: 'H.264' },
+    { value: 'H.265', label: 'H.265' },
+    { value: 'AV1', label: 'AV1' },
+    { value: 'VP9', label: 'VP9' },
+    { value: 'VC1', label: 'VC1' },
+    { value: 'X264', label: 'X264' },
+  ];
+  const regions = [
+    { value: '大陆', label: '大陆' },
+    { value: '港台', label: '港台' },
+    { value: '欧美', label: '欧美' },
+    { value: '日韩', label: '日韩' },
+    { value: '其他', label: '其他' },
+  ];
+  const genres = [
+    { value: '动作', label: '动作' },
+    { value: '喜剧', label: '喜剧' },
+    { value: '爱情', label: '爱情' },
+    { value: '科幻', label: '科幻' },
+    { value: '恐怖', label: '恐怖' },
+    { value: '动作', label: '动作' },
+    { value: '冒险', label: '冒险' },
+    { value: '历史', label: '历史' },
+    { value: '悬疑', label: '悬疑' },
+    { value: '其他', label: '其他' },
+  ];
+  const resolutions = [
+    { value: '720p', label: '720p' },
+    { value: '1080p', label: '1080p' },
+    { value: '2K', label: '2K' },
+    { value: '4K', label: '4K' },
+    { value: '8K', label: '8K' },
+    { value: '其他', label: '其他' },
+  ];
+
+
+  const eventTypes = [
+    { value: '足球', label: '足球' },
+    { value: '篮球', label: '篮球' },
+    { value: '网球', label: '网球' },
+    { value: '乒乓球', label: '乒乓球' },
+    { value: '羽毛球', label: '羽毛球' },
+  ]
+  const styles = [
+    { value: '大陆综艺', label: '大陆综艺' },
+    { value: '日韩综艺', label: '日韩综艺' },
+    { value: '欧美综艺', label: '欧美综艺' },
+    { value: '其他', label: '其他' },
+  ]
+  const platforms = [
+    { value: 'PC', label: 'PC' },
+    { value: 'PS5', label: 'PS5' },
+    { value: 'Xbox', label: 'Xbox' },
+    { value: 'Switch', label: 'Switch' },
+    { value: '手机', label: '手机' },
+    { value: '其他', label: '其他' },
+  ]
+  const gamegenres = [
+    { value: '角色扮演', label: '角色扮演' },
+    { value: '射击', label: '射击' },
+    { value: '冒险', label: '冒险' },
+    { value: '策略', label: '策略' },
+    { value: '体育', label: '体育' },
+    { value: '桌面游戏', label: '桌面游戏'},
+    { value: '其他', label: '其他' },
+  ]
+  const dataTypes = [
+    { value: '压缩包', label: '压缩包' },
+    { value: '补丁', label: '补丁' },
+    { value: '安装包', label: '安装包' },
+    { value: 'nds', label: 'nds' },
+    { value: '其他', label: '其他' },
+  ]
+  const languages = [
+    { value: '中文', label: '中文' },
+    { value: '英文', label: '英文' },
+    { value: '日文', label: '日文' },
+    { value: '其他', label: '其他' },
+  ]
+  const musicgenres = [
+    { value: '专辑', label: '专辑' },
+    { value: '单曲', label: '单曲' },
+    { value: 'EP', label: 'EP' },
+    { value: '现场', label: '现场' },
+    { value: '其他', label: '其他' },
+  ]
+  const musicstyles = [
+    { value: '流行', label: '流行' },
+    { value: '摇滚', label: '摇滚' },
+    { value: '电子', label: '电子' },
+    { value: '古典', label: '古典' },
+    { value: '爵士', label: '爵士' },
+    { value: '民谣', label: '民谣' },
+    { value: '说唱', label: '说唱' },
+    { value: '其他', label: '其他' },
+  ]
+  const musicformats = [
+    { value: 'MP3', label: 'MP3' },
+    { value: 'FLAC', label: 'FLAC' },
+    { value: 'WAV', label: 'WAV' },
+    { value: 'AAC', label: 'AAC' },
+    { value: 'OGG', label: 'OGG' },
+    { value: '其他', label: '其他' },
+  ]
+  const anigenres = [
+    { value: '新番连载', label: '新番连载' },
+    { value: '剧场版', label: '剧场版' },
+    { value: 'OVA', label: 'OVA' },
+    { value: '完结动漫', label: '完结动漫' },
+    { value: '其他', label: '其他' },
+  ]
+  const animeformats = [
+    { value: 'ZIP', label: 'ZIP' },
+    { value: 'RAR', label: 'RAR' },
+    { value: '7Z', label: '7Z' },
+    { value: 'MKV', label: 'MKV' },
+    { value: 'MP4', label: 'MP4' },
+    { value: '其他', label: '其他' },
+  ]
+  const varietygenres = [
+    { value: '真人秀', label: '真人秀' },
+    { value: '选秀', label: '选秀' },
+    { value: '访谈', label: '访谈' },
+    { value: '游戏', label: '游戏' },
+    { value: '音乐', label: '音乐' },
+    { value: '其他', label: '其他' },
+  ]
+  const sportsgenres = [
+    { value: '足球', label: '足球' },
+    { value: '篮球', label: '篮球' },
+    { value: '网球', label: '网球' },
+    { value: '乒乓球', label: '乒乓球' },
+    { value: '羽毛球', label: '羽毛球' },
+    { value: '其他', label: '其他' },
+  ]
+  const softwaregenres = [
+    { value: '系统软件', label: '系统软件' },
+    { value: '应用软件', label: '应用软件' },
+    { value: '游戏软件', label: '游戏软件' },
+    { value: '驱动程序', label: '驱动程序' },
+    { value: '办公软件', label: '办公软件' },
+    { value: '其他', label: '其他' },
+  ]
+  const softwareplatforms = [
+    { value: 'Windows', label: 'Windows' },
+    { value: 'Mac', label: 'Mac' },
+    { value: 'Linux', label: 'Linux' },
+    { value: 'Android', label: 'Android' },
+    { value: 'iOS', label: 'iOS' },
+    { value: '其他', label: '其他' },
+  ]
+  const softwareformats = [
+    { value: 'EXE', label: 'EXE' }, 
+    { value: 'DMG', label: 'DMG' },
+    { value: '光盘镜像', label: '光盘镜像' },
+    { value: 'APK', label: 'APK' },
+    { value: 'IPA', label: 'IPA' },
+    { value: '其他', label: '其他' },
+  ]
+  const learninggenres = [
+    { value: '计算机', label: '计算机' },
+    { value: '软件', label: '软件' },
+    { value: '人文', label: '人文' },
+    { value: '外语', label: '外语' },
+    { value: '理工类', label: '理工类' },
+    { value: '其他', label: '其他' },
+  ]
+  const learningformats = [
+    { value: 'PDF', label: 'PDF' },
+    { value: 'EPUB', label: 'EPUB' },
+    { value: '视频', label: '视频' },
+    { value: '音频', label: '音频' },
+    { value: 'PPT', label: 'PPT' },
+    { value: '其他', label: '其他' },
+  ]
+  const sourceTypes = [
+    { value: 'CCTV', label: 'CCTV' },
+    { value: '卫视', label: '卫视' },
+    { value: '国家地理', label: '国家地理' },
+    { value: 'BBC', label: 'BBC' },
+    { value: 'Discovery', label: 'Discovery' },
+    { value: '其他', label: '其他' },
+  ]
+  const othergenres = [
+    { value: '电子书', label: '电子书' },
+    { value: '视频', label: '视频' },
+    { value: 'MP3', label: 'MP3' },
+    { value: '图片', label: '图片' },
+    { value: '其他', label: '其他' },
+  ]
+  useEffect(() => {
+    axios.get('http://localhost:8080/categories')
+      .then(res => setCategories(res.data))
+      .catch(err => console.error('加载分类失败', err));
+  }, []);
+
+  // 根据选择的分类显示不同的表单字段
+  useEffect(() => {
+    setShowMovieFields(categoryId === '1');
+    setShowMusicFields(categoryId === '3');
+    setShowGameFields(categoryId === '5');
+    setShowTvFields(categoryId === '2');
+    setShowAnimeFields(categoryId === '4');
+    setShowlearningFields(categoryId === '9');
+    setShowsoftwareFields(categoryId === '8');
+    setShowvarietyFields(categoryId === '6');
+    setShowsportsFields(categoryId === '7');
+    setShowdocFields(categoryId === '10');
+    setShowotherFields(categoryId === '11');
+    // 其他分类...
+  }, [categoryId]);
+
+  const handleSubmit = async (e) => {
+    e.preventDefault();
+    if (!file) {
+      alert('请选择一个 .torrent 文件');
+      return;
+    }
+
+    if (!categoryId) {
+      alert('请选择分类');
+      return;
+    }
+
+    const formData = new FormData();
+    formData.append('file', file);
+    formData.append('title', title);
+    formData.append('description', description);
+    formData.append('categoryId', categoryId);
+    
+    // 通用参数
+    if (dpi) formData.append('dpi', dpi);
+    if (caption) formData.append('caption', caption);
+    if (region) formData.append('region', region);
+    if (year) formData.append('year', year);
+    if (genre) formData.append('genre', genre);
+    if (format) formData.append('format', format);
+    if (resolution) formData.append('resolution', resolution);
+    
+    // 特殊参数
+    if (codecFormat) formData.append('codecFormat', codecFormat);
+    if (platform) formData.append('platform', platform);
+    if (language) formData.append('language', language);
+    if (eventType) formData.append('eventType', eventType);
+    if (source) formData.append('source', source);
+    if (style) formData.append('style', style);
+    if (dataType) formData.append('dataType', dataType);
+    formData.append('isMainland', isMainland.toString());
+
+    try {
+      const response = await axios.post('http://localhost:8080/torrent/upload', formData, {
+        headers: { 'Content-Type': 'multipart/form-data' },
+        responseType: 'blob',
+      });
+
+      // 创建下载链接
+      const url = window.URL.createObjectURL(new Blob([response.data]));
+      const link = document.createElement('a');
+      link.href = url;
+      link.setAttribute('download', file.name);
+      document.body.appendChild(link);
+      link.click();
+      link.remove();
+
+      // 显示成功提示
+      setShowSuccess(true);
+      // 清空表单
+      setTitle('');
+      setDescription('');
+      setCategoryId('');
+      setFile(null);
+      // 清空其他字段...
+    } catch (err) {
+      console.error('上传失败', err.response?.data || err.message);
+      alert(err.response?.data || '上传失败,请检查后端是否启动');
+    }
+  };
+
+  return (
+    <div className="max-w-xl mx-auto mt-10 p-6 bg-white shadow rounded">
+      <h2 className="text-2xl font-bold mb-4">上传种子</h2>
+      <form onSubmit={handleSubmit} className="space-y-4">
+        <div>
+          <label className="block mb-1">种子文件 (.torrent)</label>
+          <input 
+            type="file" 
+            accept=".torrent" 
+            onChange={(e) => setFile(e.target.files[0])} 
+            className="w-full p-2 border rounded"
+            required
+          />
+        </div>
+
+        <div>
+          <label className="block mb-1">标题</label>
+          <input
+            type="text"
+            placeholder="标题"
+            value={title}
+            onChange={(e) => setTitle(e.target.value)}
+            className="w-full p-2 border rounded"
+            required
+          />
+        </div>
+
+        <div>
+          <label className="block mb-1">描述</label>
+          <textarea
+            placeholder="描述"
+            value={description}
+            onChange={(e) => setDescription(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div>
+
+        <div>
+          <label className="block mb-1">分类</label>
+          <select
+            value={categoryId}
+            onChange={(e) => setCategoryId(e.target.value)}
+            className="w-full p-2 border rounded"
+            required
+          >
+            <option value="">请选择分类</option>
+            {categories.map(cat => (
+              <option key={cat.categoryid} value={cat.categoryid}>{cat.category_name}</option>
+            ))}
+          </select>
+        </div>
+
+        {/* <div>
+          <label className="block mb-1">DPI(可选)</label>
+          <input
+            type="text"
+            placeholder="DPI"
+            value={dpi}
+            onChange={(e) => setDpi(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div>
+
+        <div>
+          <label className="block mb-1">字幕/说明(可选)</label>
+          <input
+            type="text"
+            placeholder="字幕/说明"
+            value={caption}
+            onChange={(e) => setCaption(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div> */}
+
+        {/* 电影相关字段 */}
+        {showMovieFields && (
+        <>
+        <div>
+          <label className="block mb-1">字幕/说明</label>
+          <input
+            type="text"
+            placeholder="字幕/说明"
+            value={caption}
+            onChange={(e) => setCaption(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div>
+        <div>
+          <label className="block mb-1">地区</label>
+          <select
+            value={region}
+            onChange={(e) => setRegion(e.target.value)}
+            className="w-full p-2 border rounded"
+          >
+            <option value="">请选择地区</option>
+            {regions.map((regions) => (
+              <option key={regions.value} value={regions.value}>
+                {regions.label}
+              </option>
+            ))}
+          </select>
+        </div>
+          {/* <input
+            type="text"
+            placeholder="region"
+            value={region}
+            onChange={(e) => setRegion(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div> */}
+
+        <div>
+          <label className="block mb-1">年份</label>
+          <input
+            type="text"
+            placeholder="年份"
+            value={year}
+            onChange={(e) => setYear(e.target.value)}
+            className="w-full p-2 border rounded"
+          />
+        </div>
+        <div>
+          <label className="block mb-1">类型</label>
+          {/* <input
+            type="text"
+            placeholder="类型"
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          /> */}
+          <select
+              value={genre}
+              onChange={(e) => setGenre(e.target.value)}
+              className="w-full p-2 border rounded"
+             >
+              <option value="">请选择类型</option>
+                {genres.map((format) => (
+               <option key={format.value} value={format.value}>
+                {format.label}
+               </option>
+                ))}
+               </select>
+        </div>
+            {/* <div>
+              <label className="block mb-1">编码格式</label>
+              <input
+                type="text"
+                placeholder="如 H.264, H.265"
+                value={codecFormat}
+                onChange={(e) => setCodecFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              />
+            </div> */}
+            <div>
+           <label className="block mb-1">编码格式</label>
+            <select
+              value={codecFormat}
+              onChange={(e) => setCodecFormat(e.target.value)}
+              className="w-full p-2 border rounded"
+             >
+              <option value="">请选择编码格式</option>
+                {codecFormats.map((format) => (
+               <option key={format.value} value={format.value}>
+                {format.label}
+               </option>
+                ))}
+               </select>
+            </div>
+            <div>
+              <label className="block mb-1">分辨率</label>
+              <select
+                value={resolution}
+                onChange={(e) => setResolution(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择分辨率</option>
+                {resolutions.map((resolution) => (
+                  <option key={resolution.value} value={resolution.value}>
+                    {resolution.label}
+                  </option>
+                ))}
+              </select>
+{/*               
+              <input
+                type="text"
+                placeholder="如 1080p, 4K"
+                value={resolution}
+                onChange={(e) => setResolution(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/*剧集相关字段 */}
+        {showTvFields && (
+          <>
+            <div>
+              <label className="block mb-1">地区</label>
+              <select
+                value={region}
+                onChange={(e) => setRegion(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择地区</option>
+                {regions.map((regions) => (
+                  <option key={regions.value} value={regions.value}>
+                    {regions.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 中国, 美国"
+                value={region}
+                onChange={(e) => setRegion(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+            <label className="block mb-1">格式</label>
+            <select
+              value={format}
+              onChange={(e) => setFormat(e.target.value)}
+              className="w-full p-2 border rounded"       
+            >
+              <option value="">请选择格式</option>
+              {resolutions.map((format) => (
+                <option key={format.value} value={format.value}>
+                  {format.label}
+                </option>
+              ))}
+            </select>
+{/*         <input
+              type="text"
+              placeholder="如1080P, 4K"
+              value={format}
+              onChange={(e) => setFormat(e.target.value)}
+              className="w-full p-2 border rounded"
+            /> */}
+          </div>
+          <div>
+          <label className="block mb-1">类型</label>
+          <select
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          >
+            <option value="">请选择类型</option>
+            {genres.map((genre) => (
+              <option key={genre.value} value={genre.value}>
+                {genre.label}
+              </option>
+            ))}
+          </select>
+{/*       <input
+            type="text"
+            placeholder="类型"
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          /> */}
+        </div>
+       </>
+        )}
+
+        {/* 游戏相关字段 */}
+        {showGameFields && (
+          <>
+            <div>
+              <label className="block mb-1">平台</label>
+              <select
+                value={platform}
+                onChange={(e) => setPlatform(e.target.value)} 
+                className="w-full p-2 border rounded" 
+              >
+                <option value="">请选择平台</option>
+                {platforms.map((platform) => (
+                  <option key={platform.value} value={platform.value}>
+                    {platform.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+              <input
+                type="text"
+                placeholder="如 PC, PS5"
+                value={platform}
+                onChange={(e) => setPlatform(e.target.value)}
+                className="w-full p-2 border rounded"
+              />*/}
+            </div>
+             <div>
+          <label className="block mb-1">类型</label>
+          <select
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          >
+            <option value="">请选择类型</option>  
+            {gamegenres.map((genre) => (
+              <option key={genre.value} value={genre.value}>
+                {genre.label}
+              </option>
+            ))}
+          </select>
+          {/* <input
+            type="text"
+            placeholder="类型"
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          /> */}
+        </div>
+            <div>
+              <label className="block mb-1">语言</label>
+              <select
+                value={language}
+                onChange={(e) => setLanguage(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择语言</option>
+                {languages.map((language) => (
+                  <option key={language.value} value={language.value}>
+                    {language.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 中文, 英文"
+                value={language}
+                onChange={(e) => setLanguage(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+             <div>
+              <label className="block mb-1">数据类型</label>
+              <select
+                value={dataType}
+                onChange={(e) => setdataType(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择数据类型</option>
+                {dataTypes.map((dataType) => (
+                  <option key={dataType.value} value={dataType.value}>
+                    {dataType.label}
+                  </option>
+                ))}
+              </select>
+{/*             <input
+                type="text"
+                placeholder="如压缩包,补丁"
+                value={dataType}
+                onChange={(e) => setdataType(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+
+        {/* 综艺相关字段 */}
+        {showvarietyFields && (
+          <>
+          <div>
+            <label className="flex items-center">
+              <input
+                type="checkbox"
+                checked={isMainland}
+                onChange={(e) => setIsMainland(e.target.checked)}
+                className="mr-2"
+              />
+              是否大陆综艺
+            </label>
+          </div>
+          <div>
+          <label className="block mb-1">类型</label>
+          <select
+            value={style}
+            onChange={(e) => setStyle(e.target.value)}
+            className="w-full p-2 border rounded"
+          >
+            <option value="">请选择类型</option>
+            {varietygenres.map((style) => (
+              <option key={style.value} value={style.value}>
+                {style.label}
+              </option>
+            ))}
+          </select>
+          {/* <input
+            type="text"
+            placeholder="类型"
+            value={genre}
+            onChange={(e) => setGenre(e.target.value)}
+            className="w-full p-2 border rounded"
+          /> */}
+        </div>
+          <div>
+            <label className="block mb-1">格式</label>
+            <select
+              value={format}
+              onChange={(e) => setFormat(e.target.value)}
+              className="w-full p-2 border rounded"
+            >
+              <option value="">请选择格式</option>
+              {resolutions.map((format) => (
+                <option key={format.value} value={format.value}>
+                  {format.label}
+                </option>
+              ))}
+            </select>
+            {/* <input
+              type="text"
+              placeholder="如1080P, 4K"
+              value={format}
+              onChange={(e) => setFormat(e.target.value)}
+              className="w-full p-2 border rounded"
+            /> */}
+          </div>
+          </>
+        )}
+        {/* 动漫相关字段 */}
+        {showAnimeFields && (
+          <>
+            <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {anigenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如治愈, 热血"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {animeformats.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如1080P, 4K"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">分辨率</label>
+              <select
+                value={resolution}
+                onChange={(e) => setResolution(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择分辨率</option>
+                {resolutions.map((resolution) => (
+                  <option key={resolution.value} value={resolution.value}>
+                    {resolution.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 1080p, 4K"
+                value={resolution}
+                onChange={(e) => setResolution(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/* 学习相关字段 */}
+        {showlearningFields && (
+          <>
+            <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {learninggenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 课程, 讲座"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+           <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {learningformats.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如1080P, 4K"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/* 软件相关字段 */}
+        {showsoftwareFields && (
+          <>
+            <div>
+              <label className="block mb-1">平台</label>
+              <select
+                value={platform}
+                onChange={(e) => setPlatform(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择平台</option>
+                {softwareplatforms.map((platform) => (
+                  <option key={platform.value} value={platform.value}>
+                    {platform.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 Windows, Mac"
+                value={platform}
+                onChange={(e) => setPlatform(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+             <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {softwaregenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 学习,办公"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {softwareformats.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 ZIP, EXE"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/* 体育相关字段 */}
+        {showsportsFields && (
+          <>
+            <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {sportsgenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如 比赛, 训练"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {resolutions.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如1080P, 4K"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">赛事类型</label>
+              <select
+                value={eventType}
+                onChange={(e) => setEventType(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择赛事类型</option>
+                {eventTypes.map((eventType) => (
+                  <option key={eventType.value} value={eventType.value}>
+                    {eventType.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如足球、篮球"
+                value={eventType}
+                onChange={(e) => setEventType(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/* 纪录片相关字段 */}
+        {showdocFields && (
+          <>
+            <div>
+              <label className="block mb-1">年份</label>
+              <input
+                type="text"
+                placeholder="如 1999, 2020"
+                value={year}
+                onChange={(e) => setYear(e.target.value)}
+                className="w-full p-2 border rounded"
+              />
+            </div>
+            <div>
+              <label className="block mb-1">视频源</label>
+              <select
+                value={source}
+                onChange={(e) => setSource(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择视频源</option>
+                {sourceTypes.map((source) => (
+                  <option key={source.value} value={source.value}>
+                    {source.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如BlibliBili, YouTube"
+                value={source}
+                onChange={(e) => setSource(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {resolutions.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如1080P, 4K"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/*音乐相关字段 */}
+        {showMusicFields && (
+          <>
+            <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {musicgenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+{/*               
+              <input
+                type="text"
+                placeholder="如专辑、单曲"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">地区</label>
+              <select
+                value={region}
+                onChange={(e) => setRegion(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择地区</option>
+                {regions.map((regions) => (
+                  <option key={regions.value} value={regions.value}>
+                    {regions.label}
+                  </option>
+                ))}
+              </select>
+{/*           <input
+                type="text"
+                placeholder="如 中国, 美国"
+                value={region}
+                onChange={(e) => setRegion(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">风格</label>
+              <select
+                value={style}
+                onChange={(e) => setStyle(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择风格</option>
+                {musicstyles.map((style) => (
+                  <option key={style.value} value={style.value}>
+                    {style.label}
+                  </option>
+                ))}
+                </select>
+              {/* <input
+                type="text"
+                placeholder="如流行、摇滚"
+                value={style}
+                onChange={(e) => setStyle(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+            <div>
+              <label className="block mb-1">格式</label>
+              <select
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择格式</option>
+                {musicformats.map((format) => (
+                  <option key={format.value} value={format.value}>
+                    {format.label}
+                  </option>
+                ))}
+              </select>
+{/*           <input
+                type="text"
+                placeholder="如MP3, FLAC"
+                value={format}
+                onChange={(e) => setFormat(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+        {/* 其他分类字段 */}
+        {showotherFields && (
+          <>
+            <div>
+              <label className="block mb-1">类型</label>
+              <select
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              >
+                <option value="">请选择类型</option>
+                {othergenres.map((genre) => (
+                  <option key={genre.value} value={genre.value}>
+                    {genre.label}
+                  </option>
+                ))}
+              </select>
+              {/* <input
+                type="text"
+                placeholder="如视频、音频"
+                value={genre}
+                onChange={(e) => setGenre(e.target.value)}
+                className="w-full p-2 border rounded"
+              /> */}
+            </div>
+          </>
+        )}
+
+        {/* 其他分类字段... */}
+        {/* 提交按钮 */}
+
+        <button 
+          type="submit" 
+          className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
+        >
+          上传
+        </button>
+      </form>
+
+      {showSuccess && (
+        <div className="mt-4 p-3 bg-green-100 text-green-800 border border-green-300 rounded">
+          上传成功!
+        </div>
+      )}
+    </div>
+  );
+}
+
+export default UploadTorrent;
\ No newline at end of file