| import React, { useState, useEffect } from 'react'; |
| import { useParams, useNavigate } from 'react-router-dom'; |
| import { |
| Descriptions, |
| Table, |
| Button, |
| Modal, |
| Image, |
| message, |
| Spin, |
| Input, |
| Select, |
| Pagination, |
| Space, |
| Card |
| } from 'antd'; |
| import { ExclamationCircleOutlined } from '@ant-design/icons'; |
| import axios from 'axios'; |
| import '../torrentdetailmanage.css'; // 引入样式 |
| |
| const { confirm } = Modal; |
| const { Option } = Select; |
| |
| //const { confirm } = Modal; |
| |
| const TorrentDetailmanage = () => { |
| const { id } = useParams(); // 从URL获取种子ID |
| const navigate = useNavigate(); // 用于返回上一页 |
| const [torrent, setTorrent] = useState(null); |
| const [loading, setLoading] = useState(true); |
| const [error, setError] = useState(null); |
| const [isLoading, setIsLoading] = useState(false); |
| |
| console.log('Torrent ID:', id); |
| |
| const currentUserId = 1; // 示例,实际应从认证系统获取 |
| |
| |
| // 格式化日期 |
| const formatDate = (dateString) => { |
| if (!dateString) return '未知'; |
| const date = new Date(dateString); |
| return date.toLocaleString('zh-CN', { |
| year: 'numeric', |
| month: '2-digit', |
| day: '2-digit', |
| hour: '2-digit', |
| minute: '2-digit' |
| }); |
| }; |
| |
| // 处理删除种子 |
| const handleDeleteTorrent = async (torrentId) => { |
| if (!currentUserId) { |
| message.warning('请先登录'); |
| return; |
| } |
| |
| confirm({ |
| title: '确认删除', |
| icon: <ExclamationCircleOutlined />, |
| content: '确定要删除这个种子吗?此操作不可恢复!', |
| onOk: async () => { |
| try { |
| await axios.delete(`http://localhost:8080/torrent/delete/${torrentId}`, { |
| params: { userid: currentUserId } |
| }); |
| // 成功删除后,更新状态或返回上一页 |
| setTorrent(null); // 清空当前种子详情 |
| navigate(-1); // 返回上一页 |
| message.success('种子删除成功'); |
| } catch (err) { |
| console.error('删除种子失败', err); |
| if (err.response && err.response.status === 403) { |
| message.error('无权删除此种子'); |
| } else { |
| message.error('删除种子失败'); |
| } |
| } |
| } |
| }); |
| }; |
| |
| |
| const handleDownloadTorrent = async (torrentId) => { |
| if (!currentUserId) { |
| message.warning('请先登录'); |
| return; |
| } |
| |
| setIsLoading(true); // 开始加载 |
| try { |
| // 使用axios发送带有参数的GET请求 |
| // const response = await axios.get(`http://localhost:8080/torrent/download/${torrentId}`, { |
| // params: { userId: currentUserId }, // 正确添加请求参数 |
| // responseType: 'blob' // 重要:指定响应类型为blob以处理文件下载 |
| // }); |
| |
| // // 创建下载链接 |
| // const url = window.URL.createObjectURL(new Blob([response.data])); |
| // const link = document.createElement('a'); |
| // link.href = url; |
| // //link.setAttribute('download', 'torrent_file.torrent'); // 可以设置为动态文件名 |
| // document.body.appendChild(link); |
| // link.click(); |
| // document.body.removeChild(link); |
| // window.URL.revokeObjectURL(url); |
| open(`http://localhost:8080/torrent/download/${torrentId}?userId=${currentUserId}`, '_blank'); |
| |
| message.success('种子下载开始'); |
| } catch (err) { |
| console.error('下载种子失败', err); |
| if (err.response?.status === 404) { |
| message.error('种子不存在'); |
| } else { |
| message.error('下载失败: ' + (err.response?.data?.message || err.message)); |
| } |
| } finally { |
| setIsLoading(false); // 结束加载 |
| } |
| }; |
| |
| |
| // 格式化文件大小 |
| const formatFileSize = (bytes) => { |
| if (bytes === 0) return '0 Bytes'; |
| const k = 1024; |
| const sizes = ['Bytes', '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 getPromotionName = (promotionId) => { |
| const promotionMap = { |
| 1: '上传加倍', |
| 2: '下载减半', |
| 3: '免费下载', |
| 0: '无促销' |
| }; |
| |
| return promotionMap[promotionId] || '未知促销'; |
| }; |
| |
| // 获取种子详情 |
| useEffect(() => { |
| const fetchTorrentDetail = async () => { |
| try { |
| const response = await axios.get(`http://localhost:8080/torrent/${id}`); |
| if (response.status === 200) { |
| setTorrent(response.data); |
| } else { |
| setError('获取种子详情失败'); |
| } |
| } catch (err) { |
| console.error('获取种子详情失败:', err); |
| if (err.response) { |
| if (err.response.status === 404) { |
| setError('种子不存在'); |
| } else { |
| setError('获取种子详情失败: ' + err.response.data); |
| } |
| } else { |
| setError('网络错误,请稍后重试'); |
| } |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| fetchTorrentDetail(); |
| }, [id]); |
| |
| console.log('Torrent Detail:', torrent); |
| |
| // 返回上一页 |
| const handleBack = () => { |
| navigate(-1); // 返回上一页 |
| }; |
| |
| // 如果正在加载 |
| if (loading) { |
| return ( |
| <div className="flex justify-center items-center h-96"> |
| <Spin size="large" tip="加载中..." /> |
| </div> |
| ); |
| } |
| |
| // 如果有错误 |
| if (error) { |
| return ( |
| <div className="p-6"> |
| <Card> |
| <div className="text-center p-6"> |
| <ExclamationCircleOutlined className="text-2xl text-red-500 mb-4" /> |
| <h3 className="text-lg font-medium text-red-600 mb-2">错误</h3> |
| <p className="text-gray-600">{error}</p> |
| <Button type="primary" onClick={handleBack} className="mt-4"> |
| 返回 |
| </Button> |
| </div> |
| </Card> |
| </div> |
| ); |
| } |
| |
| // 如果种子不存在 |
| if (!torrent) { |
| return ( |
| <div className="p-6"> |
| <Card> |
| <div className="text-center p-6"> |
| <ExclamationCircleOutlined className="text-2xl text-yellow-500 mb-4" /> |
| <h3 className="text-lg font-medium text-yellow-600 mb-2">种子不存在</h3> |
| <p className="text-gray-600">抱歉,您查找的种子不存在或已被删除。</p> |
| <Button type="primary" onClick={handleBack} className="mt-4"> |
| 返回 |
| </Button> |
| </div> |
| </Card> |
| </div> |
| ); |
| } |
| |
| return ( |
| <div className="torrent-detail-page"> |
| <Card |
| className="torrent1-card" |
| title={<div className="torrent-title">种子详情</div>} |
| extra={ |
| <Button type="primary" onClick={handleBack}> |
| 返回列表 |
| </Button> |
| } |
| > |
| <Descriptions bordered column={1} size="middle"> |
| <Descriptions.Item label="ID">{torrent.torrentid}</Descriptions.Item> |
| |
| {torrent.coverImagePath && ( |
| <Descriptions.Item label="封面图片"> |
| <Image |
| className="torrent-cover-image" |
| src={torrent.coverImagePath} |
| alt="种子封面" |
| width={260} |
| height={160} |
| placeholder={ |
| <div className="w-60 h-40 bg-gray-200 flex items-center justify-center"> |
| 加载中... |
| </div> |
| } |
| /> |
| </Descriptions.Item> |
| )} |
| |
| <Descriptions.Item label="文件名">{torrent.filename}</Descriptions.Item> |
| <Descriptions.Item label="大小">{formatFileSize(torrent.torrentSize)}</Descriptions.Item> |
| <Descriptions.Item label="上传者ID">{torrent.uploader_id}</Descriptions.Item> |
| <Descriptions.Item label="上传时间">{formatDate(torrent.uploadTime)}</Descriptions.Item> |
| <Descriptions.Item label="下载次数">{torrent.downloadCount}</Descriptions.Item> |
| <Descriptions.Item label="促销">{getPromotionName(torrent.promotionid)}</Descriptions.Item> |
| <Descriptions.Item label="描述">{torrent.description || '无描述'}</Descriptions.Item> |
| </Descriptions> |
| |
| <div className="torrent-buttons"> |
| <Button |
| danger |
| onClick={() => handleDeleteTorrent(torrent.torrentid)} |
| loading={isLoading} |
| > |
| 删除 |
| </Button> |
| <Button |
| type="primary" |
| onClick={() => handleDownloadTorrent(torrent.torrentid)} |
| loading={isLoading} |
| > |
| 下载 |
| </Button> |
| </div> |
| </Card> |
| </div> |
| ); |
| }; |
| |
| export default TorrentDetailmanage; |