diff --git a/react-ui/src/pages/Torrent/index.tsx b/react-ui/src/pages/Torrent/index.tsx
index bb058ae..30b7ef3 100644
--- a/react-ui/src/pages/Torrent/index.tsx
+++ b/react-ui/src/pages/Torrent/index.tsx
@@ -1,5 +1,5 @@
-import React, { useRef, useState } from 'react';
-import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined } from '@ant-design/icons';
+import React, { useRef, useState, useEffect } from 'react';
+import { PlusOutlined, EditOutlined, DeleteOutlined, EyeOutlined, UploadOutlined, DownloadOutlined, CommentOutlined } from '@ant-design/icons';
 import {
   Button,
   Modal,
@@ -13,21 +13,29 @@
   Layout,
   Upload,
   UploadProps,
+  Select,
+  Tag, // 导入Tag组件用于显示标签
 } from 'antd';
 import { ProTable, ActionType, ProColumns, ProDescriptions, ProDescriptionsItemProps } from '@ant-design/pro-components';
-import type { BtTorrent } from './data';
+import { useNavigate } from 'react-router-dom';
+import type { BtTorrent, BtTorrentTag } from './data';
 import {
   listBtTorrent,
   getBtTorrent,
   addBtTorrent,
   updateBtTorrent,
   removeBtTorrent,
-  uploadTorrent, // Function to handle torrent upload
+  uploadTorrent,
+  downloadTorrent,
+  addBtTorrentTag,
+  listBtTorrentTags,
+  getBtTorrentTag
 } from './service';
 
 const { Content } = Layout;
 
 const BtTorrentPage: React.FC = () => {
+  const navigate = useNavigate();
   const actionRef = useRef<ActionType>();
   const [form] = Form.useForm();
   const [modalVisible, setModalVisible] = useState(false);
@@ -35,19 +43,38 @@
   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
+  const [uploadForm] = Form.useForm(); // Form for upload modal
+  const [torrentTags, setTorrentTags] = useState<BtTorrentTag[]>([]); // 修改为数组类型来存储多个标签
 
   // 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);
+            try {
+              // 获取详细信息
+              const res = await getBtTorrent(entity.torrentId!);
+              console.log('获取的种子详情:', res); // 调试用
+
+              // 确保res是对象类型并且包含数据
+              if (res && typeof res === 'object') {
+                // 如果API返回了data包装，则提取data
+                const torrentData = res.data ? res.data : res;
+                setCurrent(torrentData);
+
+                // 先设置当前种子，然后获取标签
+                await handleGetTags(entity.torrentId!);
+                setDrawerVisible(true);
+              } else {
+                message.error('获取种子详情格式错误');
+              }
+            } catch (error) {
+              console.error('获取种子详情出错:', error);
+              message.error('获取种子详情失败');
+            }
           }}
         >
           {dom}
@@ -55,36 +82,56 @@
       ),
     },
     { title: '名称', dataIndex: 'name' },
-    { title: 'infoHash', dataIndex: 'infoHash' },
+    // { 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: '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 key="view" type="link" icon={<EyeOutlined />} onClick={async () => {
+          try {
+            // 获取详细信息
+            const res = await getBtTorrent(record.torrentId!);
+            console.log('获取的种子详情:', res); // 调试用
+
+            // 确保res是对象类型并且包含数据
+            if (res && typeof res === 'object') {
+              // 如果API返回了data包装，则提取data
+              const torrentData = res.data ? res.data : res;
+              setCurrent(torrentData);
+
+              // 获取标签
+              await handleGetTags(record.torrentId!);
+              setDrawerVisible(true);
+            } else {
+              message.error('获取种子详情格式错误');
+            }
+          } catch (error) {
+            console.error('获取种子详情出错:', error);
+            message.error('获取详情失败');
+          }
         }}>查看</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>,
+        <Button key="download" type="link" icon={<DownloadOutlined />} onClick={async () => {
+          try {
+            const blob = await downloadTorrent(record.torrentId!);
+            const url = window.URL.createObjectURL(blob);
+            const link = document.createElement('a');
+            link.href = url;
+            link.download = `${record.name}.torrent`;
+            document.body.appendChild(link);
+            link.click();
+            document.body.removeChild(link);
+            window.URL.revokeObjectURL(url);
+            message.success('下载成功');
+          } catch (error: any) {
+            message.error('下载失败');
+          }
+        }}>下载</Button>,
+
       ],
     },
   ];
