blob: 6990da78c92c9e2da84b728f21117da6dc82362b [file] [log] [blame]
import React, { useRef, useState } from 'react';
import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined } from '@ant-design/icons';
import {
Button,
Modal,
message,
Drawer,
Form,
Input,
InputNumber,
DatePicker,
Card,
Layout,
} from 'antd';
import {
ProTable,
ActionType,
ProColumns,
ProDescriptions,
ProDescriptionsItemProps,
} from '@ant-design/pro-components';
import type { BtTorrent } from './data';
import {
listBtTorrent,
getBtTorrent,
addBtTorrent,
updateBtTorrent,
removeBtTorrent,
} 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 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>,
],
},
];
const handleSubmit = async () => {
const values = await form.validateFields();
if (current?.torrentId) {
await updateBtTorrent({ ...current, ...values });
message.success('更新成功');
} else {
await addBtTorrent(values as BtTorrent);
message.success('新增成功');
}
setModalVisible(false);
form.resetFields();
actionRef.current?.reload();
};
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>,
]}
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>
{/* 详情抽屉 */}
<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;