修复种子详情下载

Change-Id: I5673279933d639e1bf425fcaea3eabd447625bfc
diff --git a/src/pages/SeedList/SeedDetail/SeedDetail.jsx b/src/pages/SeedList/SeedDetail/SeedDetail.jsx
index 16c6d01..0cb738c 100644
--- a/src/pages/SeedList/SeedDetail/SeedDetail.jsx
+++ b/src/pages/SeedList/SeedDetail/SeedDetail.jsx
@@ -5,7 +5,6 @@
 import './SeedDetail.css';
 import { useUser } from '../../../context/UserContext';
 
-
 const SeedDetail = () => {
   const params = useParams();
   const seed_id = params.id;
@@ -18,8 +17,6 @@
 
   const { user } = useUser();
 
-
-  // 格式化图片 URL
   const formatImageUrl = (url) => {
     if (!url) return '';
     const filename = url.split('/').pop();
@@ -37,8 +34,6 @@
         const res = await axios.post(`/seeds/info/${seed_id}`);
         if (res.data.code === 0) {
           const seedData = res.data.data;
-
-          // 处理封面图
           let cover = seedData.imageUrl;
           if (!cover && seedData.imgUrl) {
             const imgs = seedData.imgUrl
@@ -76,42 +71,76 @@
     fetchComments();
   }, [seed_id]);
 
- const handleDownload = async (seedId) => {
-        if (!user || !user.userId) {
-            alert('请先登录再下载种子文件');
-            return;
-        }
+  const handleDownload = async (seedId) => {
+    if (!user || !user.userId) {
+      alert('请先登录再下载种子文件');
+      return;
+    }
 
-        try {
-            const response = await axios.get(`/seeds/${seedId}/download`, {
-                params: {
-                    passkey: user.userId,
-                },
-                responseType: 'blob'
-            });
+    try {
+      const response = await axios.get(`/seeds/${seedId}/download`, {
+        params: { passkey: user.userId },
+        responseType: 'blob',
+      });
 
-            const blob = new Blob([response.data], { type: 'application/x-bittorrent' });
-            const downloadUrl = URL.createObjectURL(blob);
-            const a = document.createElement('a');
-            a.href = downloadUrl;
-            a.download = `${seedId}.torrent`;
-            a.click();
-            URL.revokeObjectURL(downloadUrl);
-        } catch (error) {
-            console.error('下载失败:', error);
-            alert('下载失败,请稍后再试。');
-        }
-    };
-
-
-  const handleCollect = () => {
-    alert('已收藏');
+      const blob = new Blob([response.data], { type: 'application/x-bittorrent' });
+      const downloadUrl = URL.createObjectURL(blob);
+      const a = document.createElement('a');
+      a.href = downloadUrl;
+      a.download = `${seedId}.torrent`;
+      a.click();
+      URL.revokeObjectURL(downloadUrl);
+    } catch (error) {
+      console.error('下载失败:', error);
+      alert('下载失败,请稍后再试。');
+    }
   };
 
-  const handleAddComment = () => {
+  const handleCollect = async () => {
+    if (!user || !user.userId) {
+      alert('请先登录再收藏');
+      return;
+    }
+
+    try {
+      const res = await axios.post(`/seeds/${seed.id}/favorite-toggle`, null, {
+        params: { user_id: user.userId },
+      });
+
+      if (res.data.code === 0) {
+        alert('操作成功');
+      } else {
+        alert(res.data.msg || '操作失败');
+      }
+    } catch (err) {
+      console.error('收藏失败:', err);
+      alert('收藏失败,请稍后再试。');
+    }
+  };
+
+  const handleAddComment = async () => {
+    if (!user || !user.userId) {
+      alert('请登录后发表评论');
+      return;
+    }
+
     if (newComment.trim()) {
-      setComments([...comments, { content: newComment, user: '用户' }]);
-      setNewComment('');
+      try {
+        const res = await axios.post(`/seeds/${seed_id}/comments`, {
+          user_id: user.userId,
+          content: newComment,
+        });
+
+        if (res.data.code === 0) {
+          setComments([...comments, { content: newComment, user: user.username || '匿名用户' }]);
+          setNewComment('');
+        } else {
+          alert(res.data.msg || '评论失败');
+        }
+      } catch (err) {
+        console.error('评论提交失败:', err);
+        alert('评论失败,请稍后重试');
+      }
     }
   };
 
@@ -137,20 +166,16 @@
     );
   }
 
-  const tags = seed.tags
-    ? Array.isArray(seed.tags)
-      ? seed.tags
-      : typeof seed.tags === 'string'
-      ? seed.tags.split(',').map((t) => t.trim())
-      : []
+  const tags = Array.isArray(seed.tags)
+    ? seed.tags
+    : typeof seed.tags === 'string'
+    ? seed.tags.split(',').map((t) => t.trim())
     : [];
 
-  const actors = seed.actors
-    ? Array.isArray(seed.actors)
-      ? seed.actors
-      : typeof seed.actors === 'string'
-      ? seed.actors.split(',').map((a) => a.trim())
-      : []
+  const actors = Array.isArray(seed.actors)
+    ? seed.actors
+    : typeof seed.actors === 'string'
+    ? seed.actors.split(',').map((a) => a.trim())
     : [];
 
   return (
@@ -185,20 +210,26 @@
             className="cover-image"
           />
         </div>
+
         <div className="action-buttons">
           <button className="btn" onClick={() => handleDownload(seed.id)}>下载</button>
-          <button className="btn" onClick={handleCollect}>收藏</button>
+          <button className="btn-outline" onClick={handleCollect}>收藏</button>
         </div>
+
         <hr className="divider" />
         <h3>评论区</h3>
         <div className="comments-section">
           <div className="comments-list">
-            {comments.map((comment, index) => (
-              <div key={index} className="comment">
-                <p className="comment-user">{comment.user}</p>
-                <p className="comment-content">{comment.content}</p>
-              </div>
-            ))}
+            {comments.length === 0 ? (
+              <p className="no-comments">暂无评论</p>
+            ) : (
+              comments.map((comment, index) => (
+                <div key={index} className="comment">
+                  <p className="comment-user">{comment.user}</p>
+                  <p className="comment-content">{comment.content}</p>
+                </div>
+              ))
+            )}
           </div>
           <div className="add-comment-form">
             <textarea