推荐种子页面及组件

Change-Id: I5fe331b1c3511ce2f3e1b07475fde5dafa44927b
diff --git a/src/components/RecommendAll.jsx b/src/components/RecommendAll.jsx
new file mode 100644
index 0000000..330c433
--- /dev/null
+++ b/src/components/RecommendAll.jsx
@@ -0,0 +1,83 @@
+import React, { useEffect, useState } from 'react';
+import '../torrentlist.css';
+
+const RecommendAll = () => {
+  const [torrents, setTorrents] = useState([]);
+  const storedUser = localStorage.getItem('user');
+    //let currentUserId = null; // 初始化为 null
+    let currentUserId = null; // 初始化为 null
+
+    if (storedUser) {
+        try {
+            const parsedUser = JSON.parse(storedUser);
+            currentUserId = parsedUser.userid; // 直接赋值
+        } catch (error) {
+            console.error('解析用户数据失败:', error);
+            // 可以在这里处理 JSON 解析错误(如数据损坏)
+        }
+    } else {
+        console.log('用户未登录');
+    }
+
+    // 现在 currentUserId 可以在后续逻辑中使用
+    console.log('当前用户ID:', currentUserId);
+
+
+  useEffect(() => {
+    const fetchAll = async () => {
+   const res = await fetch(`http://localhost:8080/recommend/list?userId=${currentUserId}`);
+    //const res = await fetch('http://localhost:8080/torrent/list');
+      const data = await res.json();
+      setTorrents(data);
+    };
+    fetchAll();
+  }, []);
+
+  const formatFileSize = (bytes) => {
+    if (!bytes) return '0 Bytes';
+    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
+    const i = Math.floor(Math.log(bytes) / Math.log(1024));
+    return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
+  };
+
+  return (
+    <div className="torrents-container">
+      <h2 style={{ fontSize: 24, fontWeight: 'bold', marginBottom: 16 }}>全部推荐种子</h2>
+      <div className="torrents1-grid">
+        {torrents.map(torrent => (
+          <div key={torrent.torrentid} className="torrent-card">
+            <div className="cover">
+              {torrent.coverImagePath ? (
+                <img src={torrent.coverImagePath} alt="封面" className="cover-image" />
+              ) : (
+                <div className="no-cover">无封面</div>
+              )}
+            </div>
+
+            <div className="info">
+              <h3 className="title" title={torrent.filename}>
+                {torrent.torrentTitle || torrent.filename}
+              </h3>
+              <p className="description" title={torrent.description}>
+                {torrent.description || '暂无描述'}
+              </p>
+
+              <div className="details">
+                <span>大小: {formatFileSize(torrent.torrentSize)}</span>
+                <span>上传时间: {new Date(torrent.uploadTime).toLocaleDateString()}</span>
+                <span>下载次数: {torrent.downloadCount}</span>
+              </div>
+
+              <div className="actions">
+                <button className="btn btn-download">下载</button>
+                <a href={`/torrent/${torrent.torrentid}`} className="btn btn-detail">详情</a>
+              </div>
+            </div>
+          </div>
+        ))}
+      </div>
+    </div>
+  );
+};
+
+export default RecommendAll;
diff --git a/src/components/RecommendPreview.jsx b/src/components/RecommendPreview.jsx
new file mode 100644
index 0000000..5eb45d3
--- /dev/null
+++ b/src/components/RecommendPreview.jsx
@@ -0,0 +1,92 @@
+import React, { useEffect, useState } from 'react';
+import { useNavigate } from 'react-router-dom';
+import '../RecommendPreview.css';
+
+const RecommendPreview = () => {
+  
+  const [recommendList, setRecommendList] = useState([]);
+  const navigate = useNavigate();
+
+  const storedUser = localStorage.getItem('user');
+    //let currentUserId = null; // 初始化为 null
+    let currentUserId = null; // 初始化为 null
+
+    if (storedUser) {
+        try {
+            const parsedUser = JSON.parse(storedUser);
+            currentUserId = parsedUser.userid; // 直接赋值
+        } catch (error) {
+            console.error('解析用户数据失败:', error);
+            // 可以在这里处理 JSON 解析错误(如数据损坏)
+        }
+    } else {
+        console.log('用户未登录');
+    }
+
+    // 现在 currentUserId 可以在后续逻辑中使用
+    console.log('当前用户ID:', currentUserId);
+
+  useEffect(() => {
+    const fetchRecommendList = async () => {
+      try {
+        const res = await fetch(`http://localhost:8080/recommend/list?userId=${currentUserId}`);
+        //const res = await fetch('http://localhost:8080/torrent/list');
+        const data = await res.json();
+        console.log('推荐列表数据:', data);
+        setRecommendList(data.slice(0, 8)); // 只展示前8个
+      } catch (err) {
+        console.error('推荐获取失败:', err);
+      }
+    };
+    fetchRecommendList();
+  }, []);
+
+  const formatFileSize = (bytes) => {
+    if (!bytes) return '0 Bytes';
+    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
+    const i = Math.floor(Math.log(bytes) / Math.log(1024));
+    return (bytes / Math.pow(1024, i)).toFixed(2) + ' ' + sizes[i];
+  };
+
+  const formatDate = (dateString) => {
+    const date = new Date(dateString);
+    return date.toLocaleDateString();
+  };
+
+  return (
+    <div className="recommend-horizontal-container">
+      <div className="recommend-header">
+        <h2>为你推荐</h2>
+        <button className="more-btn" onClick={() => navigate('/recommend')}>
+          更多
+        </button>
+      </div>
+
+      <div className="recommend-horizontal-grid">
+        {recommendList.map((torrent) => (
+          <div key={torrent.torrentid} className="horizontal-card">
+            {torrent.coverImagePath ? (
+              <img src={torrent.coverImagePath} alt="封面" className="card-cover" />
+            ) : (
+              <div className="card-no-cover">无封面</div>
+            )}
+            <div className="card-info">
+              <div className="card-title" title={torrent.torrentTitle || torrent.filename}>
+                {torrent.torrentTitle || torrent.filename}
+              </div>
+              <div className="card-description">
+                {torrent.description || '暂无描述'}
+              </div>
+              <div className="card-meta">
+                <span>{formatDate(torrent.uploadTime)}</span>
+                <span>{formatFileSize(torrent.torrentSize)}</span>
+              </div>
+            </div>
+          </div>
+        ))}
+      </div>
+    </div>
+  );
+};
+
+export default RecommendPreview;