修改提示框样式、完成付费片单、推荐跳转
Change-Id: Ie84c53d4e306435144b1f26ceb39cc182e99d57a
diff --git a/src/pages/SeedList/Recommend/PlaylistDetailPage.jsx b/src/pages/SeedList/Recommend/PlaylistDetailPage.jsx
new file mode 100644
index 0000000..07558d6
--- /dev/null
+++ b/src/pages/SeedList/Recommend/PlaylistDetailPage.jsx
@@ -0,0 +1,92 @@
+import React, { useEffect, useState } from 'react';
+import { useRoute } from 'wouter'; // ✅ 修改这里
+import axios from 'axios';
+import Header from '../../../components/Header';
+import './PlaylistDetailPage.css';
+import { useUser } from '../../../context/UserContext';
+import toast from 'react-hot-toast';
+import { confirmAlert } from 'react-confirm-alert';
+import 'react-confirm-alert/src/react-confirm-alert.css';
+
+const PlaylistDetailPage = () => {
+ const [match, params] = useRoute('/playlist/:id'); // ✅ 使用 useRoute
+ const id = params?.id;
+ const { user } = useUser();
+ const userId = user?.userId;
+
+ const [detail, setDetail] = useState(null);
+ const [loading, setLoading] = useState(true);
+ const [error, setError] = useState('');
+
+ const fetchDetail = async () => {
+ if (!id) {
+ setError('无效的片单ID');
+ setLoading(false);
+ return;
+ }
+ if (!userId) {
+ setError('请先登录');
+ setLoading(false);
+ return;
+ }
+
+ try {
+ setLoading(true);
+ setError('');
+ const res = await axios.get(`/playlist/${id}`, {
+ params: { userId }
+ });
+ if (res.data.code === 0) {
+ setDetail(res.data.data);
+ } else {
+ setError(res.data.msg || '加载失败');
+ }
+ } catch (err) {
+ console.error(err);
+ setError('请求失败,请检查网络');
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ useEffect(() => {
+ if (id && userId) fetchDetail(); // ✅ 防止空 ID 反复触发
+ }, [id, userId]);
+
+ if (loading) return <div>加载中...</div>;
+
+ if (error) {
+ return (
+ <div className="error">
+ {error}
+ <button onClick={fetchDetail} className="retry-button">重试</button>
+ </div>
+ );
+ }
+
+return (
+ <div className="playlist-detail">
+ <Header />
+ <h1>{detail.title}</h1>
+ <img
+ src={detail.coverUrl || '/default-cover.jpg'}
+ alt={detail.title}
+ onError={e => { e.target.src = '/default-cover.jpg'; }}
+ className="cover-image"
+ />
+ <p>{detail.description}</p>
+
+ <h3>包含的种子:</h3>
+ {detail.torrentList && detail.torrentList.length > 0 ? (
+ <ul>
+ {detail.torrentList.map(seed => (
+ <li key={seed.id}>{seed.title}</li>
+ ))}
+ </ul>
+ ) : (
+ <p>暂无种子数据</p>
+ )}
+ </div>
+);
+};
+export default PlaylistDetailPage;