@@ -115,16 +162,19 @@
         throw new Error('请选择一个文件');
       }
 
-      // Call the uploadTorrent function to upload the file
+      const values = await uploadForm.validateFields();
+      console.log(file);
+      // Call the uploadTorrent function to upload the file with additional info
       await uploadTorrent(file);
 
       // Show a success message
       message.success('文件上传成功');
 
-      // Close the upload modal
+      // Close the upload modal and reset form
       setUploadModalVisible(false);
+      uploadForm.resetFields();
 
-      // Optionally reload the table or perform other actions (e.g., refresh list)
+      // Reload the table
       actionRef.current?.reload();
 
     } catch (error) {
@@ -132,6 +182,64 @@
     }
   };
 
+  // 修改获取标签的函数，处理API特定的响应格式
+  const handleGetTags = async (id: number) => {
+    try {
+      // 根据API的响应格式，获取rows数组中的标签
+      const response = await listBtTorrentTags({ torrentId: id });
+      console.log('API标签响应:', response);
+
+      // 检查响应格式并提取rows数组
+      if (response && response.rows && Array.isArray(response.rows)) {
+        setTorrentTags(response.rows);
+        console.log('设置标签:', response.rows);
+      } else {
+        console.log('未找到标签或格式不符');
+        setTorrentTags([]);
+      }
+    } catch (error) {
+      console.error('获取标签失败:', error);
+      message.error('获取标签失败');
+      setTorrentTags([]);
+    }
+  };
+
+  useEffect(() => {
+    if (current?.torrentId) {
+      handleGetTags(current.torrentId);
+    } else {
+      setTorrentTags([]); // 清空标签当没有选中种子时
+    }
+  }, [current]);
+
+  // 渲染标签列表的函数
+  const renderTags = () => {
+    if (!torrentTags || torrentTags.length === 0) {
+      return <span style={{ color: '#999' }}>暂无标签</span>;
+    }
+
+    // 定义一些可能的标签颜色
+    const tagColors = ['blue', 'green', 'cyan', 'purple', 'magenta', 'orange', 'gold', 'lime'];
+
+    return (
+      <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px' }}>
+        {torrentTags.map((tag, index) => {
+          // 根据索引轮换颜色
+          const colorIndex = index % tagColors.length;
+          return (
+            <Tag
+              key={tag.id || tag.torrentId || index}
+              color={tagColors[colorIndex]}
+              style={{ margin: '0 4px 4px 0', padding: '2px 8px' }}
+            >
+              {tag.tag}
+            </Tag>
+          );
+        })}
+      </div>
+    );
+  };
+
   return (
     <Content>
       <Card bordered={false}>
@@ -142,22 +250,10 @@
           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
+              onClick={() => setUploadModalVisible(true)}
             >
               上传种子文件
             </Button>
@@ -202,37 +298,155 @@
         {/* 上传种子文件的Modal */}
         <Modal
           title="上传种子文件"
-          visible={uploadModalVisible}
-          onCancel={() => setUploadModalVisible(false)}
-          footer={null}
+          open={uploadModalVisible}
+          onCancel={() => {
+            setUploadModalVisible(false);
+            uploadForm.resetFields();
+          }}
+          onOk={() => {
+            if (uploadFile) {
+              handleFileUpload(uploadFile);
+            } else {
+              message.error('请选择文件');
+            }
+          }}
         >
-          <Upload
-            customRequest={({ file, onSuccess, onError }) => {
-              setUploadFile(file);
-              handleFileUpload(file);
-              onSuccess?.();
-            }}
-            showUploadList={false}
-            accept=".torrent"
-          >
-            <Button icon={<UploadOutlined />}>点击上传 .torrent 文件</Button>
-          </Upload>
+          <Form form={uploadForm} layout="vertical">
+            <Form.Item
+              name="file"
+              label="种子文件"
+              rules={[{ required: true, message: '请选择种子文件' }]}
+            >
+              <Upload
+                customRequest={({ file, onSuccess }) => {
+                  setUploadFile(file as File);
+                  onSuccess?.();
+                }}
+                showUploadList={true}
+                maxCount={1}
+                accept=".torrent"
+                onRemove={() => setUploadFile(null)}
+              >
+                <Button icon={<UploadOutlined />}>选择 .torrent 文件</Button>
+              </Upload>
+            </Form.Item>
+            <Form.Item
+              name="description"
+              label="介绍"
+              rules={[{ required: true, message: '请输入种子介绍' }]}
+            >
+              <Input.TextArea rows={4} placeholder="请输入种子文件的详细介绍" />
+            </Form.Item>
+            <Form.Item
+              name="tags"
+              label="标签"
+              rules={[{ required: true, message: '请输入标签' }]}
+            >
+              <Select
+                mode="tags"
+                style={{ width: '100%' }}
+                placeholder="请输入标签，按回车键确认"
+                tokenSeparators={[',']}
+              />
+            </Form.Item>
+          </Form>
         </Modal>
 
         {/* 详情抽屉 */}
         <Drawer
-          width={500}
+          width={600}
           open={drawerVisible}
           onClose={() => setDrawerVisible(false)}
           title="种子详情"
+          extra={
+            <Button
+              type="primary"
+              icon={<CommentOutlined />}
+              onClick={() => navigate(`/torrent/comments/${current.torrentId}`)}
+            >
+              查看评论
+            </Button>
+          }
         >
           {current && (
-            <ProDescriptions<BtTorrent>
-              column={1}
-              title={current.name}
-              request={async () => ({ data: current })}
-              columns={columns as ProDescriptionsItemProps<BtTorrent>[]}
-            />
+            <>
+              {/* 不要使用request属性，直接使用dataSource */}
+              <ProDescriptions<BtTorrent>
+                column={1}
+                title={current.name}
+                dataSource={current}
+                columns={[
+                  {
+                    title: '种子ID',
+                    dataIndex: 'torrentId',
+                    valueType: 'text'
+                  },
+                  {
+                    title: '名称',
+                    dataIndex: 'name',
+                    valueType: 'text'
+                  },
+                  {
+                    title: 'infoHash',
+                    dataIndex: 'infoHash',
+                    valueType: 'text',
+                    copyable: true
+                  },
+                  {
+                    title: '大小 (bytes)',
+                    dataIndex: 'length',
+                    valueType: 'digit',
+
+                  },
+                  {
+                    title: '分片大小',
+                    dataIndex: 'pieceLength',
+                    valueType: 'digit'
+                  },
+                  {
+                    title: '片段数',
+                    dataIndex: 'piecesCount',
+                    valueType: 'digit'
+                  },
+                  {
+                    title: '创建人',
+                    dataIndex: 'createdBy',
+                    valueType: 'text'
+                  },
+                  {
+                    title: '上传时间',
+                    dataIndex: 'uploadTime',
+                    valueType: 'dateTime'
+                  },
+                  {
+                    title: '标签',
+                    dataIndex: 'tags',
+                    render: () => renderTags()
+                  }
+                ] as ProDescriptionsItemProps<BtTorrent>[]}
+              />
+
+              {/* 如果需要显示额外信息，可以在这里添加 */}
+              {current.description && (
+                <div style={{ marginTop: 16 }}>
+                  <h3>介绍</h3>
+                  <p>{current.description}</p>
+                </div>
+              )}
+
+              {/* 添加调试信息 - 开发时使用，生产环境可以移除 */}
+              {/* <div style={{ marginTop: 20, background: '#f5f5f5', padding: 10, borderRadius: 4 }}>
+                <h4>调试信息:</h4>
+                <p>当前种子ID: {current.torrentId}</p>
+                <p>标签数量: {torrentTags?.length || 0}</p>
+                <details>
+                  <summary>查看完整数据</summary>
+                  <pre style={{ maxHeight: 200, overflow: 'auto' }}>{JSON.stringify(current, null, 2)}</pre>
+                  <h5>标签数据:</h5>
+                  <pre style={{ maxHeight: 200, overflow: 'auto' }}>{JSON.stringify(torrentTags, null, 2)}</pre>
+                </details>
+              </div> */}
+            </>
           )}
         </Drawer>
       </Card>
@@ -240,4 +454,4 @@
   );
 };
 
-export default BtTorrentPage;
+export default BtTorrentPage;
\ No newline at end of file
