blob: bb058aee248c9e04c8003a59c002e4aa7f45b848 [file] [log] [blame]
import React, { useRef, useState } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined } from '@ant-design/icons';
import {
Button,
Modal,
message,
Drawer,
Form,
Input,
InputNumber,
DatePicker,
Card,
Layout,
Upload,
UploadProps,
} from 'antd';
import { ProTable, ActionType, ProColumns, ProDescriptions, ProDescriptionsItemProps } from '@ant-design/pro-components';
import type { BtTorrent } from './data';
import {
listBtTorrent,
getBtTorrent,
addBtTorrent,
updateBtTorrent,
removeBtTorrent,
uploadTorrent, // Function to handle torrent upload
} from './service';
const { Content } = Layout;
const BtTorrentPage: React.FC = () => {
const actionRef = useRef<ActionType>();
const [form] = Form.useForm();
const [modalVisible, setModalVisible] = useState(false);
const [drawerVisible, setDrawerVisible] = useState(false);
const [current, setCurrent] = useState<Partial<BtTorrent>>({});
const [uploadModalVisible, setUploadModalVisible] = useState(false); // State for upload modal
const [uploadFile, setUploadFile] = useState<File | null>(null); // State to store selected file
// Columns for the ProTable (the table displaying torrents)
const columns: ProColumns<BtTorrent>[] = [
{
title: '种子ID',
dataIndex: 'torrentId',
hideInForm: true,
render: (dom, entity) => (
<a
onClick={async () => {
const res = await getBtTorrent(entity.torrentId!);
setCurrent(res);
setDrawerVisible(true);
}}
>
{dom}
</a>
),
},
{ title: '名称', dataIndex: 'name' },
{ title: 'infoHash', dataIndex: 'infoHash' },
{ title: '大小 (bytes)', dataIndex: 'length', valueType: 'digit' },
{ title: '分片大小', dataIndex: 'pieceLength', valueType: 'digit' },
{ title: '片段数', dataIndex: 'piecesCount', valueType: 'digit' },
{ title: '创建工具', dataIndex: 'createdBy', hideInSearch: true },
{ title: '上传时间', dataIndex: 'uploadTime', valueType: 'dateTime', hideInSearch: true },
{
title: '操作',
valueType: 'option',
render: (_, record) => [
<Button key="view" type="link" icon={<EyeOutlined />} onClick={() => {
setCurrent(record);
setDrawerVisible(true);
}}>查看</Button>,
<Button key="edit" type="link" icon={<EditOutlined />} onClick={() => {
setCurrent(record);
form.setFieldsValue(record);
setModalVisible(true);
}}>编辑</Button>,
<Button key="delete" type="link" icon={<DeleteOutlined />} danger onClick={() => {
Modal.confirm({
title: '删除确认',
content: '确定删除该种子?',
onOk: async () => {
await removeBtTorrent([record.torrentId!]);
message.success('删除成功');
actionRef.current?.reload();
},
});
}}>删除</Button>,
],
},
];
// Handle the submit for adding or updating a torrent
const handleSubmit = async () => {
const values = await form.validateFields();
try {
if (current?.torrentId) {
await updateBtTorrent({ ...current, ...values });
message.success('更新成功');
} else {
await addBtTorrent(values as BtTorrent);
message.success('新增成功');
}
setModalVisible(false);
form.resetFields();
actionRef.current?.reload();
} catch (error) {
message.error('操作失败');
}
};
// Handle file upload
const handleFileUpload = async (file: File) => {
try {
if (!file) {
throw new Error('请选择一个文件');
}
// Call the uploadTorrent function to upload the file
await uploadTorrent(file);
// Show a success message
message.success('文件上传成功');
// Close the upload modal
setUploadModalVisible(false);
// Optionally reload the table or perform other actions (e.g., refresh list)
actionRef.current?.reload();
} catch (error) {
message.error(error.message || '文件上传失败');
}
};
return (
<Content>
<Card bordered={false}>
<ProTable<BtTorrent>
headerTitle="种子列表"
actionRef={actionRef}
rowKey="torrentId"
search={{ labelWidth: 100 }}
toolBarRender={() => [
<Button
key="add"
type="primary"
icon={<PlusOutlined />}
onClick={() => {
form.resetFields();
setCurrent({});
setModalVisible(true);
}}
>
新增
</Button>,
<Button
key="upload"
type="primary"
icon={<UploadOutlined />}
onClick={() => setUploadModalVisible(true)} // Show the upload modal
>
上传种子文件
</Button>
]}
request={async (params) => {
const res = await listBtTorrent(params);
return { data: res.rows || res.data || [], success: true };
}}
columns={columns}
/>
{/* 编辑/新增弹窗 */}
<Modal
title={current?.torrentId ? '编辑种子' : '新增种子'}
open={modalVisible}
onOk={handleSubmit}
onCancel={() => setModalVisible(false)}
destroyOnClose
>
<Form form={form} layout="vertical">
<Form.Item name="name" label="名称" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="infoHash" label="infoHash" rules={[{ required: true }]}>
<Input />
</Form.Item>
<Form.Item name="length" label="总大小 (bytes)" rules={[{ required: true }]}>
<InputNumber style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="pieceLength" label="分片大小" rules={[{ required: true }]}>
<InputNumber style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="piecesCount" label="片段数">
<InputNumber style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="createdBy" label="创建工具">
<Input />
</Form.Item>
</Form>
</Modal>
{/* 上传种子文件的Modal */}
<Modal
title="上传种子文件"
visible={uploadModalVisible}
onCancel={() => setUploadModalVisible(false)}
footer={null}
>
<Upload
customRequest={({ file, onSuccess, onError }) => {
setUploadFile(file);
handleFileUpload(file);
onSuccess?.();
}}
showUploadList={false}
accept=".torrent"
>
<Button icon={<UploadOutlined />}>点击上传 .torrent 文件</Button>
</Upload>
</Modal>
{/* 详情抽屉 */}
<Drawer
width={500}
open={drawerVisible}
onClose={() => setDrawerVisible(false)}
title="种子详情"
>
{current && (
<ProDescriptions<BtTorrent>
column={1}
title={current.name}
request={async () => ({ data: current })}
columns={columns as ProDescriptionsItemProps<BtTorrent>[]}
/>
)}
</Drawer>
</Card>
</Content>
);
};
export default BtTorrentPage;