整体链接

Change-Id: Id3379c6188613acdc95548964f19e317eda8dc4f
diff --git a/src/views/postDetail/postDetail.tsx b/src/views/postDetail/postDetail.tsx
index 202907b..591d9f1 100644
--- a/src/views/postDetail/postDetail.tsx
+++ b/src/views/postDetail/postDetail.tsx
@@ -1,13 +1,16 @@
-import React, { useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
 import styles from './PostDetail.module.css';
-import { Card, List, Typography, Button, Input, Spin, Empty, Divider } from 'antd';
+import { Card, List, Typography, Button, Input, Spin, Empty, Divider, message } from 'antd';
 import { getPostDetail } from '@/api/post';
-import { getPostComments } from '@/api/comment';
+import { getPostComments, postPostComments } from '@/api/comment';
 import { useSearchParams } from 'react-router-dom';
 import request from '@/utils/request';
 import { useApi } from '@/hooks/request';
 import Navbar from '@/components/navbar/navbar';
-import { DownloadOutlined, LikeOutlined, LikeFilled } from '@ant-design/icons';
+import { DownloadOutlined, LikeOutlined, LikeFilled, PayCircleOutlined } from '@ant-design/icons';
+import instance from '@/utils/axios';
+import { useAppSelector } from '@/hooks/store';
+
 
 const { Title, Text, Paragraph } = Typography;
 const { TextArea } = Input;
@@ -41,6 +44,7 @@
 }
 
 const PostDetail: React.FC = () => {
+  const [messageApi, placeholder] = message.useMessage();
   const [searchParams] = useSearchParams();
   const postId = searchParams.get('postId');
   const { refresh: getPostDetailRefresh } = useApi(() => request.get(getPostDetail + `/${postId}`), false);
@@ -50,6 +54,36 @@
   const [newComment, setNewComment] = useState<string>('');
   const [loading, setLoading] = useState<boolean>(true);
   const [liked, setLiked] = useState(false);
+  const userId = useAppSelector((state)=> state.user.userId)
+
+  const {refresh:postComment} = useApi((payload)=>request.post(postPostComments, payload), false)
+
+  const handleDownload = async (torrentId: string, torrentName:string) => {
+    console.log(torrentId)
+    try {
+      const token = localStorage.getItem('token'); // 或从状态管理中获取
+      const response = await instance.get(`/torrent/download/${torrentId}`, {
+        responseType: 'blob', 
+        headers: {
+          Authorization: `Bearer ${token}`,
+        },
+      });
+      console.log(response)
+      const blob = new Blob([response.data], { type: response.headers['content-type'] });
+      const downloadUrl = URL.createObjectURL(blob);
+
+      const a = document.createElement('a');
+      a.href = downloadUrl;
+      a.download = `资源_${torrentName}.torrent`; 
+      document.body.appendChild(a);
+      a.click();
+      document.body.removeChild(a);
+      URL.revokeObjectURL(downloadUrl); 
+    } catch (error) {
+      console.error('下载失败', error);
+      alert('下载失败,请检查网络或登录状态');
+    }
+  };
 
   useEffect(() => {
     if (!postId) return;
@@ -65,37 +99,41 @@
       const commentsRes = await getPostCommentsRefresh();
       setComments(commentsRes as CommentResponse[]);
       setLoading(false);
-      console.log("postRes:", postRes);
-      console.log("commentsRes:", commentsRes);
     };
     fetchData();
   }, [postId]);
 
+  const refreshComment = useCallback(async ()=>{
+    if(!postId) return;
+    const commentsRes = await getPostCommentsRefresh();
+    setComments(commentsRes as CommentResponse[]);
+  },[postId, setComments])
+
   if (loading) return <div className={styles.center}><Spin /></div>;
   if (!post) return <div className={styles.center}><Empty description="未找到帖子" /></div>;
 
   return (
     <div className={styles.container}>
-      {/* 固定导航栏 */}
+      {placeholder}
       <div className={styles.nav}>
         <Navbar current={post.postType} />
       </div>
-      {/* 内容区域 */}
+
       <div className={styles.contentArea}>
+        {/**帖子信息 */}
         <Card
           title={<Title level={3} style={{ margin: 0 }}>{post.postTitle || "帖子标题"}</Title>}
           className={styles.card}
-          bordered={false}
           style={{ marginBottom: 24, boxShadow: '0 4px 24px rgba(0,0,0,0.08)' }}
           extra={
             <div style={{ display: 'flex', gap: 16 }}>
               <Button
                 type="primary"
                 icon={<DownloadOutlined />}
-                onClick={() => {
-                  // 下载逻辑
-                  window.open(`/api/download/post/${post.postId}`, '_blank');
-                }}
+                onClick={() => 
+                  post.torrentId && post.postTitle
+                    ? handleDownload(post.torrentId, post.postTitle)
+                    : undefined}
               >
                 下载
               </Button>
@@ -115,9 +153,6 @@
             <Text type="secondary">作者ID: {post.userId}</Text>
             <Text type="secondary">发布时间: {post.createdAt ? new Date(post.createdAt).toLocaleString() : "未知"}</Text>
             <Text type="secondary">浏览量: {post.viewCount}</Text>
-            <Text type="secondary">类型: {post.postType}</Text>
-            <Text type="secondary">热度: {post.hotScore}</Text>
-            <Text type="secondary">最后计算: {post.lastCalculated ? new Date(post.lastCalculated).toLocaleString() : "无"}</Text>
           </div>
           {post.isLocked && (
             <div className={styles.locked}>
@@ -144,7 +179,22 @@
           <Button
             type="primary"
             style={{ marginTop: 12, float: 'right' }}
-            onClick={() => setNewComment('')}
+            onClick={async() => {
+              try{
+                await postComment({
+                  postId,
+                  userId,
+                  content:newComment,
+                  parentCommentId:''
+                })
+                setNewComment('')
+                refreshComment();
+                messageApi.success('发布成功');
+              }catch(err){
+                messageApi.error((err as Error).message);
+              }
+              
+            }}
             disabled={!newComment.trim()}
           >
             评论
@@ -152,12 +202,14 @@
           <div style={{ clear: 'both' }} />
         </Card>
 
+          {/* 评论区 */}
         <Card
           className={styles.commentListCard}
           title={<Title level={4} style={{ margin: 0 }}>评论区</Title>}
-          bodyStyle={{ padding: 0 }}
         >
-          <List
+          {
+            comments && comments.length &&
+            <List
             className={styles.commentList}
             dataSource={comments}
             locale={{ emptyText: <Empty description="暂无评论" /> }}
@@ -199,6 +251,8 @@
               </List.Item>
             )}
           />
+          }
+          
         </Card>
       </div>
     </div>