blob: 9aa9ba03129d9e3e73acf750aa605e2bd0e98723 [file] [log] [blame] [edit]
// // src/pages/TorrentDetail.jsx
// import React, { useEffect, useState } from 'react';
// import { useParams } from 'react-router-dom';
// import axios from 'axios';
// const TorrentDetail = () => {
// const { id } = useParams(); // 获取 URL 中的 torrentid
// const [torrent, setTorrent] = useState(null);
// const [seeders, setSeeders] = useState([]);
// const [loading, setLoading] = useState(true);
// useEffect(() => {
// console.log("Received Torrent:", torrent);
// }, [torrent]);
// useEffect(() => {
// axios.get(`http://localhost:8080/torrent/${id}`)
// .then(res => setTorrent(res.data))
// setTorrent(res.data);
// return axios.get(`http://localhost:8080/torrent/${res.data.infoHash}/seeders`);
// }).then(res =>
// setSeeders(res.data))
// .catch(err => {
// console.error("Error fetching torrent details:", err)
// .finally(() => setLoading(false));
// },[id]);
// if (!torrent) return <div className="p-4">加载中...</div>;
// // 格式化文件大小
// const formatSize = (bytes) => {
// if (bytes === 0) return '0 B';
// const k = 1024;
// const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
// const i = Math.floor(Math.log(bytes) / Math.log(k));
// return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
// };
// // 格式化速度
// const formatSpeed = (bytesPerSec) => {
// if (bytesPerSec < 1024) return bytesPerSec.toFixed(2) + ' B/s';
// if (bytesPerSec < 1024 * 1024) return (bytesPerSec / 1024).toFixed(2) + ' KB/s';
// return (bytesPerSec / (1024 * 1024)).toFixed(2) + ' MB/s';
// };
// return (
// <div className="max-w-2xl mx-auto p-6 bg-white shadow rounded mt-6">
// <h1 className="text-2xl font-bold mb-4">{torrent.torrentTitle}</h1>
// <div className="space-y-2 text-gray-700">
// <p><strong>简介:</strong>{torrent.description}</p>
// {/* 修复上传人显示 */}
// <p><strong>上传人:</strong>{torrent.uploader_id !== undefined ? torrent.uploader_id : '未知用户'}</p>
// <p><strong>上传时间:</strong>{new Date(torrent.uploadTime).toLocaleString()}</p>
// <p><strong>下载数:</strong>{torrent.downloadCount}</p>
// <p><strong>文件大小:</strong>{torrent.torrentSize} B</p>
// <p><strong>文件分辨率:</strong>{torrent.dpi}</p>
// <p><strong>文件字幕:</strong>{torrent.caption}</p>
// <p><strong>最后做种时间:</strong>{new Date(torrent.lastseed).toLocaleString()}</p>
// </div>
// {/* 做种者列表 */}
// <div className="mt-6">
// <h2 className="text-xl font-semibold mb-3">做种用户 ({seeders.length})</h2>
// {seeders.length > 0 ? (
// <div className="overflow-x-auto">
// <table className="min-w-full bg-white border border-gray-200">
// <thead className="bg-gray-100">
// <tr>
// <th className="py-2 px-4 border-b">用户名</th>
// <th className="py-2 px-4 border-b">已上传</th>
// <th className="py-2 px-4 border-b">上传速度</th>
// <th className="py-2 px-4 border-b">已下载</th>
// <th className="py-2 px-4 border-b">下载速度</th>
// <th className="py-2 px-4 border-b">客户端</th>
// <th className="py-2 px-4 border-b">最后活动</th>
// </tr>
// </thead>
// <tbody>
// {seeders.map((seeder, index) => (
// <tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
// <td className="py-2 px-4 border-b text-center">{seeder.username}</td>
// <td className="py-2 px-4 border-b text-center">{formatSize(seeder.uploaded)}</td>
// <td className="py-2 px-4 border-b text-center text-green-600">
// {formatSpeed(seeder.uploadSpeed)}
// </td>
// <td className="py-2 px-4 border-b text-center">{formatSize(seeder.downloaded)}</td>
// <td className="py-2 px-4 border-b text-center">
// {seeder.downloadSpeed > 0 ? formatSpeed(seeder.downloadSpeed) : '-'}
// </td>
// <td className="py-2 px-4 border-b text-center">{seeder.client}</td>
// <td className="py-2 px-4 border-b text-center">
// {new Date(seeder.lastActive).toLocaleTimeString()}
// </td>
// </tr>
// ))}
// </tbody>
// </table>
// </div>
// ) : (
// <div className="p-4 text-center text-gray-500 bg-gray-50 rounded">
// 当前没有用户在做种
// </div>
// )}
// </div>
// </div>
// );
// };
// export default TorrentDetail;
// src/pages/TorrentDetail.jsx
import React, { useEffect, useState } from 'react';
import { useParams } from 'react-router-dom';
import axios from 'axios';
const TorrentDetail = () => {
const { id } = useParams();
const [torrent, setTorrent] = useState(null);
const [seeders, setSeeders] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
// 获取种子基本信息
axios.get(`http://localhost:8080/torrent/${id}`)
.then(res => {
setTorrent(res.data);
// 获取做种者信息
return axios.get(`http://localhost:8080/torrent/${res.data.infoHash}/seeders`);
})
.then(res => setSeeders(res.data))
.catch(err => console.error('获取数据失败', err))
.finally(() => setLoading(false));
}, [id]);
if (loading) return <div className="p-4">加载中...</div>;
if (!torrent) return <div className="p-4">种子不存在</div>;
console.log('Received Torrent:', torrent);
console.log('Received Seeders:', seeders);
// 格式化文件大小
const formatSize = (bytes) => {
if (bytes === 0) return '0 B';
const k = 1024;
const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
};
// 格式化速度
const formatSpeed = (bytesPerSec) => {
if (bytesPerSec < 1024) return bytesPerSec.toFixed(2) + ' B/s';
if (bytesPerSec < 1024 * 1024) return (bytesPerSec / 1024).toFixed(2) + ' KB/s';
return (bytesPerSec / (1024 * 1024)).toFixed(2) + ' MB/s';
};
return (
<div className="max-w-4xl mx-auto p-6 bg-white shadow rounded mt-6">
<h1 className="text-2xl font-bold mb-4">{torrent.torrentTitle}</h1>
{/* 种子基本信息 */}
<div className="mb-8 p-4 bg-gray-50 rounded">
<h2 className="text-xl font-semibold mb-3">基本信息</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 text-gray-700">
<div>
<p><strong>简介:</strong>{torrent.description || '暂无简介'}</p>
<p><strong>上传人:</strong>{torrent.uploader_id || '未知用户'}</p>
<p><strong>上传时间:</strong>{new Date(torrent.uploadTime).toLocaleString()}</p>
<p><strong>文件大小:</strong>{formatSize(torrent.torrentSize)}</p>
</div>
<div>
<p><strong>下载数:</strong>{torrent.downloadCount || 0}</p>
<p><strong>做种数:</strong>{seeders.length}</p>
<p><strong>文件分辨率:</strong>{torrent.dpi || '未知'}</p>
<p><strong>文件字幕:</strong>{torrent.caption || '无'}</p>
<p><strong>最后做种时间:</strong>{torrent.lastseed ? new Date(torrent.lastseed).toLocaleString() : '暂无'}</p>
</div>
</div>
</div>
{/* 做种者列表 */}
<div className="mt-6">
<h2 className="text-xl font-semibold mb-3">做种用户 ({seeders.length})</h2>
{seeders.length > 0 ? (
<div className="overflow-x-auto">
<table className="min-w-full bg-white border border-gray-200">
<thead className="bg-gray-100">
<tr>
<th className="py-2 px-4 border-b">用户名</th>
<th className="py-2 px-4 border-b">已上传</th>
<th className="py-2 px-4 border-b">上传时间</th>
<th className="py-2 px-4 border-b">完成时间</th>
<th className="py-2 px-4 border-b">上传速度</th>
<th className="py-2 px-4 border-b">已下载</th>
<th className="py-2 px-4 border-b">下载速度</th>
<th className="py-2 px-4 border-b">客户端</th>
<th className="py-2 px-4 border-b">端口</th>
<th className="py-2 px-4 border-b">最后活动</th>
</tr>
</thead>
<tbody>
{seeders.map((seeder, index) => (
<tr key={index} className={index % 2 === 0 ? 'bg-gray-50' : 'bg-white'}>
<td className="py-2 px-4 border-b text-center">{seeder.username}</td>
<td className="py-2 px-4 border-b text-center">{formatSize(seeder.uploaded)}</td>
<td className="py-2 px-4 border-b text-center text-green-600">
{new Date(seeder.createdAt).toLocaleString()}
</td>
<td className="py-2 px-4 border-b text-center text-green-600">
{new Date(seeder.completed_time).toLocaleString()}
</td>
<td className="py-2 px-4 border-b text-center text-green-600">
{formatSpeed(seeder.uploadSpeed)}
</td>
<td className="py-2 px-4 border-b text-center">{formatSize(seeder.downloaded)}</td>
<td className="py-2 px-4 border-b text-center">
{seeder.downloadSpeed > 0 ? formatSpeed(seeder.downloadSpeed) : '-'}
</td>
<td className="py-2 px-4 border-b text-center">{seeder.client}</td>
<td className="py-2 px-4 border-b text-center">{seeder.port}</td>
<td className="py-2 px-4 border-b text-center">
{seeder.lastEvent}
</td>
</tr>
))}
</tbody>
</table>
</div>
) : (
<div className="p-4 text-center text-gray-500 bg-gray-50 rounded">
当前没有用户在做种
</div>
)}
</div>
</div>
);
};
export default TorrentDetail;