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 (