blob: be4b76b5408deaeb63d3df9d7f2ceba22108104b [file] [log] [blame]
// import { useState, useEffect } from 'react';
// import { Link } from 'react-router-dom';
// import axios from 'axios';
// function TorrentList() {
// const [torrents, setTorrents] = useState([]);
// const [categories, setCategories] = useState([]);
// const [selectedCategory, setSelectedCategory] = useState('');
// // 获取所有分类
// useEffect(() => {
// axios.get('http://localhost:8080/categories') // 假设这个接口返回所有分类
// .then(res => setCategories(res.data))
// .catch(err => console.error('获取分类失败', err));
// }, []);
// // 获取种子(根据分类筛选)
// useEffect(() => {
// const url = selectedCategory
// ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
// : 'http://localhost:8080/torrent/list';
// axios.get(url)
// .then(res => setTorrents(res.data))
// .catch(err => console.error('获取种子失败', err));
// }, [selectedCategory]);
// console.log(torrents);
// return (
// <div className="p-4">
// <div className="mb-4">
// <label className="mr-2 font-medium">选择分类:</label>
// <select
// value={selectedCategory}
// onChange={e => setSelectedCategory(e.target.value)}
// className="border rounded px-2 py-1"
// >
// <option value="">全部</option>
// {categories.map(cat => (
// <option key={cat.categoryid} value={cat.categoryid}>
// {cat.category_name}
// </option>
// ))}
// </select>
// </div>
// <table className="w-full border-collapse">
// <thead>
// <tr className="bg-gray-200">
// <th className="p-2 border">名称</th>
// <th className="p-2 border">上传者</th>
// <th className="p-2 border">描述</th>
// <th className="p-2 border">上传时间</th>
// <th className="p-2 border">下载次数</th>
// <th className="p-2 border">促销方式</th>
// <th className="p-2 border">操作</th>
// </tr>
// </thead>
// <tbody>
// {torrents.map(t => (
// <tr key={t.torrentid} className="border-t hover:bg-gray-100">
// <td className="p-2 border">{t.filename}</td>
// <td className="p-2 border">{t.uploader_id}</td>
// <td className="p-2 border">{t.description}</td>
// <td className="p-2 border">{new Date(t.uploadTime).toLocaleString()}</td>
// <td className="p-2 border">{t.downloadCount}</td>
// <td className="p-2 border">
// {(() => {
// switch(t.promotionid) {
// case 1: return '上传加倍';
// case 2: return '下载免费';
// case 3: return '下载减半';
// case 0: return '没有促销';
// default: return '没有促销';
// }
// })()}
// </td>
// <td className="p-2 border">
// <a
// href={`http://localhost:8080/torrent/download/${t.torrentid}`}
// className="text-blue-500 hover:underline"
// target="_blank"
// rel="noreferrer"
// >
// 下载
// </a>
// </td>
// <Link
// to={`/torrent/${t.torrentid}`}
// className="text-green-600 hover:underline"
// >
// 查看详情
// </Link>
// </tr>
// ))}
// </tbody>
// </table>
// </div>
// );
// }
// export default TorrentList;
// import { useState, useEffect } from 'react';
// import axios from 'axios';
// function TorrentList() {
// const [torrents, setTorrents] = useState([]);
// const [categories, setCategories] = useState([]);
// const [selectedCategory, setSelectedCategory] = useState('');
// const [filters, setFilters] = useState({});
// const [showSuccess, setShowSuccess] = useState(false);
// const softwaregenres = [
// { value: '系统软件', label: '系统软件' },
// { value: '应用软件', label: '应用软件' },
// { value: '游戏软件', label: '游戏软件' },
// { value: '驱动程序', label: '驱动程序' },
// { value: '办公软件', label: '办公软件' },
// { value: '其他', label: '其他' },
// ]
// const softwareplatforms = [
// { value: 'Windows', label: 'Windows' },
// { value: 'Mac', label: 'Mac' },
// { value: 'Linux', label: 'Linux' },
// { value: 'Android', label: 'Android' },
// { value: 'iOS', label: 'iOS' },
// { value: '其他', label: '其他' },
// ]
// const softwareformats = [
// { value: 'EXE', label: 'EXE' },
// { value: 'DMG', label: 'DMG' },
// { value: '光盘镜像', label: '光盘镜像' },
// { value: 'APK', label: 'APK' },
// { value: 'IPA', label: 'IPA' },
// { value: '其他', label: '其他' },
// ]
// const sourceTypes = [
//     { value: 'CCTV', label: 'CCTV' },
//     { value: '卫视', label: '卫视' },
//     { value: '国家地理', label: '国家地理' },
//     { value: 'BBC', label: 'BBC' },
//     { value: 'Discovery', label: 'Discovery' },
//     { value: '其他', label: '其他' },
//   ]
//   const othergenres = [
//     { value: '电子书', label: '电子书' },
//     { value: '视频', label: '视频' },
//     { value: 'MP3', label: 'MP3' },
//     { value: '图片', label: '图片' },
//     { value: '其他', label: '其他' },
//   ]
// const resolutions = [
// { value: '720p', label: '720p' },
// { value: '1080p', label: '1080p' },
// { value: '2K', label: '2K' },
// { value: '4K', label: '4K' },
// { value: '8K', label: '8K' },
// { value: '其他', label: '其他' },
// ];
// // 每个分类的筛选字段配置
// const categoryFiltersConfig = {
// 1: [ // Movie 电影
// { id: 'resolution', label: '分辨率', type: 'select', options: ['1080p', '4K', '720p', '其他'] },
// { id: 'codecFormat', label: '编码格式', type: 'select', options: ['H.264', 'H.265', 'AV1', 'VC1', 'X264', '其他'] },
// { id: 'region', label: '地区', type: 'select', options: ['大陆', '港台', '欧美', '日韩', '其他'] },
// { id: 'genre', label: '类型', type: 'select', options: ['动作', '喜剧', '爱情', '科幻', '恐怖','动作', '冒险', '历史', '悬疑', '其他'] },
// ],
// 2: [ // TV 剧集
// { id: 'region', label: '地区', type: 'select', options: ['大陆', '港台', '欧美', '日韩', '其他'] },
// { id: 'format', label: '格式', type: 'select', options: resolutions },
// { id: 'genre', label: '类型', type: 'select', options: ['动作', '喜剧', '爱情', '科幻', '恐怖','动作', '冒险', '历史', '悬疑', '其他'] },
// ],
// 3: [ // Music 音乐
// { id: 'genre', label: '类型', type: 'select', options: ['专辑', '单曲', 'EP', '现场', '其他'] },
// { id: 'style', label: '风格', type: 'select', options: ['流行', '摇滚', '电子', '古典', '爵士', '民谣', '说唱', '其他'] },
// ],
// 4: [ // Anime 动漫
// { id: 'genre', label: '类型', type: 'select', options: ['新番连载', '剧场版', 'OVA', '完结动漫', '其他'] },
// { id: 'format', label: '格式', type: 'select', options: ['ZIP', 'RAR', '7Z', 'MKV', 'MP4', '其他'] },
// { id: 'resolution', label: '分辨率', type: 'select', options: ['720P', '1080P', '4K', '其他'] },
// ],
// 5: [ // Game 游戏
// { id: 'platform', label: '平台', type: 'select', options: ['PC', 'PS5', 'Xbox', 'Switch', '手机', '其他'] },
// { id: 'genre', label: '类型', type: 'select', options: ['角色扮演', '射击', '冒险', '策略', '体育', '桌面游戏', '其他'] },
// { id: 'language', label: '语言', type: 'select', options: ['中文', '英文', '日文', '其他'] },
// { id: 'dataType', label: '数据类型', type: 'select', options: ['压缩包', '补丁', '安装包', 'nds', '其他'] },
// ],
// 6: [ // 综艺
// { id: 'isMainland', label: '是否为大陆综艺', type: 'select', options: ['是','不是'] },
// { id: 'format', label: '格式', type: 'select', options: ['1080P', '4K', 'HD', '其他'] },
// { id: 'genre', label: '类型', type: 'select', options: ['真人秀', '选秀','访谈', '音乐', '游戏', '其他'] },
// ],
// 7: [ // 学习
// { id: 'genre', label: '类型', type: 'select', options: ['计算机','软件','人文','外语','理工科','其他'] },
// { id: 'learningformat', label: '格式', type: 'select', options: ['PDF','EPUB','视频','音频','PPT','其他'] },
// ],
// 8: [ // 体育
// { id: 'eventType', label: '赛事类型', type: 'select', options: ['足球', '篮球', '网球', '乒乓球', '羽毛球', '其他'] },
// { id: 'region', label: '地区', type: 'select', options: ['亚洲', '欧洲', '美洲', '其他'] },
// ],
// 9: [ // 其他
// { id: 'otherGenre', label: '类型', type: 'select', options: othergenres },
// ],
// 10: [ // 纪录片
// { id: 'source', label: '来源', type: 'select', options: sourceTypes },
// { id: 'resolution', label: '分辨率', type: 'select', options: resolutions },
// ],
// 11: [ // 软件
// { id: 'softwsreplatform', label: '平台', type: 'select', options: softwareplatforms },
// { id: 'softwareGenre', label: '软件类型', type: 'select', options: softwaregenres },
// { id: 'softwareFormat', label: '软件格式', type: 'select', options: softwareformats },
// ],
// // 其他分类...
// };
// // 获取所有分类
// useEffect(() => {
// axios.get('http://localhost:8080/categories')
// .then(res => setCategories(res.data))
// .catch(err => console.error('加载分类失败', err));
// }, []);
// // 根据选择的分类显示不同的表单字段
// useEffect(() => {
// setFilters({}); // 清空筛选条件
// }, [selectedCategory]);
// const handleFilterChange = (e) => {
// const { name, value } = e.target;
// setFilters(prev => ({ ...prev, [name]: value }));
// };
// const filteredTorrents = (torrents) => {
// return torrents.filter(torrent => {
// if (!selectedCategory) return true; // 如果没有选择分类,显示所有
// if (torrent.categoryid !== parseInt(selectedCategory)) return false;
// // 根据筛选条件过滤
// for (const [key, value] of Object.entries(filters)) {
// if (value && torrent[key] !== value) {
// return false;
// }
// }
// return true;
// });
// };
// // 获取种子(根据分类筛选)
// useEffect(() => {
// let url = selectedCategory
// ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
// : 'http://localhost:8080/torrent/list';
// // 添加筛选条件到 URL
// Object.entries(filters).forEach(([key, value]) => {
// if (value) {
// url += `&${key}=${encodeURIComponent(value)}`;
// }
// });
// axios.get(url)
// .then(res => {
// setTorrents(res.data);
// })
// .catch(err => console.error('获取种子失败', err));
// }, [selectedCategory, filters]);
// const handleDownload = (torrentId) => {
// window.open(`http://localhost:8080/torrent/download/${torrentId}`, '_blank');
// };
// return (
// <div className="p-4">
// {/* 分类选择 */}
// <div className="mb-4">
// <label className="mr-2 font-medium">选择分类:</label>
// <select
// value={selectedCategory}
// onChange={(e) => setSelectedCategory(e.target.value)}
// className="border rounded px-2 py-1 mr-4"
// >
// <option value="">全部</option>
// {categories.map(cat => (
// <option key={cat.categoryid} value={cat.categoryid}>
// {cat.category_name}
// </option>
// ))}
// </select>
// {/* 动态渲染筛选表单 */}
// {selectedCategory && categoryFiltersConfig[selectedCategory] && (
// <div className="flex flex-wrap gap-2">
// {categoryFiltersConfig[selectedCategory].map(filter => {
// if (filter.type === 'select') {
// // 根据筛选字段选择对应的选项列表
// let options;
// switch (filter.id) {
// case 'softwareplatform':
// options = softwareplatforms;
// break;
// case 'softwareGenre':
// options = softwaregenres;
// break;
// case 'softwareFormat':
// options = softwareformats;
// break;
// case 'resolution':
// options = [
// { value: '720p', label: '720p' },
// { value: '1080p', label: '1080p' },
// { value: '2K', label: '2K' },
// { value: '4K', label: '4K' },
// { value: '8K', label: '8K' },
// { value: '其他', label: '其他' },
// ];
// break;
// case 'region':
// if (selectedCategory === '1' || selectedCategory === '2') { // Movie or TV
// options = [
// { value: '大陆', label: '大陆' },
// { value: '港台', label: '港台' },
// { value: '欧美', label: '欧美' },
// { value: '日韩', label: '日韩' },
// { value: '其他', label: '其他' },
// ];
// }
// else if (selectedCategory === '8') { // Sports
// options = [
// { value: '亚洲', label: '亚洲' },
// { value: '欧洲', label: '欧洲' },
// { value: '美洲', label: '美洲' },
// { value: '其他', label: '其他' },
// ];
// }
// break;
// case 'isMainland':
// options = [
// { value: 'true', label: '是' },
// { value: 'false', label: '不是' },
// ];
// break;
// case 'codecFormat':
// options = [
// { value: 'H.264', label: 'H.264' },
// { value: 'H.265', label: 'H.265' },
// { value: 'AV1', label: 'AV1' },
// { value: 'VC1', label: 'VC1' },
// { value: 'X264', label: 'X264' },
// { value: '其他', label: '其他' },
// ];
// break;
// case 'platform':
// options = [
// { value: 'PC', label: 'PC' },
// { value: 'PS5', label: 'PS5' },
// { value: 'Xbox', label: 'Xbox' },
// { value: 'Switch', label: 'Switch' },
// { value: '手机', label: '手机' },
// { value: '其他', label: '其他' },
// ];
// break;
// case 'language':
// options = [
// { value: '中文', label: '中文' },
// { value: '英文', label: '英文' },
// { value: '日文', label: '日文' },
// { value: '其他', label: '其他' },
// ];
// break;
// case'EventType':
// options = [
// { value: '足球', label: '足球' },
// { value: '篮球', label: '篮球' },
// { value: '网球', label: '网球' },
// { value: '乒乓球', label: '乒乓球' },
// { value: '羽毛球', label: '羽毛球' },
// { value: '其他', label: '其他' },
// ];
// break;
// case 'genre':
// if (selectedCategory === '3') { // Music
// options = [
// { value: '专辑', label: '专辑' },
// { value: '单曲', label: '单曲' },
// { value: 'EP', label: 'EP' },
// { value: '现场', label: '现场' },
// { value: '其他', label: '其他' },
// ];
// } else if (selectedCategory === '4') { // Anime
// options = [
// { value: '新番连载', label: '新番连载' },
// { value: '剧场版', label: '剧场版' },
// { value: 'OVA', label: 'OVA' },
// { value: '完结动漫', label: '完结动漫' },
// { value: '其他', label: '其他' },
// ];
// } else if (selectedCategory === '5') { // Game
// options = [
// { value: '角色扮演', label: '角色扮演' },
// { value: '射击', label: '射击' },
// { value: '冒险', label: '冒险' },
// { value: '策略', label: '策略' },
// { value: '体育', label: '体育' },
// { value: '桌面游戏', label: '桌面游戏' },
// { value: '其他', label: '其他' },
// ];
// } else if (selectedCategory === '1') { // TV
// options = [
// { value: '动作', label: '动作' },
//     { value: '喜剧', label: '喜剧' },
//     { value: '爱情', label: '爱情' },
//     { value: '科幻', label: '科幻' },
//     { value: '恐怖', label: '恐怖' },
//     { value: '动作', label: '动作' },
//     { value: '冒险', label: '冒险' },
//   { value: '历史', label: '历史' },
//     { value: '悬疑', label: '悬疑' },
//     { value: '其他', label: '其他' },
// ];
// }
// else if(selectedCategory === '2') {
// options = [
// { value: '动作', label: '动作' },
//     { value: '喜剧', label: '喜剧' },
//     { value: '爱情', label: '爱情' },
//     { value: '科幻', label: '科幻' },
//     { value: '恐怖', label: '恐怖' },
//     { value: '动作', label: '动作' },
//     { value: '冒险', label: '冒险' },
//   { value: '历史', label: '历史' },
//     { value: '悬疑', label: '悬疑' },
//     { value: '其他', label: '其他' },
// ]; // Movie
// }
// else if(selectedCategory === '6') {
// options = [
// { value: '真人秀', label: '真人秀' },
// { value: '选秀', label: '选秀' },
// { value: '访谈', label: '访谈' },
// { value: '音乐', label: '音乐' },
// { value: '游戏', label: '游戏' },
// { value: '其他', label: '其他' },
// ];
// }
// break;
// case 'style':
// if (selectedCategory === '3') { // Music
// options = [
// { value: '流行', label: '流行' },
// { value: '摇滚', label: '摇滚' },
// { value: '电子', label: '电子' },
// { value: '古典', label: '古典' },
// { value: '爵士', label: '爵士' },
// { value: '民谣', label: '民谣' },
// { value: '说唱', label: '说唱' },
// { value: '其他', label: '其他' },
// ];
// } else {
// options = []; // 根据需要定义
// }
// break;
// case 'dataType':
// if (selectedCategory === '5') { // Game
// options = [
// { value: '压缩包', label: '压缩包' },
// { value: '补丁', label: '补丁' },
// { value: '安装包', label: '安装包' },
// { value: 'nds', label: 'nds' },
// { value: '其他', label: '其他' },
// ];
// } else {
// options = []; // 根据需要定义
// }
// break;
// case 'format': if(selectedCategory === '4') {
// options = [
// { value: 'ZIP', label: 'ZIP' },
// { value: 'RAR', label: 'RAR' },
// { value: '7Z', label: '7Z' },
// { value: 'MKV', label: 'MKV' },
// { value: 'MP4', label: 'MP4' },
// { value: '其他', label: '其他' },
// ];
// } else if(selectedCategory === '6') {
// options = [
// { value: '1080P', label: '1080P' },
// { value: '4K', label: '4K' },
// { value: 'HD', label: 'HD' },
// { value: '其他', label: '其他' },
// ];
// } else if(selectedCategory === '2') {
// options = [ { value: '720p', label: '720p' },
// { value: '1080p', label: '1080p' },
// { value: '2K', label: '2K' },
// { value: '4K', label: '4K' },
// { value: '8K', label: '8K' },
// { value: '其他', label: '其他' },
// ];
// } else {
// options = []; // 根据需要定义
// }
// break;
// case 'eventType':
// if (selectedCategory === '7') { // Sports
// options = [
// { value: '足球', label: '足球' },
// { value: '篮球', label: '篮球' },
// { value: '网球', label: '网球' },
// { value: '乒乓球', label: '乒乓球' },
// { value: '羽毛球', label: '羽毛球' },
// { value: '其他', label: '其他' },
// ];
// } else {
// options = []; // 根据需要定义
// }
// break;
// case 'source':
// if (selectedCategory === '10') { // Documentary
// options = [
// { value: 'CCTV', label: 'CCTV' },
// { value: '卫视', label: '卫视' },
// { value: '国家地理', label: '国家地理' },
// { value: 'BBC', label: 'BBC' },
// { value: 'Discovery', label: 'Discovery' },
// { value: '其他', label: '其他' },
// ];
// } else {
// options = []; // 根据需要定义
// }
// break;
// default:
// options = []; // 默认无选项
// }
// return (
// <select
// key={filter.id}
// name={filter.id}
// value={filters[filter.id] || ''}
// onChange={handleFilterChange}
// className="border rounded px-2 py-1"
// >
// <option value="">全部</option>
// {options.map(option => (
// <option key={option.value} value={option.value}>
// {option.label}
// </option>
// ))}
// </select>
// );
// }
// // 其他类型(如输入框)可以类似实现
// return null;
// })}
// </div>
// )}
// </div>
// {/* 筛选按钮 */}
// <button
// onClick={() => {
// // 这里可以根据需要添加额外的筛选逻辑
// // 例如,如果某些筛选需要联动,可以在这里处理
// }}
// className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600 ml-4"
// >
// 应用筛选
// </button>
// {/* 种子列表 */}
// <table className="w-full border-collapse mt-4">
// <thead>
// <tr className="bg-gray-200">
// <th className="p-2 border">名称</th>
// <th className="p-2 border">上传者</th>
// <th className="p-2 border">描述</th>
// <th className="p-2 border">上传时间</th>
// <th className="p-2 border">下载次数</th>
// <th className="p-2 border">促销方式</th>
// <th className="p-2 border">操作</th>
// </tr>
// </thead>
// <tbody>
// {torrents.map(t => (
// <tr key={t.torrentid} className="border-t hover:bg-gray-100">
// <td className="p-2 border">{t.filename}</td>
// <td className="p-2 border">{t.uploader_id}</td>
// <td className="p-2 border">{t.description}</td>
// <td className="p-2 border">{new Date(t.uploadTime).toLocaleString()}</td>
// <td className="p-2 border">{t.downloadCount}</td>
// <td className="p-2 border">
// {(() => {
// switch(t.promotionid) {
// case 1: return '上传加倍';
// case 2: return '下载免费';
// case 3: return '下载减半';
// case 0: return '没有促销';
// default: return '没有促销';
// }
// })()}
// </td>
// <td className="p-2 border">
// <button
// onClick={() => handleDownload(t.torrentid)}
// className="text-blue-500 hover:underline mr-2"
// >
// 下载
// </button>
// <a
// href={`/torrent/${t.torrentid}`}
// className="text-green-600 hover:underline"
// >
// 查看详情
// </a>
// </td>
// </tr>
// ))}
// </tbody>
// </table>
// {/* 成功提示 */}
// {showSuccess && (
// <div className="mt-4 p-3 bg-green-100 text-green-800 border border-green-300 rounded">
// 上传成功!
// </div>
// )}
// </div>
// );
// }
// export default TorrentList;
import { useState, useEffect } from 'react';
import axios from 'axios';
// 常量配置集中管理
const FILTER_OPTIONS = {
// 通用选项
common: {
resolution: [
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
],
region: {
movie: [
{ value: '大陆', label: '大陆' },
{ value: '港台', label: '港台' },
{ value: '欧美', label: '欧美' },
{ value: '日韩', label: '日韩' },
{ value: '其他', label: '其他' },
],
variety: [
{ value: '大陆', label: '大陆' },
{ value: '港台', label: '港台' },
{ value: '欧美', label: '欧美' },
{ value: '日韩', label: '日韩' },
{ value: '其他', label: '其他' },
],
sports: [
{ value: '亚洲', label: '亚洲' },
{ value: '欧洲', label: '欧洲' },
{ value: '美洲', label: '美洲' },
{ value: '其他', label: '其他' },
]
},
genre: {
movie: [
{ value: '动作', label: '动作' },
{ value: '喜剧', label: '喜剧' },
{ value: '爱情', label: '爱情' },
{ value: '科幻', label: '科幻' },
{ value: '恐怖', label: '恐怖' },
{ value: '冒险', label: '冒险' },
{ value: '历史', label: '历史' },
{ value: '悬疑', label: '悬疑' },
{ value: '其他', label: '其他' },
],
music: [
{ value: '流行', label: '流行' },
{ value: '摇滚', label: '摇滚' },
{ value: '电子', label: '电子' },
{ value: '古典', label: '古典' },
{ value: '爵士', label: '爵士' },
{ value: '民谣', label: '民谣' },
{ value: '说唱', label: '说唱' },
{ value: '其他', label: '其他' },
],
anime: [
{ value: '新番连载', label: '新番连载' },
{ value: '剧场版', label: '剧场版' },
{ value: 'OVA', label: 'OVA' },
{ value: '完结动漫', label: '完结动漫' },
{ value: '其他', label: '其他' },
],
game: [
{ value: '角色扮演', label: '角色扮演' },
{ value: '射击', label: '射击' },
{ value: '冒险', label: '冒险' },
{ value: '策略', label: '策略' },
{ value: '体育', label: '体育' },
{ value: '桌面游戏', label: '桌面游戏' },
{ value: '其他', label: '其他' },
],
variety: [
{ value: '真人秀', label: '真人秀' },
{ value: '选秀', label: '选秀' },
{ value: '访谈', label: '访谈' },
{ value: '音乐', label: '音乐' },
{ value: '游戏', label: '游戏' },
{ value: '其他', label: '其他' },
],
learning: [
{ value: '计算机', label: '计算机' },
{ value: '软件', label: '软件' },
{ value: '人文', label: '人文' },
{ value: '外语', label: '外语' },
{ value: '理工科', label: '理工科' },
{ value: '其他', label: '其他' },
],
sports: [
{ value: '足球', label: '足球' },
{ value: '篮球', label: '篮球' },
{ value: '网球', label: '网球' },
{ value: '乒乓球', label: '乒乓球' },
{ value: '羽毛球', label: '羽毛球' },
{ value: '其他', label: '其他' },
],
// 其他类型...
}
},
// 分类特定选项
categories: {
1: { // 电影
name: '电影',
filters: [
{ id: 'resolution', label: '分辨率', type: 'select' },
{ id: 'codec_format', label: '编码格式', type: 'select',
options: [
{ value: 'H.264', label: 'H.264' },
{ value: 'H.265', label: 'H.265' },
{ value: 'AV1', label: 'AV1' },
{ value: 'VC1', label: 'VC1' },
{ value: 'X264', label: 'X264' },
{ value: '其他', label: '其他' },
]
},
{ id: 'region', label: '地区', type: 'select' },
{ id: 'genre', label: '类型', type: 'select' }
]
},
2: { // 电视剧
name: '剧集',
filters: [
{ id: 'region', label: '地区', type: 'select',
options: [
{ value: '大陆', label: '大陆' },
{ value: '港台', label: '港台' },
{ value: '欧美', label: '欧美' },
{ value: '日韩', label: '日韩' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '分辨率', type: 'select',
options: [
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
]
},
{ id: 'genre', label: '类型', type: 'select' ,
options:[
{ value: '真人秀', label: '真人秀' },
{ value: '选秀', label: '选秀' },
{ value: '访谈', label: '访谈' },
{ value: '游戏', label: '游戏' },
{ value: '音乐', label: '音乐' },
{ value: '其他', label: '其他' },
]
}
]
},
3: { // 音乐
name: '音乐',
filters: [
{ id: 'genre', label: '类型', type: 'select',
options: [
{ value: '专辑', label: '专辑' },
{ value: '单曲', label: '单曲' },
{ value: 'EP', label: 'EP' },
{ value: '现场', label: '现场' },
{ value: '其他', label: '其他' },
]
},
{ id: 'style', label: '风格', type: 'select',
options: [
{ value: '流行', label: '流行' },
{ value: '摇滚', label: '摇滚' },
{ value: '电子', label: '电子' },
{ value: '古典', label: '古典' },
{ value: '爵士', label: '爵士' },
{ value: '民谣', label: '民谣' },
{ value: '说唱', label: '说唱' },
{ value: '其他', label: '其他' },
]
},
{id:'format', label: '格式', type: 'select',
options:[
{ value: 'MP3', label: 'MP3' },
{ value: 'FLAC', label: 'FLAC' },
{ value: 'WAV', label: 'WAV' },
{ value: 'AAC', label: 'AAC' },
{ value: 'OGG', label: 'OGG' },
{ value: '其他', label: '其他' },
]
}
]
},
4: { // 动漫
name: '动漫',
filters: [
{ id: 'genre', label: '类型', type: 'select' ,
options: [
{ value: '新番连载', label: '新番连载' },
{ value: '剧场版', label: '剧场版' },
{ value: 'OVA', label: 'OVA' },
{ value: '完结动漫', label: '完结动漫' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '格式', type: 'select' ,
options:[
{ value: 'ZIP', label: 'ZIP' },
{ value: 'RAR', label: 'RAR' },
{ value: '7Z', label: '7Z' },
{ value: 'MKV', label: 'MKV' },
{ value: 'MP4', label: 'MP4' },
{ value: '其他', label: '其他' },
]
},
{ id: 'resolution', label: '分辨率', type: 'select',
options:[
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
]
}
]
},
5: { // 游戏
name: '游戏',
filters: [
{ id: 'platform', label: '平台', type: 'select',
options: [
{ value: 'PC', label: 'PC' },
{ value: 'PS5', label: 'PS5' },
{ value: 'Xbox', label: 'Xbox' },
{ value: 'Switch', label: 'Switch' },
{ value: '手机', label: '手机' },
{ value: '其他', label: '其他' },
]
},
{ id: 'genre', label: '类型', type: 'select',
options: [
{ value: '角色扮演', label: '角色扮演' },
{ value: '射击', label: '射击' },
{ value: '冒险', label: '冒险' },
{ value: '策略', label: '策略' },
{ value: '体育', label: '体育' },
{ value: '桌面游戏', label: '桌面游戏' },
{ value: '其他', label: '其他' },
]
},
{ id: 'data_format', label: '数据类型', type: 'select' ,
options: [
{ value: '压缩包', label: '压缩包' },
{ value: '补丁', label: '补丁' },
{ value: '安装包', label: '安装包' },
{ value: 'nds', label: 'nds' },
{ value: '其他', label: '其他' },
]
},
{ id: 'language', label: '语言', type: 'select',
options: [
{ value: '中文', label: '中文' },
{ value: '英文', label: '英文' },
{ value: '日文', label: '日文' },
{ value: '其他', label: '其他' },
]
}
]
},
6: { // 综艺
name: '综艺',
filters: [
{ id: 'is_mainland', label: '是否大陆综艺', type: 'select' ,
options:[
{ value: 'true', label: '是' },
{ value: 'false', label: ' 不是' },
]
},
{ id: 'format', label: '分辨率', type: 'select',
options:[
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
]
},
{id: 'genre', label: '类型', type: 'select',
options:[
{ value: '真人秀', label: '真人秀' },
{ value: '选秀', label: '选秀' },
{ value: '访谈', label: '访谈' },
{ value: '游戏', label: '游戏' },
{ value: '音乐', label: '音乐' },
{ value: '其他', label: '其他' },
]
}
]
},
7: { // 体育
name: '体育',
filters: [
{ id: 'genre', label: '体育类型', type: 'select' ,
options:[
{ value: '足球', label: '足球' },
{ value: '篮球', label: '篮球' },
{ value: '网球', label: '网球' },
{ value: '乒乓球', label: '乒乓球' },
{ value: '羽毛球', label: '羽毛球' },
{ value: '其他', label: '其他' },
]
},
{ id: 'event_type', label: '赛事类型', type: 'select',
options:[
{ value: '足球', label: '足球' },
{ value: '篮球', label: '篮球' },
{ value: '网球', label: '网球' },
{ value: '乒乓球', label: '乒乓球' },
{ value: '羽毛球', label: '羽毛球' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '分辨率', type: 'select',
options:[
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
]
}
]
},
8: { // 软件
name: '软件',
filters: [
{ id: 'platform', label: '平台', type: 'select' ,
options:[
{ value: 'Windows', label: 'Windows' },
{ value: 'Mac', label: 'Mac' },
{ value: 'Linux', label: 'Linux' },
{ value: 'Android', label: 'Android' },
{ value: 'iOS', label: 'iOS' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '格式', type: 'select',
options:[
{ value: 'EXE', label: 'EXE' },
{ value: 'DMG', label: 'DMG' },
{ value: '光盘镜像', label: '光盘镜像' },
{ value: 'APK', label: 'APK' },
{ value: 'IPA', label: 'IPA' },
{ value: '其他', label: '其他' },
]
},
{ id: 'genre', label: '类型', type: 'select',
options:[
{ value: '系统软件', label: '系统软件' },
{ value: '应用软件', label: '应用软件' },
{ value: '游戏软件', label: '游戏软件' },
{ value: '驱动程序', label: '驱动程序' },
{ value: '办公软件', label: '办公软件' },
{ value: '其他', label: '其他' },
]
},
]
},
9: { // 学习
name: '学习',
filters: [
{ id: 'genre', label: '类型', type: 'select' ,
options:[
{ value: '计算机', label: '计算机' },
{ value: '软件', label: '软件' },
{ value: '人文', label: '人文' },
{ value: '外语', label: '外语' },
{ value: '理工科', label: '理工科' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '格式', type: 'select',
options:[
{ value: 'PDF', label: 'PDF' },
{ value: 'EPUB', label: 'EPUB' },
{ value: '视频', label: '视频' },
{ value: '音频', label: '音频' },
{ value: 'PPT', label: 'PPT' },
{ value: '其他', label: '其他' },
]
}
]
},
10: { // 纪录片
name: '纪录片',
filters: [
{ id: 'source', label: '视频源', type: 'select',
options:[
{ value: 'CCTV', label: 'CCTV' },
{ value: '卫视', label: '卫视' },
{ value: '国家地理', label: '国家地理' },
{ value: 'BBC', label: 'BBC' },
{ value: 'Discovery', label: 'Discovery' },
{ value: '其他', label: '其他' },
]
},
{ id: 'format', label: '格式', type: 'select',
options:[
{ value: '720p', label: '720p' },
{ value: '1080p', label: '1080p' },
{ value: '2K', label: '2K' },
{ value: '4K', label: '4K' },
{ value: '8K', label: '8K' },
{ value: '其他', label: '其他' },
]
}
]
},
11: { // 其他
name: '其他',
filters: [
{ id: 'gener', label: '类型', type: 'select',
options:[
{ value: '电子书', label: '电子书' },
{ value: '视频', label: '视频' },
{ value: 'MP3', label: 'MP3' },
{ value: '图片', label: '图片' },
{ value: '其他', label: '其他' },
]
}
]
}
// 其他分类配置...
}
};
// 获取分类筛选配置
const getCategoryFilters = (categoryId) => {
const category = FILTER_OPTIONS.categories[categoryId];
if (!category) return [];
return category.filters.map(filter => {
// 自动填充通用选项
if (filter.id === 'resolution' && !filter.options) {
return { ...filter, options: FILTER_OPTIONS.common.resolution };
}
if (filter.id === 'region' && !filter.options) {
const regionType = categoryId === 8 ? 'sports' : 'movie';
return { ...filter, options: FILTER_OPTIONS.common.region[regionType] };
}
if (filter.id === 'genre' && !filter.options) {
const genreType = categoryId === 3 ? 'music' : 'movie';
return { ...filter, options: FILTER_OPTIONS.common.genre[genreType] };
}
return filter;
});
};
// 格式化日期显示
const formatDate = (dateString) => {
const options = { year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit' };
return new Date(dateString).toLocaleString('zh-CN', options);
};
// 获取促销方式名称
const getPromotionName = (promotionId) => {
switch(promotionId) {
case 1: return '上传加倍';
case 2: return '下载免费';
case 3: return '下载减半';
default: return '没有促销';
}
};
function TorrentList() {
const [torrents, setTorrents] = useState([]);
const [categories, setCategories] = useState([]);
const [selectedCategory, setSelectedCategory] = useState('');
const [filters, setFilters] = useState({});
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState(null);
// 获取所有分类
useEffect(() => {
const fetchCategories = async () => {
try {
const res = await axios.get('http://localhost:8080/categories');
setCategories(res.data);
} catch (err) {
console.error('加载分类失败', err);
setError('加载分类失败,请稍后重试');
}
};
fetchCategories();
}, []);
// 获取种子数据
useEffect(() => {
const fetchTorrents = async () => {
setIsLoading(true);
setError(null);
try {
let url = selectedCategory
// ? `http://localhost:8080/torrent/listByCategory?categoryid=${selectedCategory}`
? `http://localhost:8080/torrent/listByCategorywithfilter?categoryid=${selectedCategory}`
: 'http://localhost:8080/torrent/list';
// 添加筛选参数
const params = new URLSearchParams();
Object.entries(filters).forEach(([key, value]) => {
if (value) params.append(key, value);
});
const res = await axios.get(`${url}&${params.toString()}`);
setTorrents(res.data);
console.log('torrents:', torrents);
} catch (err) {
console.error('获取种子失败', err);
setError('获取种子列表失败,请稍后重试');
} finally {
setIsLoading(false);
}
};
console.log('Fetching torrents with filters:', filters);
console.log('Selected category:', selectedCategory);
console.log(torrents);
const timer = setTimeout(fetchTorrents, 300); // 防抖
return () => clearTimeout(timer);
}, [selectedCategory, filters]);
// 切换分类时重置筛选条件
const handleCategoryChange = (categoryId) => {
setSelectedCategory(categoryId);
setFilters({});
};
// 处理筛选条件变化
const handleFilterChange = (e) => {
const { name, value } = e.target;
setFilters(prev => ({ ...prev, [name]: value }));
};
// 下载种子
const handleDownload = (torrentId) => {
window.open(`http://localhost:8080/torrent/download/${torrentId}`, '_blank');
};
// 获取当前分类的筛选配置
const currentFilters = getCategoryFilters(selectedCategory);
return (
<div className="p-4 max-w-7xl mx-auto">
<h1 className="text-2xl font-bold mb-6">种子列表</h1>
{/* 分类选择 */}
<div className="mb-6 bg-white p-4 rounded-lg shadow">
<div className="flex flex-wrap items-center gap-4">
<div className="flex items-center">
<label className="mr-2 font-medium whitespace-nowrap">选择分类:</label>
<select
value={selectedCategory}
onChange={(e) => handleCategoryChange(e.target.value)}
className="border rounded px-3 py-2 min-w-[150px]"
>
<option value="">全部分类</option>
{categories.map(cat => (
<option key={cat.categoryid} value={cat.categoryid}>
{cat.category_name}
</option>
))}
</select>
</div>
{/* 动态筛选表单 */}
{currentFilters.length > 0 && (
<div className="flex flex-wrap gap-4">
{currentFilters.map(filter => (
<div key={filter.id} className="flex items-center">
<label className="mr-2 text-sm whitespace-nowrap">{filter.label}:</label>
<select
name={filter.id}
value={filters[filter.id] || ''}
onChange={handleFilterChange}
className="border rounded px-3 py-2 min-w-[120px]"
>
<option value="">全部</option>
{filter.options.map(option => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
</div>
))}
</div>
)}
</div>
</div>
{/* 错误提示 */}
{error && (
<div className="mb-4 p-3 bg-red-100 text-red-700 rounded border border-red-200">
{error}
</div>
)}
{/* 加载状态 */}
{isLoading ? (
<div className="flex justify-center items-center h-64">
<div className="animate-spin rounded-full h-12 w-12 border-t-2 border-b-2 border-blue-500"></div>
</div>
) : (
/* 种子列表 */
<div className="bg-white rounded-lg shadow overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-gray-50">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">名称</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">大小</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">上传者</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">上传时间</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">下载次数</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">促销</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">操作</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{torrents.length > 0 ? (
torrents.map(torrent => (
<tr key={torrent.torrentid} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm font-medium text-gray-900">{torrent.filename}</div>
<div className="text-sm text-gray-500">{torrent.description}</div>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{torrent.torrentSize} B
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{torrent.uploader_id}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{new Date(torrent.uploadTime).toLocaleString()}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{torrent.downloadCount}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{getPromotionName(torrent.promotionid)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
<button
onClick={() => handleDownload(torrent.torrentid)}
className="text-blue-600 hover:text-blue-900 mr-4"
>
下载
</button>
<a
href={`/torrent/${torrent.torrentid}`}
className="text-green-600 hover:text-green-900"
>
详情
</a>
</td>
</tr>
))
) : (
<tr>
<td colSpan="7" className="px-6 py-4 text-center text-sm text-gray-500">
没有找到符合条件的种子
</td>
</tr>
)}
</tbody>
</table>
</div>
</div>
)}
</div>
);
}
export default TorrentList;