blob: 13a6ba5f2b8221c9ea12ca1fda7d79f306ea3e9d [file] [log] [blame]
wht338fc032025-06-09 17:16:22 +08001import React, { useState, useEffect } from "react";
2import HomeIcon from "@mui/icons-material/Home";
956303669a32fc2c2025-06-02 19:45:53 +08003import MovieIcon from "@mui/icons-material/Movie";
TRM-codingfa3ffdf2025-06-09 22:47:42 +08004import TvIcon from "@mui/icons-material/Tv";
956303669a32fc2c2025-06-02 19:45:53 +08005import MusicNoteIcon from "@mui/icons-material/MusicNote";
TRM-codingfa3ffdf2025-06-09 22:47:42 +08006import AnimationIcon from "@mui/icons-material/Animation";
956303669a32fc2c2025-06-02 19:45:53 +08007import SportsEsportsIcon from "@mui/icons-material/SportsEsports";
8import SportsMartialArtsIcon from "@mui/icons-material/SportsMartialArts";
9import PersonIcon from "@mui/icons-material/Person";
10import AccountCircleIcon from "@mui/icons-material/AccountCircle";
wht338fc032025-06-09 17:16:22 +080011import ForumIcon from "@mui/icons-material/Forum";
12import HelpIcon from "@mui/icons-material/Help";
TRM-codingfa3ffdf2025-06-09 22:47:42 +080013import "./SharedStyles.css";
956303669a32fc2c2025-06-02 19:45:53 +080014import { useNavigate } from "react-router-dom";
223011330f9623f2025-06-06 00:22:05 +080015import { API_BASE_URL } from "./config";
956303669a32fc2c2025-06-02 19:45:53 +080016
17const navItems = [
TRM-codingfa3ffdf2025-06-09 22:47:42 +080018 { label: "首页", icon: <HomeIcon className="emerald-nav-icon" />, path: "/home", type: "home" },
19 { label: "电影", icon: <MovieIcon className="emerald-nav-icon" />, path: "/movie", type: "movie" },
20 { label: "剧集", icon: <TvIcon className="emerald-nav-icon" />, path: "/tv", type: "tv" },
21 { label: "音乐", icon: <MusicNoteIcon className="emerald-nav-icon" />, path: "/music", type: "music" },
22 { label: "动漫", icon: <AnimationIcon className="emerald-nav-icon" />, path: "/anime", type: "anime" },
23 { label: "游戏", icon: <SportsEsportsIcon className="emerald-nav-icon" />, path: "/game", type: "game" },
24 { label: "体育", icon: <SportsMartialArtsIcon className="emerald-nav-icon" />, path: "/sport", type: "sport" },
25 { label: "资料", icon: <PersonIcon className="emerald-nav-icon" />, path: "/info", type: "info" },
26 { label: "论坛", icon: <ForumIcon className="emerald-nav-icon" />, path: "/forum", type: "forum" },
27 { label: "发布", icon: <AccountCircleIcon className="emerald-nav-icon" />, path: "/publish", type: "publish" },
28 { label: "求种", icon: <HelpIcon className="emerald-nav-icon" />, path: "/begseed", type: "help" },
956303669a32fc2c2025-06-02 19:45:53 +080029];
30
TRM-codingfa3ffdf2025-06-09 22:47:42 +080031// 音乐地区标签
956303669a32fc2c2025-06-02 19:45:53 +080032const areaTabs = [
TRM-codingfa3ffdf2025-06-09 22:47:42 +080033 { label: "华语音乐", value: "chinese" },
34 { label: "港台音乐", value: "hk_tw" },
35 { label: "欧美音乐", value: "western" },
36 { label: "日韩音乐", value: "jp_kr" },
37 { label: "其他音乐", value: "others" }
956303669a32fc2c2025-06-02 19:45:53 +080038];
39
40export default function MusicPage() {
41 const navigate = useNavigate();
TRM-codingfa3ffdf2025-06-09 22:47:42 +080042 const [searchText, setSearchText] = React.useState('');
wht338fc032025-06-09 17:16:22 +080043 const [userInfo, setUserInfo] = useState({ avatar_url: '', username: '' });
44 const [userPT, setUserPT] = useState({ magic: 0, ratio: 0, upload: 0, download: 0 });
TRM-codingfa3ffdf2025-06-09 22:47:42 +080045 const [activeTab, setActiveTab] = React.useState(0);
46 const [musicList, setMusicList] = React.useState([]);
wht338fc032025-06-09 17:16:22 +080047
48 useEffect(() => {
49 const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
50 const userId = match ? match[2] : null;
51 if (!userId) return;
52 fetch(`${API_BASE_URL}/api/get-userpt?userid=${encodeURIComponent(userId)}`)
53 .then(res => res.json())
54 .then(data => {
55 setUserInfo({ avatar_url: data.user.avatar_url, username: data.user.username });
56 setUserPT({
57 magic: data.magic_value || data.magic || 0,
58 ratio: data.share_ratio || data.share || 0,
59 upload: data.upload_amount || data.upload || 0,
60 download: data.download_amount || data.download || 0,
61 });
62 })
63 .catch(err => console.error('Fetching user profile failed', err));
64 }, []);
956303669a32fc2c2025-06-02 19:45:53 +080065
TRM-codingfa3ffdf2025-06-09 22:47:42 +080066 React.useEffect(() => {
67 // 根据选中的标签获取音乐列表
rhjc6a4ee02025-06-06 00:45:18 +080068 const area = areaTabs[activeTab].label;
223011330f9623f2025-06-06 00:22:05 +080069 fetch(`${API_BASE_URL}/api/get-seed-list-by-tag?tag=${encodeURIComponent(area)}`)
rhjc6a4ee02025-06-06 00:45:18 +080070 .then(res => res.json())
71 .then(data => setMusicList(data))
72 .catch(() => setMusicList([]));
73 }, [activeTab]);
74
wht338fc032025-06-09 17:16:22 +080075 // 搜索按钮处理
76 const handleSearch = () => {
77 const area = areaTabs[activeTab].label;
78 fetch(`${API_BASE_URL}/api/search-seeds?tag=${encodeURIComponent(area)}&keyword=${encodeURIComponent(searchText)}`)
79 .then(res => res.json())
80 .then(data => {
TRM-codingfa3ffdf2025-06-09 22:47:42 +080081 console.log('搜索返回数据:', data);
wht338fc032025-06-09 17:16:22 +080082 setMusicList(data);
83 })
84 .catch(() => setMusicList([]));
85 };
86
TRM-codingfa3ffdf2025-06-09 22:47:42 +080087 const musicTypesList = [
88 ["华语流行", "华语摇滚", "华语民谣", "华语其他"], // 华语音乐
89 ["港台流行", "港台摇滚", "港台怀旧", "港台其他"], // 港台音乐
90 ["欧美流行", "欧美摇滚", "欧美电子", "欧美其他"], // 欧美音乐
91 ["日韩流行", "日韩摇滚", "日韩其他"], // 日韩音乐
92 ["古典音乐", "世界音乐", "其他类型"] // 其他音乐
93 ];
94 const musicTypes = musicTypesList[activeTab] || [];
956303669a32fc2c2025-06-02 19:45:53 +080095 return (
TRM-codingfa3ffdf2025-06-09 22:47:42 +080096 <div className="emerald-home-container">
97 {/* 流星雨背景效果 */}
98 <div className="meteor-shower">
99 <div className="meteor">💫</div>
100 <div className="meteor">⭐</div>
101 <div className="meteor">✨</div>
102 <div className="meteor">🌟</div>
103 <div className="meteor">💫</div>
104 <div className="meteor">⭐</div>
105 <div className="meteor">✨</div>
106 <div className="meteor">🌟</div>
107 <div className="meteor">💫</div>
108 <div className="meteor">⭐</div>
956303669a32fc2c2025-06-02 19:45:53 +0800109 </div>
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800110
111 {/* 浮动园林装饰元素 */}
112 <div className="floating-garden-elements">
113 <div className="garden-element">🌿</div>
114 <div className="garden-element">🦋</div>
115 <div className="garden-element">🌺</div>
116 <div className="garden-element">🌸</div>
956303669a32fc2c2025-06-02 19:45:53 +0800117 </div>
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800118
119 <div className="emerald-content">
120 {/* NeuraFlux用户栏 */}
121 <div className="emerald-user-bar">
122 <div className="emerald-user-avatar" onClick={() => navigate('/user')}>
123 {userInfo.avatar_url ? (
124 <img src={userInfo.avatar_url} alt="用户头像" style={{ width: 38, height: 38, borderRadius: '50%', objectFit: 'cover' }} />
rhjc6a4ee02025-06-06 00:45:18 +0800125 ) : (
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800126 <AccountCircleIcon style={{ fontSize: 38, color: 'white' }} />
rhjc6a4ee02025-06-06 00:45:18 +0800127 )}
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800128 </div>
129 <div className="emerald-brand-section">
130 <div className="emerald-brand-icon">⚡</div>
131 <div className="emerald-user-label">NeuraFlux</div>
132 </div>
133 <div className="emerald-user-stats">
134 <span className="emerald-stat-item">
135 魔力值: <span className="emerald-stat-value">{userPT.magic}</span>
136 </span>
137 <span className="emerald-stat-item">
138 分享率: <span className="emerald-stat-value">{userPT.ratio}</span>
139 </span>
140 <span className="emerald-stat-item">
141 上传: <span className="emerald-stat-value">{userPT.upload}GB</span>
142 </span>
143 <span className="emerald-stat-item">
144 下载: <span className="emerald-stat-value">{userPT.download}GB</span>
145 </span>
146 </div>
147 </div>
148
149 {/* NeuraFlux导航栏 */}
150 <nav className="emerald-nav-bar">
151 {navItems.map((item) => (
152 <div
153 key={item.label}
154 className={`emerald-nav-item ${item.label === "音乐" ? "active" : ""}`}
155 data-type={item.type}
156 onClick={() => navigate(item.path)}
157 >
158 {item.icon}
159 <span className="emerald-nav-label">{item.label}</span>
160 </div>
161 ))}
162 </nav>
163
164 {/* 音乐内容区域 */}
165 <div className="emerald-content-section">
166 <h1 className="emerald-page-title">🎵 音乐资源</h1>
167 <p style={{ textAlign: 'center', color: '#2d5016', fontSize: '18px', marginBottom: '30px' }}>
168 欢迎来到NeuraFlux音乐频道,这里有最新最热门的音乐资源
169 </p>
170
171 {/* 搜索栏 */}
172 <div style={{
173 display: 'flex',
174 justifyContent: 'center',
175 marginBottom: '30px',
176 gap: '15px'
177 }}>
178 <input
179 type="text"
180 placeholder="搜索音乐资源..."
181 value={searchText}
182 onChange={(e) => setSearchText(e.target.value)}
183 style={{
184 padding: '12px 20px',
185 borderRadius: '20px',
186 border: '2px solid rgba(144, 238, 144, 0.3)',
187 background: 'rgba(240, 255, 240, 0.5)',
188 fontSize: '16px',
189 width: '300px',
190 fontFamily: 'Lora, serif'
191 }}
192 />
193 <button
194 onClick={handleSearch}
195 style={{
196 padding: '12px 24px',
197 borderRadius: '20px',
198 border: 'none',
199 background: 'linear-gradient(135deg, #2d5016 0%, #90ee90 100%)',
200 color: 'white',
201 fontSize: '16px',
202 cursor: 'pointer',
203 fontFamily: 'Lora, serif'
204 }}
205 >
206 搜索
207 </button>
208 </div>
209
210 {/* 地区分类标签 */}
211 <div style={{
212 display: 'flex',
213 justifyContent: 'center',
214 marginBottom: '30px',
215 gap: '15px',
216 flexWrap: 'wrap'
217 }}>
218 {areaTabs.map((tab, index) => (
219 <button
220 key={tab.value}
221 onClick={() => setActiveTab(index)}
222 style={{
223 padding: '10px 20px',
224 borderRadius: '15px',
225 border: '2px solid rgba(144, 238, 144, 0.3)',
226 background: activeTab === index
227 ? 'linear-gradient(135deg, #90ee90 0%, #2d5016 100%)'
228 : 'rgba(240, 255, 240, 0.3)',
229 color: activeTab === index ? 'white' : '#2d5016',
230 fontSize: '14px',
231 cursor: 'pointer',
232 fontFamily: 'Lora, serif',
233 transition: 'all 0.3s ease'
234 }}
235 >
236 {tab.label}
237 </button>
238 ))}
239 </div>
240
241 {/* 音乐列表 */}
242 <div className="emerald-table-section">
243 <table className="emerald-table">
244 <thead>
245 <tr>
246 <th>音乐类型</th>
247 <th>标题</th>
248 <th>发布者</th>
249 <th>大小</th>
250 <th>热度</th>
251 <th>折扣倍率</th>
252 </tr>
253 </thead>
254 <tbody>
255 {musicList.length > 0 ? (
256 musicList.map((item, index) => (
257 <tr key={item.id || index}>
258 <td>{item.seedtag}</td>
259 <td>
260 <a href={`/torrent/${item.seedid}`}>
261 {item.title}
262 </a>
263 </td>
264 <td>{item.username}</td>
265 <td>{item.seedsize}</td>
266 <td>{item.downloadtimes}</td>
267 <td>{item.discount == null ? 1 : item.discount}</td>
268 </tr>
269 ))
270 ) : (
271 musicTypes.map((type, index) => (
272 <tr key={type}>
273 <td>{type}</td>
274 <td>
275 <a href={`/torrent/${type}`}>
276 种子{index + 1}
277 </a>
278 </td>
279 <td>发布者{index + 1}</td>
280 <td>--</td>
281 <td>--</td>
282 <td>1</td>
283 </tr>
284 ))
285 )}
286 </tbody>
287 </table>
288 </div>
289 </div>
956303669a32fc2c2025-06-02 19:45:53 +0800290 </div>
956303669a32fc2c2025-06-02 19:45:53 +0800291 </div>
292 );
293}
294
TRM-codingfa3ffdf2025-06-09 22:47:42 +0800295// Pagination组件暂时不使用
956303669a32fc2c2025-06-02 19:45:53 +0800296function Pagination() {
297 const [page, setPage] = React.useState(3);
298 const total = 5;
299 return (
300 <div className="pagination">
301 <button onClick={() => setPage(p => Math.max(1, p - 1))} disabled={page === 1}>上一页</button>
302 <span className="page-num">{page}/{total}</span>
303 <button onClick={() => setPage(p => Math.min(total, p + 1))} disabled={page === total}>下一页</button>
304 <span className="page-info">第 <b>{page}</b> 页</span>
305 </div>
306 );
wht338fc032025-06-09 17:16:22 +0800307}