blob: 936b88a4b2190d11b66b822afefce999039719e9 [file] [log] [blame]
// index.tsx - 活动中心页面
import React, { useState, useEffect, useRef } from 'react';
import {
Card,
Button,
Tag,
message,
Spin,
Empty,
List,
Space,
Typography,
Upload
} from 'antd';
import {
GiftOutlined,
UploadOutlined,
DownloadOutlined,
FireOutlined,
CheckCircleOutlined,
ClockCircleOutlined
} from '@ant-design/icons';
import { PageContainer } from '@ant-design/pro-components';
import { getActivityList, participateActivity, formatDateTime } from './service';
import { uploadTorrent, downloadTorrent } from '../Torrent/service';
import type { SysActivity } from './data';
const { Title, Text } = Typography;
const ActivityPage: React.FC = () => {
const [activities, setActivities] = useState<SysActivity[]>([]);
const [loading, setLoading] = useState(false);
const [participatingIds, setParticipatingIds] = useState<Set<number>>(new Set());
const [uploading, setUploading] = useState(false);
const [downloading, setDownloading] = useState<number | null>(null);
const fileInputRef = useRef<HTMLInputElement>(null);
// 获取活动列表
const fetchActivities = async () => {
setLoading(true);
try {
const res = await getActivityList({ pageNum: 1, pageSize: 20 });
console.log('活动列表响应:', res);
if (res.code === 0) {
// 修正:使用 res.data.list 而不是 res.rows
setActivities(res.data.list);
console.log('活动数据:', res.data.list);
console.log('第一个活动:', res.data.list[0]);
} else {
message.error(res.msg || '获取活动列表失败');
}
} catch (error) {
console.error('获取活动列表异常:', error);
message.error('网络异常,请稍后重试');
} finally {
setLoading(false);
}
};
// 获取排行榜
// const fetchLeaderboard = async () => {
// try {
// const res = await getLeaderboard({ pageNum: 1, pageSize: 50 });
// if (res.code === 0) {
// setLeaderboard(res.data.list);
// } else {
// message.error(res.msg || '获取排行榜失败');
// }
// } catch (error) {
// console.error('获取排行榜失败', error);
// message.error('获取排行榜异常,请稍后重试');
// }
// };
// 处理文件上传
const handleUpload = async (file: File, activity: SysActivity) => {
setUploading(true);
try {
const res = await uploadTorrent(file);
if (res.code === 0) {
message.success('上传成功!');
// 上传成功后自动参与活动
await handleParticipate(activity.activityId);
} else {
message.error(res.msg || '上传失败');
}
} catch (error) {
console.error('上传异常:', error);
message.error('上传异常,请稍后重试');
} finally {
setUploading(false);
}
};
// 处理种子下载
const handleDownload = async (activity: SysActivity) => {
setDownloading(activity.activityId);
try {
const torrentId = activity.conditionValue; // 种子ID存储在conditionValue中
const blob = await downloadTorrent(Number(torrentId));
// 创建下载链接
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = `torrent_${torrentId}.torrent`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
message.success('下载成功');
// 下载成功后自动参与活动
await handleParticipate(activity.activityId);
} catch (error) {
console.error('下载异常:', error);
message.error('下载异常,请稍后重试');
} finally {
setDownloading(null);
}
};
// 触发文件选择
const triggerFileUpload = (activity: SysActivity) => {
const input = document.createElement('input');
input.type = 'file';
input.accept = '.torrent';
input.onchange = (e) => {
const file = (e.target as HTMLInputElement).files?.[0];
if (file) {
handleUpload(file, activity);
}
};
input.click();
};
// 参与活动
const handleParticipate = async (activityId: number) => {
// 添加到参与中的活动ID集合
setParticipatingIds(prev => new Set(prev).add(activityId));
try {
const res = await participateActivity(activityId);
if (res.code === 0) {
message.success('参与成功!');
fetchActivities();
// 已删除排行榜刷新
} else {
message.error(res.msg || '参与失败');
}
} catch (error) {
console.error('参与活动异常:', error);
message.error('网络异常,请稍后重试');
} finally {
// 从参与中的活动ID集合中移除
setParticipatingIds(prev => {
const newSet = new Set(prev);
newSet.delete(activityId);
return newSet;
});
}
};
useEffect(() => {
fetchActivities();
// 已删除排行榜获取
}, []);
// 渲染活动类型图标(可点击)
const renderActivityIcon = (activity: SysActivity) => {
if (activity.status === 0) {
// 活动已结束,图标不可点击
return activity.activityType === 'UPLOAD' ?
<UploadOutlined style={{ fontSize: 20, color: '#d9d9d9' }} /> :
<DownloadOutlined style={{ fontSize: 20, color: '#d9d9d9' }} />;
}
if (activity.activityType === 'UPLOAD') {
return (
<UploadOutlined
style={{
fontSize: 20,
color: '#1890ff',
cursor: 'pointer'
}}
title="点击上传种子文件"
onClick={() => triggerFileUpload(activity)}
/>
);
} else {
return (
<DownloadOutlined
style={{
fontSize: 20,
color: '#52c41a',
cursor: 'pointer'
}}
title="点击下载种子"
onClick={() => handleDownload(activity)}
/>
);
}
};
// 渲染状态标签
const renderStatusTag = (status: number) => {
return status === 1 ? (
<Tag icon={<FireOutlined />} color="success">进行中</Tag>
) : (
<Tag icon={<CheckCircleOutlined />} color="default">已结束</Tag>
);
};
// 格式化条件显示
const formatCondition = (activity: SysActivity) => {
if (activity.activityType === 'UPLOAD') {
return `上传 ${activity.conditionValue}`;
}
return '完成下载任务';
};
// 格式化时间显示
const formatTimeRange = (startTime: string, endTime: string) => {
try {
// 处理 ISO 8601 格式的时间
const start = formatDateTime(startTime);
const end = formatDateTime(endTime);
// 只显示日期部分
const startDate = start.split(' ')[0];
const endDate = end.split(' ')[0];
return `${startDate} ~ ${endDate}`;
} catch (error) {
console.error('时间格式化错误:', error);
// 降级处理:如果是老格式,直接使用
return `${startTime.split(' ')[0]} ~ ${endTime.split(' ')[0]}`;
}
};
// 排行榜相关代码已删除
return (
<PageContainer title="活动中心">
<Spin spinning={loading}>
<List
grid={{ gutter: 16, xs: 1, sm: 2, md: 2, lg: 3, xl: 3 }}
dataSource={activities}
locale={{ emptyText: <Empty description="暂无活动" /> }}
renderItem={(activity) => (
<List.Item>
<Card
hoverable
actions={[
<Button
key="participate"
type="primary"
disabled={activity.status === 0}
loading={
participatingIds.has(activity.activityId) ||
uploading ||
downloading === activity.activityId
}
onClick={() => handleParticipate(activity.activityId)}
>
{activity.status === 1 ? '确认参与' : '已结束'}
</Button>
]}
>
<Space direction="vertical" size={8} style={{ width: '100%' }}>
<Space style={{ width: '100%', justifyContent: 'space-between' }}>
{renderActivityIcon(activity)}
{renderStatusTag(activity.status)}
</Space>
<Title level={5} style={{ margin: 0 }}>
{activity.activityName}
</Title>
<Text type="secondary">
{formatCondition(activity)}
</Text>
<Space>
<GiftOutlined style={{ color: '#faad14' }} />
<Text strong style={{ color: '#faad14' }}>
{activity.rewardBonus} 积分
</Text>
</Space>
<Space size={4} style={{ fontSize: 12 }}>
<ClockCircleOutlined />
<Text type="secondary">
{formatTimeRange(activity.startTime, activity.endTime)}
</Text>
</Space>
{/* 操作提示 */}
{activity.status === 1 && (
<Text type="secondary" style={{ fontSize: 12 }}>
{activity.activityType === 'UPLOAD'
? '点击上传图标选择种子文件'
: '点击下载图标获取种子'
}
</Text>
)}
</Space>
</Card>
</List.Item>
)}
/>
</Spin>
</PageContainer>
);
};
export default ActivityPage;