Merge "接悬赏显示优化"
diff --git a/react-ui/src/pages/Reward/index.tsx b/react-ui/src/pages/Reward/index.tsx
index 42a9bac..ee9611a 100644
--- a/react-ui/src/pages/Reward/index.tsx
+++ b/react-ui/src/pages/Reward/index.tsx
@@ -1,5 +1,5 @@
-import { ExclamationCircleOutlined, PlusOutlined, DeleteOutlined, UploadOutlined, TrophyOutlined } from '@ant-design/icons';
-import { Button, message, Modal, Switch, Upload, Form } from 'antd';
+import { ExclamationCircleOutlined, PlusOutlined, DeleteOutlined, UploadOutlined, TrophyOutlined, CheckCircleOutlined, CloseCircleOutlined, DownloadOutlined } from '@ant-design/icons';
+import { Button, message, Modal, Switch, Upload, Form, Tag } from 'antd';
import React, { useRef, useState, useEffect } from 'react';
import { FormattedMessage, useIntl } from 'umi';
import { FooterToolbar, PageContainer } from '@ant-design/pro-layout';
@@ -7,7 +7,7 @@
import ProTable from '@ant-design/pro-table';
import type { FormInstance } from 'antd';
import type { UploadFile } from 'antd/es/upload/interface';
-import { getRewardList, removeReward, updateReward, addReward } from './service';
+import { getRewardList, removeReward, updateReward, addReward, getTorrentID, submitReward } from './service';
import UpdateForm from './components/UpdateForm';
import { getDictValueEnum } from '@/services/system/dict';
import DictTag from '@/components/DictTag';
@@ -15,7 +15,7 @@
import { RewardItem, RewardListParams } from './data';
import { BtTorrent } from '../Torrent/data';
import { uploadTorrent } from '../Torrent/service';
-
+import { downloadTorrent } from '../Torrent/service';
/**
* 删除节点
*
@@ -73,11 +73,29 @@
};
/**
- * 处理接悬赏提交
+ * 下载已提交的种子文件
* @param rewardId 悬赏ID
- * @param fileList 上传的文件列表
*/
+const handleDownloadSubmitted = async (rewardId: number) => {
+ const hide = message.loading('正在下载...');
+ try {
+ const torrentID = await getTorrentID(rewardId);
+ // 这里需要调用下载接口,假设接口为 downloadRewardFile
+ const blob = await downloadTorrent(torrentID.torrentId);
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement('a');
+ link.href = url;
+ link.download = `${blob.name}.torrent`;
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ message.success('下载成功');
+ } catch (error: any) {
+ message.error('下载失败');
+ }
+};
const RewardTableList: React.FC = () => {
const formTableRef = useRef<FormInstance>();
@@ -107,8 +125,6 @@
});
}, []);
- // 修复后的接悬赏相关代码
-
/**
* 处理接悬赏提交
* @param rewardId 悬赏ID
@@ -118,7 +134,7 @@
const hide = message.loading('正在提交悬赏...');
try {
// 直接传递File对象给uploadTorrent函数
- const resp = await uploadTorrent(file);
+ const resp = await submitReward(file);
hide();
if (resp.code === 200) {
@@ -173,7 +189,7 @@
}
};
- // 文件上传前的检查(保持不变,但添加更详细的验证)
+ // 文件上传前的检查
const beforeUpload = (file: File) => {
console.log('上传前检查文件:', file.name, file.type, file.size);
@@ -199,7 +215,7 @@
return false; // 阻止自动上传,我们手动处理
};
- // 处理文件列表变化(简化逻辑)
+ // 处理文件列表变化
const handleFileChange = ({ fileList: newFileList }: { fileList: UploadFile[] }) => {
// 只保留最后一个文件
const latestFileList = newFileList.slice(-1);
@@ -239,15 +255,45 @@
</span>
),
},
- // {
- // title: '悬赏状态',
- // dataIndex: 'status',
- // valueType: 'select',
- // valueEnum: statusOptions,
- // render: (_, record) => {
- // return (<DictTag enums={statusOptions} value={record.status} />);
- // },
- // },
+ {
+ title: '完成状态',
+ dataIndex: 'status',
+ valueType: 'select',
+ valueEnum: {
+ '0': { text: '进行中', status: 'Processing' },
+ '1': { text: '已完成', status: 'Success' },
+ '2': { text: '已取消', status: 'Error' },
+ },
+ render: (_, record) => {
+ const status = record.status;
+ let color = 'default';
+ let icon = <CloseCircleOutlined />;
+ let text = '进行中';
+
+ if (status === '1') {
+ color = 'success';
+ icon = <CheckCircleOutlined />;
+ text = '已完成';
+ } else if (status === '2') {
+ color = 'error';
+ icon = <CloseCircleOutlined />;
+ text = '已取消';
+ } else {
+ color = 'processing';
+ icon = <TrophyOutlined />;
+ text = '进行中';
+ }
+
+ return (
+ <Tag
+ color={color}
+ icon={icon}
+ >
+ {text}
+ </Tag>
+ );
+ },
+ },
{
title: '发布时间',
dataIndex: 'createTime',
@@ -273,75 +319,100 @@
{
title: <FormattedMessage id="pages.searchTable.titleOption" defaultMessage="操作" />,
dataIndex: 'option',
- width: '300px',
+ width: '350px',
valueType: 'option',
- render: (_, record) => [
- <Button
- type="link"
- size="small"
- key="view"
- onClick={() => {
- setModalVisible(true);
- setCurrentRow(record);
- // 设置只读模式
- setReadOnly(true);
- }}
- >
- 查看
- </Button>,
- <Button
- type="link"
- size="small"
- key="accept"
- style={{ color: '#52c41a' }}
- icon={<TrophyOutlined />}
- onClick={() => {
- setCurrentAcceptReward(record);
- setAcceptModalVisible(true);
- setFileList([]);
- }}
- >
- 接悬赏
- </Button>,
- <Button
- type="link"
- size="small"
- key="edit"
- hidden={!access.hasPerms('reward:reward:edit')}
- onClick={() => {
- setModalVisible(true);
- setCurrentRow(record);
- setReadOnly(false);
- }}
- >
- 编辑
- </Button>,
- <Button
- type="link"
- size="small"
- danger
- key="batchRemove"
- hidden={!access.hasPerms('reward:reward:remove')}
- onClick={async () => {
- Modal.confirm({
- title: '删除',
- content: '确定删除该项吗?',
- okText: '确认',
- cancelText: '取消',
- onOk: async () => {
- const success = await handleRemove([record]);
- if (success) {
- if (actionRef.current) {
- actionRef.current.reload();
+ render: (_, record) => {
+ // 根据status判断:0进行中 1已完成 2已取消
+ const status = record.status;
+ const isCompleted = status === '1'; // 已完成
+ const isInProgress = status === '0'; // 进行中
+ const isCancelled = status === '2'; // 已取消
+
+ return [
+ <Button
+ type="link"
+ size="small"
+ key="view"
+ onClick={() => {
+ setModalVisible(true);
+ setCurrentRow(record);
+ setReadOnly(true);
+ }}
+ >
+ 查看
+ </Button>,
+ // 只有进行中的悬赏才显示"接悬赏"按钮
+ isInProgress && (
+ <Button
+ type="link"
+ size="small"
+ key="accept"
+ style={{ color: '#52c41a' }}
+ icon={<TrophyOutlined />}
+ onClick={() => {
+ setCurrentAcceptReward(record);
+ setAcceptModalVisible(true);
+ setFileList([]);
+ }}
+ >
+ 接悬赏
+ </Button>
+ ),
+ // 只有已完成的悬赏才显示"下载"按钮
+ isCompleted && (
+ <Button
+ type="link"
+ size="small"
+ key="download"
+ style={{ color: '#1890ff' }}
+ icon={<DownloadOutlined />}
+ onClick={() => {
+ handleDownloadSubmitted(record.rewardId);
+ }}
+ >
+ 下载
+ </Button>
+ ),
+ <Button
+ type="link"
+ size="small"
+ key="edit"
+ hidden={!access.hasPerms('reward:reward:edit')}
+ onClick={() => {
+ setModalVisible(true);
+ setCurrentRow(record);
+ setReadOnly(false);
+ }}
+ >
+ 编辑
+ </Button>,
+ <Button
+ type="link"
+ size="small"
+ danger
+ key="batchRemove"
+ hidden={!access.hasPerms('reward:reward:remove')}
+ onClick={async () => {
+ Modal.confirm({
+ title: '删除',
+ content: '确定删除该项吗?',
+ okText: '确认',
+ cancelText: '取消',
+ onOk: async () => {
+ const success = await handleRemove([record]);
+ if (success) {
+ if (actionRef.current) {
+ actionRef.current.reload();
+ }
}
- }
- },
- });
- }}
- >
- 删除
- </Button>,
- ],
+ },
+ });
+ }}
+ >
+ 删除
+ </Button>,
+ ].filter(Boolean) // 过滤掉 false 值
+ },
},
];
diff --git a/react-ui/src/pages/Reward/service.ts b/react-ui/src/pages/Reward/service.ts
index 390f43d..f226bae 100644
--- a/react-ui/src/pages/Reward/service.ts
+++ b/react-ui/src/pages/Reward/service.ts
@@ -9,6 +9,13 @@
BtTorrentAnnounce,
BtTorrentTag,
} from '@/pages/Torrent/data';
+
+
+export async function getTorrentID(rewardId: number): Promise<{ torrentId: number }> {
+ return request(`/api/reward/bt/${rewardId}`, {
+ method: 'GET'
+ });
+}
/** 获取悬赏任务列表 */
export async function getRewardList(params?: RewardListParams) {
const queryString = params
@@ -59,4 +66,17 @@
method: 'post',
data,
});
+}
+
+export async function submitReward(file: File) {
+ const formData = new FormData();
+ formData.append('file', file);
+
+ return request('/api/rward/uploadTorrent', {
+ method: 'POST',
+ data: formData,
+ headers: {
+ 'Content-Type': 'multipart/form-data',
+ },
+ });
}
\ No newline at end of file