connect-recommend-api

Change-Id: I301d348cd901445d0f618f50f5fc4d787a2044be
diff --git a/src/pages/PublishSeed/PublishSeed.css b/src/pages/PublishSeed/PublishSeed.css
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pages/PublishSeed/PublishSeed.css
diff --git a/src/pages/PublishSeed/PublishSeed.jsx b/src/pages/PublishSeed/PublishSeed.jsx
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/pages/PublishSeed/PublishSeed.jsx
diff --git a/src/pages/SeedList/Recommend/Recommend.css b/src/pages/SeedList/Recommend/Recommend.css
index 3cc0e90..1eb3541 100644
--- a/src/pages/SeedList/Recommend/Recommend.css
+++ b/src/pages/SeedList/Recommend/Recommend.css
@@ -1,42 +1,38 @@
-.recommend-page {
+.recommend-wrapper {
   padding: 20px;
-  background-color: #f0f0f0;
-}
-
-.recommend-section {
-  margin-bottom: 30px;
-}
-
-.recommend-section h2 {
-  font-size: 24px;
-  margin-bottom: 10px;
-  color: #333;
-}
-
-.recommend-row {
-  display: flex;
-  overflow-x: scroll;
-  gap: 20px;
-}
-
-.recommend-card {
-  width: 150px;
-  text-align: center;
   background-color: #fff;
-  border-radius: 10px;
-  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
-  padding: 10px;
 }
 
-.recommend-image {
+.recommend-section-title {
+  font-size: 20px;
+  font-weight: bold;
+  margin-bottom: 15px;
+}
+
+.recommend-paid-row {
+  display: flex;
+  gap: 20px;
+  flex-wrap: nowrap;
+  overflow-x: auto;
+}
+
+.paid-card {
+  width: 200px;
+  flex-shrink: 0;
+  border: 1px solid #eee;
+  border-radius: 8px;
+  overflow: hidden;
+  background-color: #f9f9f9;
+  text-align: center;
+}
+
+.paid-cover {
   width: 100%;
-  height: 150px;
+  height: 120px;
   object-fit: cover;
-  border-radius: 5px;
 }
 
-.recommend-title {
-  margin-top: 10px;
+.paid-title {
   font-size: 16px;
-  color: #333;
+  padding: 10px;
 }
diff --git a/src/pages/SeedList/Recommend/Recommend.jsx b/src/pages/SeedList/Recommend/Recommend.jsx
index c33d153..97e702b 100644
--- a/src/pages/SeedList/Recommend/Recommend.jsx
+++ b/src/pages/SeedList/Recommend/Recommend.jsx
@@ -1,87 +1,51 @@
-import React from 'react';
+// export default Recommend;
+import React, { useEffect, useState } from 'react';
 import './Recommend.css';
 
-// 假数据
-const recommendData = {
-  paidList: [
-    { title: '片单 1', image: 'https://via.placeholder.com/150' },
-    { title: '片单 2', image: 'https://via.placeholder.com/150' },
-    { title: '片单 3', image: 'https://via.placeholder.com/150' },
-  ],
-  nowPlaying: [
-    { title: '电影 1', image: 'https://via.placeholder.com/150' },
-    { title: '电影 2', image: 'https://via.placeholder.com/150' },
-    { title: '电影 3', image: 'https://via.placeholder.com/150' },
-    { title: '电影 4', image: 'https://via.placeholder.com/150' },
-    { title: '电影 5', image: 'https://via.placeholder.com/150' },
-    { title: '电影 6', image: 'https://via.placeholder.com/150' },
-    { title: '电影 7', image: 'https://via.placeholder.com/150' },
-    { title: '电影 8', image: 'https://via.placeholder.com/150' },
-  ],
-  movieRecommendations: [
-    { title: '电影 1', image: 'https://via.placeholder.com/150' },
-    { title: '电影 2', image: 'https://via.placeholder.com/150' },
-    { title: '电影 3', image: 'https://via.placeholder.com/150' },
-    { title: '电影 4', image: 'https://via.placeholder.com/150' },
-  ],
-  tvRecommendations: [
-    { title: '电视剧 1', image: 'https://via.placeholder.com/150' },
-    { title: '电视剧 2', image: 'https://via.placeholder.com/150' },
-    { title: '电视剧 3', image: 'https://via.placeholder.com/150' },
-    { title: '电视剧 4', image: 'https://via.placeholder.com/150' },
-  ]
-};
-
 const Recommend = () => {
+  const [paidLists, setPaidLists] = useState([]);
+  const [loading, setLoading] = useState(true);
+
+  useEffect(() => {
+    const fetchPaidLists = async () => {
+      try {
+        const API_BASE = process.env.REACT_APP_API_BASE;
+        const response = await fetch(`${API_BASE}/echo/recommendations/paid?user_id=1`);
+        console.log('请求地址:', `${process.env.REACT_APP_API_BASE}/echo/recommendations/paid?user_id=1`);
+
+
+        // const response = await fetch('/echo/recommendations/paid?user_id=1');
+        const data = await response.json();
+        if (data.status === 'success') {
+          setPaidLists(data.paid_recommendations);
+        } else {
+          console.warn('获取付费片单失败');
+        }
+      } catch (error) {
+        console.error('请求出错:', error);
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchPaidLists();
+  }, []);
+
   return (
-    <div className="recommend-page">
-      <div className="recommend-section">
-        <h2>付费片单</h2>
-        <div className="recommend-row">
-          {recommendData.paidList.map((item, index) => (
-            <div key={index} className="recommend-card">
-              <img src={item.image} alt={item.title} className="recommend-image" />
-              <span className="recommend-title">{item.title}</span>
+    <div className="recommend-wrapper">
+      <h2 className="recommend-section-title">付费片单</h2>
+      {loading ? (
+        <p>加载中...</p>
+      ) : (
+        <div className="recommend-paid-row">
+          {paidLists.map((item) => (
+            <div className="paid-card" key={item.group_id}>
+              <img src={item.image_url} alt={item.group_name} className="paid-cover" />
+              <div className="paid-title">{item.group_name}</div>
             </div>
           ))}
         </div>
-      </div>
-
-      <div className="recommend-section">
-        <h2>正在热映</h2>
-        <div className="recommend-row">
-          {recommendData.nowPlaying.map((item, index) => (
-            <div key={index} className="recommend-card">
-              <img src={item.image} alt={item.title} className="recommend-image" />
-              <span className="recommend-title">{item.title}</span>
-            </div>
-          ))}
-        </div>
-      </div>
-
-      <div className="recommend-section">
-        <h2>电影推荐</h2>
-        <div className="recommend-row">
-          {recommendData.movieRecommendations.map((item, index) => (
-            <div key={index} className="recommend-card">
-              <img src={item.image} alt={item.title} className="recommend-image" />
-              <span className="recommend-title">{item.title}</span>
-            </div>
-          ))}
-        </div>
-      </div>
-
-      <div className="recommend-section">
-        <h2>电视剧推荐</h2>
-        <div className="recommend-row">
-          {recommendData.tvRecommendations.map((item, index) => (
-            <div key={index} className="recommend-card">
-              <img src={item.image} alt={item.title} className="recommend-image" />
-              <span className="recommend-title">{item.title}</span>
-            </div>
-          ))}
-        </div>
-      </div>
+      )}
     </div>
   );
 };
diff --git a/src/pages/SeedList/SeedList.jsx b/src/pages/SeedList/SeedList.jsx
index 0e9badf..3519f17 100644
--- a/src/pages/SeedList/SeedList.jsx
+++ b/src/pages/SeedList/SeedList.jsx
@@ -1,68 +1,388 @@
+// import React, { useState, useEffect } from 'react';
+// import { Link } from 'wouter';
+// import axios from 'axios';
+// import logo from '../../assets/logo.png';
+// import Recommend from './Recommend/Recommend';
+// import './SeedList.css';
+
+// const API_BASE = process.env.REACT_APP_API_BASE;
+
+// const SeedList = () => {
+//     const [seeds, setSeeds] = useState([]);
+//     const [filteredSeeds, setFilteredSeeds] = useState([]);
+//     const [loading, setLoading] = useState(true);
+//     const [searchTerm, setSearchTerm] = useState('');
+//     const [sortOption, setSortOption] = useState('最新');
+//     const [activeTab, setActiveTab] = useState('种子列表');
+
+//     const [filters, setFilters] = useState({});
+//     const [selectedFilters, setSelectedFilters] = useState({});
+
+//     const TAGS = ['猜你喜欢', '电影', '电视剧', '动漫', '音乐', '游戏', '综艺', '软件', '体育', '学习', '纪录片', '其他'];
+
+//     const CATEGORY_MAP = {
+//         '电影': 'movie',
+//         '电视剧': 'tv',
+//         '动漫': 'anime',
+//         '音乐': 'music',
+//         '游戏': 'game',
+//         '综艺': 'variety',
+//         '软件': 'software',
+//         '体育': 'sports',
+//         '学习': 'study',
+//         '纪录片': 'documentary',
+//         '其他': 'other'
+//     };
+
+//     const buildQueryParams = () => {
+//         const category = CATEGORY_MAP[activeTab];
+
+//         const params = {
+//             category,
+//             sort_by: sortOption === '最新' ? 'newest'
+//                     : sortOption === '最热' ? 'downloads'
+//                     : undefined,
+//             page: 1,
+//             limit: 20,
+//         };
+
+//         const tags = Object.entries(selectedFilters)
+//             .filter(([_, value]) => value !== '不限')
+//             .map(([_, value]) => value);
+
+//         if (tags.length > 0) params.tags = tags.join(',');
+
+//         return params;
+//     };
+
+//     const fetchSeeds = async () => {
+//         setLoading(true);
+//         try {
+//             const params = buildQueryParams();
+//             const queryString = new URLSearchParams(params).toString();
+//             const response = await fetch(`${API_BASE}/echo/seeds?${queryString}`);
+//             const data = await response.json();
+//             const seeds = data?.seeds || [];
+//             setSeeds(seeds);
+//             setFilteredSeeds(seeds);
+//         } catch (error) {
+//             console.error('获取种子列表失败:', error);
+//         } finally {
+//             setLoading(false);
+//         }
+//     };
+
+//     const fetchFilterOptions = async () => {
+//         if (activeTab === '猜你喜欢') return;
+//         const category = CATEGORY_MAP[activeTab];
+//         try {
+//             const res = await axios.get(`${API_BASE}/echo/seed-filters?category=${category}`);
+//             setFilters(res.data || {});
+//             const defaultSelections = {};
+//             for (const key in res.data) {
+//                 defaultSelections[key] = '不限';
+//             }
+//             setSelectedFilters(defaultSelections);
+//         } catch (err) {
+//             console.error('获取筛选项失败:', err);
+//             setFilters({});
+//             setSelectedFilters({});
+//         }
+//     };
+
+//     useEffect(() => {
+//         if (activeTab !== '猜你喜欢') {
+//             fetchFilterOptions();
+//         }
+//     }, [activeTab]);
+
+//     useEffect(() => {
+//         if (activeTab !== '猜你喜欢') {
+//             fetchSeeds();
+//         }
+//     }, [activeTab, sortOption, selectedFilters]);
+
+//     const handleDownload = async (seedId) => {
+//         const peer_id = 'echo-' + Math.random().toString(36).substring(2, 10);
+//         const ip = '127.0.0.1';
+//         const port = 6881;
+//         const uploaded = 0;
+//         const downloaded = 0;
+//         const left = 0;
+
+//         try {
+//             const response = await axios.get(`${API_BASE}/echo/seeds/${seedId}/download`, {
+//                 params: {
+//                     peer_id,
+//                     ip,
+//                     port,
+//                     uploaded,
+//                     downloaded,
+//                     left,
+//                 },
+//                 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('下载失败,请稍后再试。');
+//         }
+//     };
+
+//     return (
+//         <div className="main-page">
+//             <header className="header">
+//                 <div className="logo-and-name">
+//                     <img src={logo} alt="网站logo" className="logo" />
+//                     <span className="site-name">Echo</span>
+//                 </div>
+//                 <div className="user-and-message">
+//                     <img src="user-avatar.png" alt="用户头像" className="user-avatar" />
+//                     <span className="message-center">消息</span>
+//                 </div>
+//             </header>
+
+//             <nav className="nav">
+//                 <Link to="/friend-moments" className="nav-item">好友动态</Link>
+//                 <Link to="/forum" className="nav-item">论坛</Link>
+//                 <Link to="/interest-groups" className="nav-item">兴趣小组</Link>
+//                 <Link to="/seed-list" className="nav-item active">种子列表</Link>
+//                 <Link to="/publish-seed" className="nav-item">发布种子</Link>
+//             </nav>
+
+//             <div className="controls">
+//                 <input
+//                     type="text"
+//                     placeholder="搜索种子..."
+//                     value={searchTerm}
+//                     onChange={(e) => setSearchTerm(e.target.value)}
+//                     className="search-input"
+//                 />
+//                 <select value={sortOption} onChange={(e) => setSortOption(e.target.value)} className="sort-select">
+//                     <option value="最新">最新</option>
+//                     <option value="最热">最热</option>
+//                 </select>
+//             </div>
+
+//             <div className="tag-filters">
+//                 {TAGS.map((tag) => (
+//                     <button
+//                         key={tag}
+//                         className={`tag-button ${activeTab === tag ? 'active-tag' : ''}`}
+//                         onClick={() => {
+//                             setActiveTab(tag);
+//                             setFilters({});
+//                             setSelectedFilters({});
+//                         }}
+//                     >
+//                         {tag}
+//                     </button>
+//                 ))}
+//             </div>
+
+//             {activeTab !== '猜你喜欢' && Object.keys(filters).length > 0 && (
+//                 <div className="filter-bar">
+//                     {Object.entries(filters).map(([key, options]) => (
+//                         <div className="filter-group" key={key}>
+//                             <label>{key}:</label>
+//                             <select
+//                                 value={selectedFilters[key]}
+//                                 onChange={(e) =>
+//                                     setSelectedFilters({ ...selectedFilters, [key]: e.target.value })
+//                                 }
+//                             >
+//                                 {options.map((opt) => (
+//                                     <option key={opt} value={opt}>{opt}</option>
+//                                 ))}
+//                             </select>
+//                         </div>
+//                     ))}
+//                 </div>
+//             )}
+
+//             <div className="seed-list-content">
+//                 {activeTab === '猜你喜欢' ? (
+//                     <Recommend />
+//                 ) : loading ? (
+//                     <p>加载中...</p>
+//                 ) : filteredSeeds.length === 0 ? (
+//                     <p>未找到符合条件的种子。</p>
+//                 ) : (
+//                     <div className="seed-cards">
+//                         {filteredSeeds.map((seed, index) => (
+//                             <div key={index} className="seed-card">
+//                                 <div className="seed-card-header">
+//                                     <h3>{seed.title}</h3>
+//                                 </div>
+//                                 <div className="seed-card-body">
+//                                     <p><strong>大小:</strong> {seed.size || '未知'} GB</p>
+//                                     <p><strong>时间:</strong> {seed.upload_time?.split('T')[0] || '未知'}</p>
+//                                     <p><strong>下载数:</strong> {seed.downloads ?? 0}</p>
+//                                 </div>
+//                                 <div className="seed-card-actions">
+//                                     <button className="btn-primary" onClick={() => handleDownload(seed.seed_id)}>下载</button>
+//                                     <Link href={`/seed/${seed.seed_id}`} className="btn-secondary">详情</Link>
+//                                     <button className="btn-outline">收藏</button>
+//                                 </div>
+//                             </div>
+//                         ))}
+//                     </div>
+//                 )}
+//             </div>
+//         </div>
+//     );
+// };
+
+// export default SeedList;
 import React, { useState, useEffect } from 'react';
-import axios from 'axios';
 import { Link } from 'wouter';
+import axios from 'axios';
 import logo from '../../assets/logo.png';
-import Recommend from './Recommend/Recommend'; // 导入Recommend组件
+import Recommend from './Recommend/Recommend';
 import './SeedList.css';
 
+const API_BASE = process.env.REACT_APP_API_BASE;
+
 const SeedList = () => {
     const [seeds, setSeeds] = useState([]);
     const [filteredSeeds, setFilteredSeeds] = useState([]);
     const [loading, setLoading] = useState(true);
     const [searchTerm, setSearchTerm] = useState('');
-    const [selectedTag, setSelectedTag] = useState('全部');
     const [sortOption, setSortOption] = useState('最新');
-    const [activeTab, setActiveTab] = useState('种子列表'); // 用于控制激活的标签
+    const [activeTab, setActiveTab] = useState('种子列表');
+    const [filters, setFilters] = useState({});
+    const [selectedFilters, setSelectedFilters] = useState({});
+    const [tagMode, setTagMode] = useState('all'); // 支持 tag_mode 参数
+    const [errorMsg, setErrorMsg] = useState('');
 
-    const TAGS = ['猜你喜欢', '电影', '电视剧','动漫','音乐', '游戏','综艺', '软件', '体育','学习','纪录片','其他'];
+    const TAGS = ['猜你喜欢', '电影', '电视剧', '动漫', '音乐', '游戏', '综艺', '软件', '体育', '学习', '纪录片', '其他'];
 
-    useEffect(() => {
-        const fetchSeeds = async () => {
-            try {
-                const response = await axios.get('/echo/seeds');
-                setSeeds(response.data);
-                setFilteredSeeds(response.data);
-            } catch (error) {
-                console.error('获取种子列表失败:', error);
-            } finally {
-                setLoading(false);
-            }
+    const CATEGORY_MAP = {
+        '电影': 'movie',
+        '电视剧': 'tv',
+        '动漫': 'anime',
+        '音乐': 'music',
+        '游戏': 'game',
+        '综艺': 'variety',
+        '软件': 'software',
+        '体育': 'sports',
+        '学习': 'education',
+        '纪录片': 'documentary',
+        '其他': 'other'
+    };
+
+    const buildQueryParams = () => {
+        const category = CATEGORY_MAP[activeTab];
+        const params = {
+            category,
+            sort_by: sortOption === '最新' ? 'newest' : sortOption === '最热' ? 'downloads' : undefined,
+            page: 1,
+            limit: 20,
+            include_fields: 'seed_id,title,category,tags,size,upload_time,downloads',
         };
 
-        fetchSeeds();
-    }, []);
+        if (searchTerm.trim()) {
+            params.search = searchTerm.trim();
+        }
+
+        const tags = Object.entries(selectedFilters)
+            .filter(([_, value]) => value !== '不限')
+            .map(([_, value]) => value);
+
+        if (tags.length > 0) {
+            params.tags = tags.join(',');
+            params.tag_mode = tagMode;
+        }
+
+        return params;
+    };
+
+    const fetchSeeds = async () => {
+        setLoading(true);
+        setErrorMsg('');
+        try {
+            const params = buildQueryParams();
+            const queryString = new URLSearchParams(params).toString();
+            const response = await fetch(`${API_BASE}/echo/seeds?${queryString}`);
+            const data = await response.json();
+
+            if (data.status !== 'success') throw new Error(data.message || '获取失败');
+            const seeds = data.seeds || [];
+            setSeeds(seeds);
+            setFilteredSeeds(seeds);
+        } catch (error) {
+            console.error('获取种子列表失败:', error);
+            setErrorMsg(error.message || '获取失败,请稍后再试。');
+            setSeeds([]);
+            setFilteredSeeds([]);
+        } finally {
+            setLoading(false);
+        }
+    };
+
+    const fetchFilterOptions = async () => {
+        if (activeTab === '猜你喜欢') return;
+        const category = CATEGORY_MAP[activeTab];
+        try {
+            const res = await axios.get(`${API_BASE}/echo/seed-filters?category=${category}`);
+            setFilters(res.data || {});
+            const defaultSelections = {};
+            for (const key in res.data) {
+                defaultSelections[key] = '不限';
+            }
+            setSelectedFilters(defaultSelections);
+        } catch (err) {
+            console.error('获取筛选项失败:', err);
+            setFilters({});
+            setSelectedFilters({});
+        }
+    };
 
     useEffect(() => {
-        let filtered = seeds;
-
-        if (searchTerm) {
-            filtered = filtered.filter(seed =>
-                seed.name.toLowerCase().includes(searchTerm.toLowerCase())
-            );
+        if (activeTab !== '猜你喜欢') {
+            fetchFilterOptions();
         }
+    }, [activeTab]);
 
-        if (selectedTag !== '全部') {
-            filtered = filtered.filter(seed =>
-                seed.tags && seed.tags.includes(selectedTag)
-            );
+    useEffect(() => {
+        if (activeTab !== '猜你喜欢') {
+            fetchSeeds();
         }
+    }, [activeTab, sortOption, selectedFilters, tagMode, searchTerm]);
 
-        switch (sortOption) {
-            case '最新':
-                filtered.sort((a, b) => new Date(b.uploadTime) - new Date(a.uploadTime));
-                break;
-            case '最热':
-                filtered.sort((a, b) => (b.downloadCount || 0) - (a.downloadCount || 0));
-                break;
-            case '文件大小':
-                filtered.sort((a, b) => (b.size || 0) - (a.size || 0));
-                break;
-            default:
-                break;
+    const handleDownload = async (seedId) => {
+        const peer_id = 'echo-' + Math.random().toString(36).substring(2, 10);
+        const ip = '127.0.0.1';
+        const port = 6881;
+        const uploaded = 0;
+        const downloaded = 0;
+        const left = 0;
+
+        try {
+            const response = await axios.get(`${API_BASE}/echo/seeds/${seedId}/download`, {
+                params: { peer_id, ip, port, uploaded, downloaded, left },
+                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('下载失败,请稍后再试。');
         }
-
-        setFilteredSeeds([...filtered]);
-    }, [searchTerm, selectedTag, sortOption, seeds]);
+    };
 
     return (
         <div className="main-page">
@@ -85,7 +405,6 @@
                 <Link to="/publish-seed" className="nav-item">发布种子</Link>
             </nav>
 
-            {/* 导航部分:点击不同标签时改变 activeTab */}
             <div className="controls">
                 <input
                     type="text"
@@ -97,7 +416,10 @@
                 <select value={sortOption} onChange={(e) => setSortOption(e.target.value)} className="sort-select">
                     <option value="最新">最新</option>
                     <option value="最热">最热</option>
-                    <option value="文件大小">文件大小</option>
+                </select>
+                <select value={tagMode} onChange={(e) => setTagMode(e.target.value)} className="tag-mode-select">
+                    <option value="any">包含任意标签</option>
+                    <option value="all">包含所有标签</option>
                 </select>
             </div>
 
@@ -105,10 +427,11 @@
                 {TAGS.map((tag) => (
                     <button
                         key={tag}
-                        className={`tag-button ${selectedTag === tag ? 'active-tag' : ''}`}
+                        className={`tag-button ${activeTab === tag ? 'active-tag' : ''}`}
                         onClick={() => {
-                            setSelectedTag(tag);
-                            setActiveTab(tag); // 添加这一行来更新 activeTab 状态
+                            setActiveTab(tag);
+                            setFilters({});
+                            setSelectedFilters({});
                         }}
                     >
                         {tag}
@@ -116,12 +439,33 @@
                 ))}
             </div>
 
-            {/* 显示不同页面,根据activeTab */}
+            {activeTab !== '猜你喜欢' && Object.keys(filters).length > 0 && (
+                <div className="filter-bar">
+                    {Object.entries(filters).map(([key, options]) => (
+                        <div className="filter-group" key={key}>
+                            <label>{key}:</label>
+                            <select
+                                value={selectedFilters[key]}
+                                onChange={(e) =>
+                                    setSelectedFilters({ ...selectedFilters, [key]: e.target.value })
+                                }
+                            >
+                                {options.map((opt) => (
+                                    <option key={opt} value={opt}>{opt}</option>
+                                ))}
+                            </select>
+                        </div>
+                    ))}
+                </div>
+            )}
+
             <div className="seed-list-content">
                 {activeTab === '猜你喜欢' ? (
-                    <Recommend /> // 显示推荐页面
+                    <Recommend />
                 ) : loading ? (
                     <p>加载中...</p>
+                ) : errorMsg ? (
+                    <p className="error-text">{errorMsg}</p>
                 ) : filteredSeeds.length === 0 ? (
                     <p>未找到符合条件的种子。</p>
                 ) : (
@@ -129,17 +473,16 @@
                         {filteredSeeds.map((seed, index) => (
                             <div key={index} className="seed-card">
                                 <div className="seed-card-header">
-                                    <h3>{seed.name}</h3>
+                                    <h3>{seed.title}</h3>
                                 </div>
                                 <div className="seed-card-body">
-                                    <p><strong>大小:</strong> {seed.size || '未知'}</p>
-                                    <p><strong>上传者:</strong> {seed.uploader || '匿名'}</p>
-                                    <p><strong>时间:</strong> {seed.uploadTime || '未知'}</p>
-                                    <p><strong>下载数:</strong> {seed.downloadCount ?? 0}</p>
+                                    <p><strong>大小:</strong> {seed.size || '未知'} GB</p>
+                                    <p><strong>时间:</strong> {seed.upload_time?.split('T')[0] || '未知'}</p>
+                                    <p><strong>下载数:</strong> {seed.downloads ?? 0}</p>
                                 </div>
                                 <div className="seed-card-actions">
-                                    <button className="btn-primary">下载</button>
-                                    <Link href={`/seed/${seed.id}`} className="btn-secondary">详情</Link>
+                                    <button className="btn-primary" onClick={() => handleDownload(seed.seed_id)}>下载</button>
+                                    <Link href={`/seed/${seed.seed_id}`} className="btn-secondary">详情</Link>
                                     <button className="btn-outline">收藏</button>
                                 </div>
                             </div>