fix-user-collections

Change-Id: I51af59fc5866095a4d8ef248be7a28b27d9f4f64
diff --git a/src/pages/PublishSeed/PublishSeed.jsx b/src/pages/PublishSeed/PublishSeed.jsx
index 09dcc67..e3be08c 100644
--- a/src/pages/PublishSeed/PublishSeed.jsx
+++ b/src/pages/PublishSeed/PublishSeed.jsx
@@ -1,9 +1,8 @@
 import React, { useState } from 'react';
 import axios from 'axios';
-import Header from '../../components/Header'; // 导入 Header 组件
-import './PublishSeed.css'
-
-
+import Header from '../../components/Header';
+import './PublishSeed.css';
+import { useUser } from '../../context/UserContext';
 
 const PublishSeed = () => {
   const [title, setTitle] = useState('');
@@ -15,6 +14,8 @@
   const [message, setMessage] = useState('');
   const [isLoading, setIsLoading] = useState(false);
 
+  const { user } = useUser(); // 从上下文中获取当前登录用户信息
+
   const handleTagsChange = (e) => {
     setTags(e.target.value.split(',').map(tag => tag.trim()));
   };
@@ -28,25 +29,38 @@
     setIsLoading(true);
     setMessage('');
 
+    if (!user || !user.id) {
+      setMessage('请先登录');
+      setIsLoading(false);
+      return;
+    }
+
+    if (!file || !file.name.endsWith('.torrent')) {
+      setMessage('请上传一个 .torrent 文件');
+      setIsLoading(false);
+      return;
+    }
+
     const formData = new FormData();
+    formData.append('file', file); // 文件字段
     formData.append('title', title);
     formData.append('description', description);
-    formData.append('tags', JSON.stringify(tags)); // Tags as JSON array
     formData.append('category', category);
-    formData.append('file', file);
-    formData.append('image_url', imageUrl);
+    formData.append('imageUrl', imageUrl);
+    formData.append('tags', tags.join(',')); // 后端使用字符串或数组自行处理
+    formData.append('uploader', user.id); // 添加上传者 ID(必须字段)
 
     try {
-      const response = await axios.post(`/echo/seeds/upload`, formData, {
+      const response = await axios.post('/seeds/upload', formData, {
         headers: {
           'Content-Type': 'multipart/form-data',
         },
       });
 
-      if (response.data.status === 'success') {
+      if (response.data.code === 0) {
         setMessage('种子上传成功');
       } else {
-        setMessage('上传失败,请稍后再试');
+        setMessage(response.data.msg || '上传失败,请稍后再试');
       }
     } catch (error) {
       console.error(error);
@@ -58,90 +72,94 @@
 
   return (
     <div className="publish-seed-container">
-      <Header /> {/* 在这里插入导航栏 */}
+      <Header />
       <div className="pub-card">
-      {message && <div className="message">{message}</div>}
-      <form onSubmit={handleSubmit} encType="multipart/form-data">
-        <div className="title-tag">
-          <label>标题</label>
-          <input
-            type="text"
-            value={title}
-            onChange={(e) => setTitle(e.target.value)}
-            required
-          />
-        </div>
+        {message && <div className="message">{message}</div>}
+        <form onSubmit={handleSubmit} encType="multipart/form-data">
+          <div className="title-tag">
+            <label>标题</label>
+            <input
+              type="text"
+              value={title}
+              onChange={(e) => setTitle(e.target.value)}
+              required
+            />
+          </div>
 
-        <div className="discription">
-          <label>描述</label>
-          <textarea
-            value={description}
-            onChange={(e) => setDescription(e.target.value)}
-            required
-          />
-        </div>
+          <div className="discription">
+            <label>描述</label>
+            <textarea
+              value={description}
+              onChange={(e) => setDescription(e.target.value)}
+              required
+            />
+          </div>
 
-        <div className="title-tag">
-          <label>标签 (逗号分隔)</label>
-          <input
-            type="text"
-            value={tags.join(', ')}
-            onChange={handleTagsChange}
-            placeholder="例如:科幻, 动作"
-            required
-          />
-        </div>
+          <div className="title-tag">
+            <label>标签 (逗号分隔)</label>
+            <input
+              type="text"
+              value={tags.join(', ')}
+              onChange={handleTagsChange}
+              placeholder="例如:科幻, 动作"
+              required
+            />
+          </div>
 
-        <div className="pub-categoty">
-          <label>分类</label>
-          <select
-            value={category}
-            onChange={(e) => setCategory(e.target.value)}
-            required
-          >
-            <option value="movie">电影</option>
-            <option value="tv">电视剧</option>
-            <option value="music">音乐</option>
-          </select>
-        </div>
+          <div className="pub-categoty">
+            <label>分类</label>
+            <select
+              value={category}
+              onChange={(e) => setCategory(e.target.value)}
+              required
+            >
+              <option value="movie">电影</option>
+              <option value="tv">电视剧</option>
+              <option value="music">音乐</option>
+            </select>
+          </div>
 
-        <div className="seed-file">
-          <label>种子文件</label>
-          <label className="seed-file-label">
+          <div className="seed-file">
+            <label>种子文件</label>
+            <label className="seed-file-label">
               点击选择文件
               <input
                 type="file"
+                accept=".torrent"
                 onChange={handleFileChange}
                 style={{ display: 'none' }}
               />
-          </label>
-        </div>
+            </label>
+            {file && <div style={{ marginTop: '5px' }}>{file.name}</div>}
+          </div>
 
-        <div className="form-group">
-          <label>封面图URL</label>
-          <input
-            type="url"
-            value={imageUrl}
-            onChange={(e) => setImageUrl(e.target.value)}
-            placeholder="例如:http://example.com/images/cover.jpg"
-            required
-            style={{ padding: '1%',
-              width: '100%',
-              borderRadius: '6px',
-              border: '1px solid #e0c4a1',
-              backgroundColor: '#fff5f5',
-              color: '#5F4437',
-              fontSize: '1rem',
-              marginBottom: '2%'}}
-          />
-        </div>
+          <div className="form-group">
+            <label>封面图URL</label>
+            <input
+              type="url"
+              value={imageUrl}
+              onChange={(e) => setImageUrl(e.target.value)}
+              placeholder="例如:http://example.com/images/cover.jpg"
+              required
+              style={{
+                padding: '1%',
+                width: '100%',
+                borderRadius: '6px',
+                border: '1px solid #e0c4a1',
+                backgroundColor: '#fff5f5',
+                color: '#5F4437',
+                fontSize: '1rem',
+                marginBottom: '2%',
+              }}
+            />
+          </div>
 
-        <div className="upload-button">
-          <button type="submit" disabled={isLoading}>
-            {isLoading ? '正在上传...' : '上传种子'}
-          </button>
-        </div>
-      </form>
+          <div className="upload-button">
+            <button type="submit" disabled={isLoading}>
+              {isLoading ? '正在上传...' : '上传种子'}
+            </button>
+          </div>
+        </form>
       </div>
     </div>
   );
diff --git a/src/pages/UserCenter/NewbieTasks.jsx b/src/pages/UserCenter/NewbieTasks.jsx
index fd1e44e..8a7cd9f 100644
--- a/src/pages/UserCenter/NewbieTasks.jsx
+++ b/src/pages/UserCenter/NewbieTasks.jsx
@@ -127,7 +127,7 @@
 
         <div className="common-card right-content">
           <div className="profile-header">
-            <h1>🎯 新手任务</h1>
+            <h1>🎯 新手考核</h1>
           </div>
 
           <div className="profile-details">
diff --git a/src/pages/UserCenter/UserCollect.css b/src/pages/UserCenter/UserCollect.css
index e69de29..47b7ac5 100644
--- a/src/pages/UserCenter/UserCollect.css
+++ b/src/pages/UserCenter/UserCollect.css
@@ -0,0 +1,22 @@
+.user-center {
+  max-width: 100%;
+  padding: 3%;
+  font-family: Arial, sans-serif;
+  display: flex;
+  gap: 10%;
+  background: #333;
+}
+
+.post-item {
+  margin-bottom: 20px;
+}
+
+.post-item h3 {
+  font-size: 1.3em;
+  margin-bottom: 8px;
+}
+
+.post-item p {
+  margin: 4px 0;
+  color: #333;
+}
diff --git a/src/pages/UserCenter/UserCollect.jsx b/src/pages/UserCenter/UserCollect.jsx
index e69de29..59d9c9a 100644
--- a/src/pages/UserCenter/UserCollect.jsx
+++ b/src/pages/UserCenter/UserCollect.jsx
@@ -0,0 +1,82 @@
+import React, { useEffect, useState } from 'react';
+import axios from 'axios';
+import Header from '../../components/Header';
+import UserNav from './UserNav';
+import { useUser } from '../../context/UserContext';
+import { useLocation } from 'wouter'; // ✅ 引入 wouter 的 useLocation
+import './UserCollect.css';
+
+const UserCollect = () => {
+  const { user, loading: userLoading } = useUser();
+  const [collections, setCollections] = useState([]);
+  const [loading, setLoading] = useState(true);
+  const [error, setError] = useState(null);
+  const [, navigate] = useLocation(); // ✅ 获取跳转函数
+
+  useEffect(() => {
+    if (userLoading) return;
+
+    if (!user || !user.userId) {
+      setError('未登录或用户信息获取失败');
+      setLoading(false);
+      return;
+    }
+
+    const fetchCollections = async () => {
+      try {
+        const response = await axios.get(`/echo/forum/posts/${user.userId}/getAllcollections`);
+        setCollections(response.data || []);
+        setError(null);
+      } catch (error) {
+        console.error('获取收藏失败:', error);
+        setError('获取收藏失败,请稍后再试');
+      } finally {
+        setLoading(false);
+      }
+    };
+
+    fetchCollections();
+  }, [user, userLoading]);
+
+  return (
+    <div className="user-profile-container">
+      <Header />
+      <div className="user-center">
+        <div className="user-nav-container">
+          <UserNav />
+        </div>
+
+        <div className="common-card">
+          <div className="right-content">
+            <h2 style={{ marginBottom: '1rem' }}>我的收藏</h2>
+            {userLoading || loading ? (
+              <p>加载中...</p>
+            ) : error ? (
+              <p className="error">{error}</p>
+            ) : collections.length === 0 ? (
+              <p>暂无收藏内容。</p>
+            ) : (
+              collections.map((post) => (
+                <div
+                  key={post.postNo}
+                  className="post-item"
+                  onClick={() => navigate(`/forum/post/${post.postNo}`)} // ✅ 跳转帖子详情页
+                  style={{ cursor: 'pointer' }}
+                >
+                  <h3>{post.title || '无标题'}</h3>
+                  <p>{post.postContent?.slice(0, 100) || '暂无内容'}...</p>
+                  <p style={{ fontSize: '12px', color: '#888' }}>
+                    作者:{post.username || '未知'} | 发布时间未知
+                  </p>
+                  <hr />
+                </div>
+              ))
+            )}
+          </div>
+        </div>
+      </div>
+    </div>
+  );
+};
+
+export default UserCollect;
diff --git a/src/pages/UserCenter/UserNav.jsx b/src/pages/UserCenter/UserNav.jsx
index 11d08f8..cc343b1 100644
--- a/src/pages/UserCenter/UserNav.jsx
+++ b/src/pages/UserCenter/UserNav.jsx
@@ -5,14 +5,14 @@
 const UserNav = () => {
   const location = useLocation();
 
-  // 竖直导航栏的链接项(已添加“新手任务”)
+  // 竖直导航栏的链接项(已添加“新手考核”)
   const navLinks = [
     { to: '/user/profile', label: '个人资料' },
     { to: '/user/dynamics', label: '我的动态' },
     { to: '/user/friends', label: '我的好友' },
     { to: '/user/groups', label: '我的群组' },
     { to: '/user/collections', label: '我的收藏' },
-    { to: '/user/newbie-tasks', label: '新手任务' },
+    { to: '/user/newbie-tasks', label: '新手考核' },
   ];
 
   // 判断路径是否是当前活动页面
@@ -47,7 +47,7 @@
 //     // { key: 'friends', label: '我的好友' },
 //     // { key: 'groups', label: '我的群组' },
 //     // { key: 'collections', label: '我的收藏' },
-//     { key: 'newbieTasks', label: '新手任务' },
+//     { key: 'newbieTasks', label: '新手考核' },
 //   ];
 
 //   return (