Merge "fix local data" into main
diff --git a/Dockerfile b/Dockerfile
index af2bef1..e901b14 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -30,10 +30,12 @@
 
 # 设置环境变量
 ENV NODE_ENV=production
-ENV PORT=3000
+ENV PORT=3009
+ENV NEXT_PUBLIC_NGINX_URL=http://team9.10813352.xyz:5009/upload
+ENV PUBLIC_URL=http://team9.10813352.xyz:5009/api
 
 # 暴露端口
-EXPOSE 3000
+EXPOSE 3009
 
 # 启动命令
 CMD ["node", "server.js"]
\ No newline at end of file
diff --git "a/src/app/community/community-detail/\133communityId\135/page.tsx" "b/src/app/community/community-detail/\133communityId\135/page.tsx"
index e366843..33011eb 100644
--- "a/src/app/community/community-detail/\133communityId\135/page.tsx"
+++ "b/src/app/community/community-detail/\133communityId\135/page.tsx"
@@ -142,12 +142,13 @@
     const handleSubmit = async () => {
         try {
             const currentDate = new Date().toISOString();
+            console.log(formData);
             const postData = {
                 userId, // 记得用户登录状态获取
                 threadPicture: formData.threadPicture,
                 title: formData.title,
                 content: formData.content,
-                createdAt: currentDate,
+                createAt: currentDate.slice(0, 10),
                 communityId: communityId // 从URL参数获取的社区ID
             };
             // 发送POST请求
@@ -213,7 +214,7 @@
                     {threads.map((thread) => (
                         <Card key={thread.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${thread.threadId}`)}>
                             <Image
-                                src={process.env.NEXT_PUBLIC_NGINX_URL + thread.threadPicture}
+                                src={ thread.threadPicture}
                                 alt={thread.title}
                                 width="368"
                                 height="200"
@@ -285,8 +286,9 @@
                                 try {
                                     const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
 
-                                    const fileUrl = res.data.url;
+                                    const fileUrl = res.data;
                                     console.log(fileUrl);
+                                    setFormData(prev => ({ ...prev, threadPicture: fileUrl }))
                                     toast.current?.show({ severity: 'success', summary: '上传成功' });
                                 } catch (error) {
                                     console.log(error);
diff --git a/src/app/community/page.tsx b/src/app/community/page.tsx
index 81c8a6b..b24242a 100644
--- a/src/app/community/page.tsx
+++ b/src/app/community/page.tsx
@@ -106,7 +106,7 @@
                         width="24"
                         height="24"
                       /></div>
-                    <Image src={process.env.NEXT_PUBLIC_NGINX_URL + item.communityPicture} alt={item.communityName} height="200" className="w-full h-48 object-cover" />
+                    <Image src={item.communityPicture} alt={item.communityName} height="200" className="w-full h-48 object-cover" />
                   </div>
                 }
               >
@@ -165,7 +165,7 @@
         <div className="all-communities-list">
           {communities.map((community) => (
             <Card key={community.communityId} className="all-communities-card" onClick={() => router.push(`/community/community-detail/${community.communityId}`)}>
-              <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + community.communityPicture} className="community-avatar" width="250" height="140" />
+              <Image alt="avatar" src={ community.communityPicture} className="community-avatar" width="250" height="140" />
               <div className="community-header">
                 <div className="community-content">
                   <h3>{community.communityName}</h3>
diff --git "a/src/app/community/resource-community-list/\133category\135/page.tsx" "b/src/app/community/resource-community-list/\133category\135/page.tsx"
index 16f6bd6..cb3e3b0 100644
--- "a/src/app/community/resource-community-list/\133category\135/page.tsx"
+++ "b/src/app/community/resource-community-list/\133category\135/page.tsx"
@@ -111,7 +111,7 @@
             <div className="resource-communities-list">
                 {communities.map((community) => (
                     <Card key={community.communityId} className="resource-communities-list-card" onClick={() => router.push(`/community/community-detail/${community.communityId}`)}>
-                        <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + community.communityPicture} className="community-avatar" width="250" height="140" />
+                        <Image alt="avatar" src={ community.communityPicture} className="community-avatar" width="250" height="140" />
                         <div className="community-header">
                             <div className="community-content">
                                 <h3>{community.communityName}</h3>
diff --git "a/src/app/community/thread-detail/\133threadId\135/page.tsx" "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
index 0f3e5b2..097c35a 100644
--- "a/src/app/community/thread-detail/\133threadId\135/page.tsx"
+++ "b/src/app/community/thread-detail/\133threadId\135/page.tsx"
@@ -59,9 +59,9 @@
 // 新评论接口
 interface NewComment {
     userId: number;
-    threadId: number;
-    resourceId: number;
-    replyId: number;
+    threadId: number | null;
+    resourceId: number | null;
+    replyId: number | null;
     content: string;
     createdAt: string;
 }
@@ -139,7 +139,7 @@
             try {
                 const response = await axios.post(
                     process.env.PUBLIC_URL + `/thread/like`, {
-                    params: { threadId, userId }
+                     threadId, userId
                 }
                 );
                 fetchThreadInfo(); // 刷新帖子信息
@@ -194,7 +194,7 @@
             const pageNumber = first / rows + 1;
             console.log("当前页" + pageNumber + "size" + rows);
             const response = await axios.get<CommentList>(
-                process.env.PUBLIC_URL + `/comments`, {
+                process.env.PUBLIC_URL + `/comment`, {
                 params: { threadId, pageNumber, rows }
             }
             );
@@ -225,10 +225,10 @@
             const newComment: NewComment = {
                 userId,
                 threadId: threadInfo.threadId,
-                resourceId: 0,
+                resourceId: null,
                 replyId: commentId,
                 content: commentValue,
-                createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+                createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
             };
 
             const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -255,10 +255,10 @@
             const newComment: NewComment = {
                 userId,
                 threadId: threadInfo.threadId,
-                resourceId: 0,
-                replyId: 0, // 直接评论,不是回复
+                resourceId: null,
+                replyId: null, // 直接评论,不是回复
                 content: commentValue,
-                createdAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+                createdAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
             };
 
             const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -310,7 +310,7 @@
             {/* 帖子头部 */}
             <div className="thread-header">
                 <div className="user-info">
-                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                     <div className="user-meta">
                         <h3>{userInfo.username}</h3>
                         <span>{userInfo.signature}</span>
@@ -324,7 +324,7 @@
                 <h1>{threadInfo.title}</h1>
                 <div className="content-body">
                     <Image
-                        src={process.env.NEXT_PUBLIC_NGINX_URL + threadInfo.threadPicture}
+                        src={ threadInfo.threadPicture}
                         alt={threadInfo.title}
                         width="800"
                         height="400"
@@ -347,7 +347,7 @@
                     <h2>评论 ({totalComments})</h2>
                 </div>
                 <div className="comments-input">
-                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                     <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
                     <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
                 </div>
@@ -356,7 +356,7 @@
                         <div key={comment.commentId} className="comment-item">
                             <div className="comment-user">
                                 <Avatar
-                                    image={comment.userId ? process.env.NEXT_PUBLIC_NGINX_URL + "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
+                                    image={comment.userId ?  "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
                                     size="normal"
                                     shape="circle"
                                 />
@@ -391,7 +391,7 @@
                             </OverlayPanel>
                             <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
                                 <div className="reply-input">
-                                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                                     <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
                                     <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
                                 </div>
diff --git a/src/app/hook/useLocalStorage.ts b/src/app/hook/useLocalStorage.ts
index 2b28b01..7628f37 100644
--- a/src/app/hook/useLocalStorage.ts
+++ b/src/app/hook/useLocalStorage.ts
@@ -1,19 +1,51 @@
 import { useEffect, useState } from 'react';
 
-export const useLocalStorage = <T>(key: string): T | null => {
-  const [value, setValue] = useState<T | null>(null);
+// export const useLocalStorage = <T>(key: string): T | null => {
+//   const [value, setValue] = useState<T | null>(null);
 
-  useEffect(() => {
-    if (typeof window !== 'undefined') {
+//   useEffect(() => {
+//     if (typeof window !== 'undefined') {
+//       const item = localStorage.getItem(key);
+//       if (item) {
+//         try {
+//           setValue(JSON.parse(item));
+//           console.log(JSON.parse(item));
+//         } catch (e) {
+//           console.error(`解析 localStorage ${key} 失败`, e);
+//         }
+//       }
+//     }
+//   }, [key]);
+
+//   return value;
+// };
+
+export const useLocalStorage = <T>(key: string): T | null => {
+  const isClient = typeof window !== 'undefined';
+  const [value, setValue] = useState<T | null>(() => {
+    if (isClient) {
       const item = localStorage.getItem(key);
       if (item) {
         try {
-          setValue(JSON.parse(item));
+          return JSON.parse(item);
         } catch (e) {
           console.error(`解析 localStorage ${key} 失败`, e);
         }
       }
     }
+    return null;
+  });
+
+  useEffect(() => {
+    if (!isClient) return;
+    const item = localStorage.getItem(key);
+    if (item) {
+      try {
+        setValue(JSON.parse(item));
+      } catch (e) {
+        console.error(`解析 localStorage ${key} 失败`, e);
+      }
+    }
   }, [key]);
 
   return value;
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 5076a0a..f3555da 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -233,7 +233,7 @@
             className="custom-carousel"
             itemTemplate={(hotResource) => (
               <div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
-                <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
+                <Image alt="slide" src={hotResource.resourcePicture} className="carousel-avatar" width="700" height="350" />
               </div>
             )}
           />
@@ -288,7 +288,7 @@
           {mods.map((mod) => (
             <Card key={mod.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${mod.resourceId}`)}>
               <Image
-                src={process.env.NEXT_PUBLIC_NGINX_URL + mod.resourcePicture}
+                src={mod.resourcePicture}
                 alt={mod.resourceName}
                 width="368"
                 height="200"
@@ -318,7 +318,7 @@
           {maps.map((map) => (
             <Card key={map.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${map.resourceId}`)}>
               <Image
-                src={process.env.NEXT_PUBLIC_NGINX_URL + map.resourcePicture}
+                src={map.resourcePicture}
                 alt={map.resourceName}
                 width="368"
                 height="200"
@@ -348,7 +348,7 @@
           {textures.map((texture) => (
             <Card key={texture.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${texture.resourceId}`)}>
               <Image
-                src={process.env.NEXT_PUBLIC_NGINX_URL + texture.resourcePicture}
+                src={texture.resourcePicture}
                 alt={texture.resourceName}
                 width="368"
                 height="200"
@@ -378,7 +378,7 @@
           {modpacks.map((modpack) => (
             <Card key={modpack.resourceId} className="resource-card" onClick={() => router.push(`/resource/${modpack.resourceId}`)}>
               <Image
-                src={process.env.NEXT_PUBLIC_NGINX_URL + modpack.resourcePicture}
+                src={modpack.resourcePicture}
                 alt={modpack.resourceName}
                 width="368"
                 height="200"
diff --git a/src/app/resource/classification/page.tsx b/src/app/resource/classification/page.tsx
index f147ed2..6b41969 100644
--- a/src/app/resource/classification/page.tsx
+++ b/src/app/resource/classification/page.tsx
@@ -61,6 +61,7 @@
   const [selectedGameplay, setSelectedGameplay] = useState<string[]>([]);
   const [selectedVersions, setSelectedVersions] = useState<string[]>([]);
   const [searchValue, setSearchValue] = useState<string>('');
+  
   const debouncedSearch = useRef(
     debounce((value: string) => {
       setSearchValue(value);
@@ -88,8 +89,8 @@
           pageNumber,
           rows,
           classify: selectedClassify,
-          gameplayList: selectedGameplay.join(','),
-          versionList: selectedVersions.join(','),
+          gameplayList: selectedGameplay.join(',') ,
+          gameVersionList: selectedVersions.join(','),
           searchValue
         }
       });
@@ -115,7 +116,7 @@
       <div className="all-resources-list">
         {hotResources.map((hotResource) => (
           <Card key={hotResource.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
-            <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
+            <Image alt="avatar" src={ "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
             <div className="resource-header">
               <div className="resource-content">
                 <h3>{hotResource.resourceName}</h3>
diff --git a/src/app/resource/hot-resource/page.tsx b/src/app/resource/hot-resource/page.tsx
index 4990638..57f1b26 100644
--- a/src/app/resource/hot-resource/page.tsx
+++ b/src/app/resource/hot-resource/page.tsx
@@ -216,7 +216,7 @@
             className="custom-carousel"
             itemTemplate={(hotResource) => (
               <div className="carousel-item" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
-                <Image alt="slide" src={process.env.NEXT_PUBLIC_NGINX_URL + hotResource.resourcePicture} className="carousel-avatar" width="480" height="350" />
+                <Image alt="slide" src={ hotResource.resourcePicture} className="carousel-avatar" width="480" height="350" />
                 <h3>{hotResource.resourceName}</h3>
               </div>
             )}
@@ -238,7 +238,7 @@
               <div className="all-resources-list">
                 {hotResources.map((hotResource) => (
                   <Card key={hotResource.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${hotResource.resourceId}`)}>
-                    <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
+                    <Image alt="avatar" src={ "hotResource/" + hotResource.resourcePicture} className="resource-avatar" width="250" height="140" />
                     <div className="resource-header">
                       <div className="resource-content">
                         <h3>{hotResource.resourceName}</h3>
diff --git "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx" "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
index 5e0a634..baec9a6 100644
--- "a/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
+++ "b/src/app/resource/resource-detail/\133resourceId\135/page.tsx"
@@ -61,7 +61,6 @@
   likes: number;  // 点赞数
   collections: number;   // 收藏数
   comments: number;   // 评论数
-  seeds: number;    // 种子数
   classify: string;  // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
   hot: number;     // 资源热度
   gameplayList: string[];  // 资源标签
@@ -70,7 +69,7 @@
   isLike: boolean;   // 是否被点赞
   isPurchase: boolean;   // 是否被购买
   isUpload: boolean;     // 是否是该用户上传的
-  userId: number;     // 资源上传者的id
+  uploaderId: number;     // 资源上传者的id
 }
 
 // 评论信息
@@ -99,10 +98,10 @@
 // 新评论接口
 interface NewComment {
   userId: number;
-  threadId: number;
-  resourceId: number;
-  rewardId: number;
-  replyId: number;
+  threadId: number | null;
+  resourceId: number | null;
+  rewardId: number | null;
+  replyId: number | null;
   content: string;
   createAt: string;
 }
@@ -131,7 +130,7 @@
   const userId: number = user?.Id ?? -1;
   // 获取URL参数
   const params = useParams<{ resourceId: string }>();
-  const resourceId = decodeURIComponent(params.resourceId); // 防止中文路径乱码
+  const resourceId = Number(decodeURIComponent(params.resourceId)); // 防止中文路径乱码
   // 页面跳转
   const router = useRouter();
 
@@ -198,7 +197,7 @@
         setCollectionCount(response.data.collections);
       }
 
-      setResourceAuthorId(response.data.userId);
+      setResourceAuthorId(response.data.uploaderId);
     } catch (err) {
       console.error('获取资源信息失败', err);
       toast.current?.show({ severity: 'error', summary: 'error', detail: "获取资源信息失败" });
@@ -246,9 +245,9 @@
   }
 
   useEffect(() => {
-    if (!resource?.userId || !subscriberList?.userList) return;
+    if (!resource?.uploaderId || !subscriberList?.userList) return;
 
-    const authorId = resource.userId;
+    const authorId = resource.uploaderId;
     // 设置 isSubscribed 状态
     const subscribed = subscriberList.userList.some(user => user.userId === authorId);
     setIsSubscribed(subscribed);
@@ -257,7 +256,7 @@
   // 若浏览用户与资源作者是同一人,则不显示关注按钮。若不是同一人,则显示按钮
   const handleSubscribe = () => {
     // 资源作者 ID
-    const authorId = resource?.userId;
+    const authorId = resource?.uploaderId;
     // 当前登录用户 ID
     const currentUserId = userId;
 
@@ -340,7 +339,7 @@
   // 判断该资源是否已被购买, 返回不同的购买按钮
   const isPurchase = () => {
     // 作者本人查看资源,不显示购买按钮
-    if (resource?.userId == userId) {
+    if (resource?.uploaderId == userId) {
       return;
     }
 
@@ -405,7 +404,7 @@
       if (newCollectionState) {
         // 收藏操作
         await axios.post(process.env.PUBLIC_URL + `/resource/collection`, {
-          params: { resourceId: resourceId, userId }
+          resourceId: resourceId, userId 
         });
         console.log('收藏资源');
       } else {
@@ -442,7 +441,7 @@
       if (newLikeState) {
         // 点赞操作
         await axios.post(process.env.PUBLIC_URL + `/resource/like`, {
-          params: { resourceId: resourceId, userId }
+          resourceId: resourceId, userId 
         });
         console.log('点赞资源');
       } else {
@@ -488,7 +487,7 @@
   useEffect(() => {
     if (!resource) return;
     // 发帖人
-    axios.get(process.env.PUBLIC_URL + `/user/info?userId=${resource?.userId}`)
+    axios.get(process.env.PUBLIC_URL + `/user/info?userId=${resource?.uploaderId}`)
       .then(res => setUserInfo(res.data))
       .catch(console.error);
   }, [resource]);
@@ -515,7 +514,7 @@
       const pageNumber = first / rows + 1;
       console.log("当前页" + pageNumber + "size" + rows);
       const response = await axios.get<CommentList>(
-        process.env.PUBLIC_URL + `/comments`, {
+        process.env.PUBLIC_URL + `/comment`, {
         params: { id: resourceId, pageNumber, rows, type: 'resource' }
       }
       );
@@ -547,12 +546,12 @@
     try {
       const newComment: NewComment = {
         userId,
-        rewardId: 0,
-        threadId: 0,
+        rewardId: null,
+        threadId: null,
         resourceId: resource.resourceId,
         replyId: commentId,
         content: commentValue,
-        createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+        createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
       };
 
       const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -571,6 +570,26 @@
     }
   };
 
+  const buyResource = async () => {
+    console.log("Buy Resource")
+    try {
+      const response = await axios.post(process.env.PUBLIC_URL + '/resource/purchase', {
+        userId,
+        resourceId
+      });
+
+      if (response.status === 200) {
+        toast.current?.show({ severity: 'success', summary: 'Success', detail: '购买成功' });
+      } else {
+      toast.current?.show({ severity: 'error', summary: 'error', detail: '购买失败' });
+
+      }
+    } catch (error) {
+      console.error('购买失败:', error);
+      toast.current?.show({ severity: 'error', summary: 'error', detail: '购买失败' });
+    }
+  }
+
   // 发布评论接口
   const publishComment = async () => {
     if (!commentValue.trim() || !resource) return;
@@ -578,12 +597,12 @@
     try {
       const newComment: NewComment = {
         userId,
-        rewardId: 0,
-        threadId: 0,
+        rewardId: null,
+        threadId: null,
         resourceId: resource.resourceId,
-        replyId: 0, // 直接评论,不是回复
+        replyId: null, // 直接评论,不是回复
         content: commentValue,
-        createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+        createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
       };
 
       const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -740,12 +759,11 @@
           </div>
 
           <ButtonGroup >
-            {isPurchase()}
             <Button label={"$" + resource?.price} style={{
               height: "44px", background: "rgba(82, 102, 101, 1)",
               borderStyle: "solid", borderWidth: "1px", borderColor: "rgba(82, 102, 101, 1)",
               borderRadius: "0 20px 20px 0", fontSize: "26px",
-            }} disabled={true} />
+            }}  onClick={buyResource} />
           </ButtonGroup>
         </div>
       </div>
@@ -763,7 +781,7 @@
           <Link href="/community" className="no-underline">进入社区</Link>
         </div>
         <div className="comments-input">
-          <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+          <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
           <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
           <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
         </div>
@@ -772,7 +790,7 @@
             <div key={comment.commentId} className="comment-item">
               <div className="comment-user">
                 <Avatar
-                  image={comment.userId ? process.env.NEXT_PUBLIC_NGINX_URL + "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
+                  image={comment.userId ?  "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
                   size="normal"
                   shape="circle"
                 />
@@ -807,7 +825,7 @@
               </OverlayPanel>
               <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
                 <div className="reply-input">
-                  <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                  <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                   <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
                   <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
                 </div>
diff --git a/src/app/reward/page.tsx b/src/app/reward/page.tsx
index b53d93c..77d11a6 100644
--- a/src/app/reward/page.tsx
+++ b/src/app/reward/page.tsx
@@ -1,268 +1,392 @@
-'use client';
+"use client";
 
 import React, { useEffect, useState, useRef } from "react";
-import { InputText } from 'primereact/inputtext';
-import { Button } from 'primereact/button';
-import { Card } from 'primereact/card';
-import { Image } from 'primereact/image';
+import { InputText } from "primereact/inputtext";
+import { Button } from "primereact/button";
+import { Card } from "primereact/card";
+import { Image } from "primereact/image";
 // 页面跳转
-import { useRouter } from 'next/navigation';
+import { useRouter } from "next/navigation";
 // 分页
-import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
+import { Paginator, type PaginatorPageChangeEvent } from "primereact/paginator";
 // 消息提醒
-import { Toast } from 'primereact/toast';
+import { Toast } from "primereact/toast";
 // 发布帖子
-import { Dialog } from 'primereact/dialog';
-import { FileUpload } from 'primereact/fileupload';
-import { InputTextarea } from 'primereact/inputtextarea';
+import { Dialog } from "primereact/dialog";
+import { FileUpload } from "primereact/fileupload";
+import { InputTextarea } from "primereact/inputtextarea";
 // 接口传输
-import axios from 'axios';
+import axios from "axios";
 // 防抖函数
-import { debounce } from 'lodash';
-import { TabView, TabPanel } from 'primereact/tabview';
-import { useLocalStorage } from '../hook/useLocalStorage';
+import { debounce } from "lodash";
+import { TabView, TabPanel } from "primereact/tabview";
+import { useLocalStorage } from "../hook/useLocalStorage";
 // 样式
-import './reward.scss';
+import "./reward.scss";
 interface User {
-    Id: number;
+  Id: number;
 }
 // 悬赏列表数据
 interface Reward {
-    rewardId: number;
-    userId: number;
-    rewardPicture: string;
-    rewardName: string;
-    createAt: string;
-    rewardDescription: string;
-    price: number;
+  rewardId: number;
+  userId: number;
+  rewardPicture: string;
+  rewardName: string;
+  createAt: string;
+  rewardDescription: string;
+  price: number;
 }
 interface RewardList {
-    total: number; // 总记录数
-    records: Reward[];
+  total: number; // 总记录数
+  records: Reward[];
 }
 
-
 // 社区详情页面
 export default function RewardDetailPage() {
-    const user = useLocalStorage<User>('user');
-    const userId: number = user?.Id ?? -1;
-    // 页面跳转
-    const router = useRouter();
-    // 帖子列表数据
-    const [rewards, setRewards] = useState<Reward[]>([]);
-    const [totalRewards, setTotalRewards] = useState<number>(0);
-    const [activeOption, setActiveOption] = useState<number>(0); // 0表示"赏金最高",1表示"最新发布"
-    const options = ["赏金最高", "最新发布"];
-    // 搜索框
-    const [searchValue, setSearchValue] = useState("");
-    const debouncedSearch = useRef(
-        debounce((value: string) => {
-            setSearchValue(value);
-        }, 600)
-    ).current;
-    // 消息提醒
-    const toast = useRef<Toast>(null);
-    // 分页
-    const [first, setFirst] = useState(0);
-    const [rows, setRows] = useState(5);
-    const onPageChange = (event: PaginatorPageChangeEvent) => {
-        setFirst(event.first);
-        setRows(event.rows);
-    };
+  const user = useLocalStorage<User>("user");
+  const userId: number = user?.Id ?? -1;
+  // 页面跳转
+  const router = useRouter();
+  // 帖子列表数据
+  const [rewards, setRewards] = useState<Reward[]>([]);
+  const [totalRewards, setTotalRewards] = useState<number>(0);
+  const [activeOption, setActiveOption] = useState<number>(0); // 0表示"赏金最高",1表示"最新发布"
+  const options = ["赏金最高", "最新发布"];
+  // 搜索框
+  const [searchValue, setSearchValue] = useState("");
+  const debouncedSearch = useRef(
+    debounce((value: string) => {
+      setSearchValue(value);
+    }, 600)
+  ).current;
+  // 消息提醒
+  const toast = useRef<Toast>(null);
+  // 分页
+  const [first, setFirst] = useState(0);
+  const [rows, setRows] = useState(5);
+  const onPageChange = (event: PaginatorPageChangeEvent) => {
+    setFirst(event.first);
+    setRows(event.rows);
+  };
 
-    // 获取悬赏列表
-    useEffect(() => {
+  // 获取悬赏列表
+  useEffect(() => {
+    fetchRewards();
+  }, [first, rows, searchValue, activeOption]);
+
+  const fetchRewards = async () => {
+    try {
+      const pageNumber = first / rows + 1;
+      console.log(
+        "当前页" +
+          pageNumber +
+          "size" +
+          rows +
+          "搜索内容" +
+          searchValue +
+          "排序方式" +
+          activeOption
+      );
+      const response = await axios.get<RewardList>(
+        process.env.PUBLIC_URL + `/reward`,
+        {
+          params: {
+            pageNumber,
+            rows,
+            searchValue,
+            option: options[activeOption],
+          },
+        }
+      );
+      console.log("获取悬赏列表:", response.data.records);
+      setRewards(response.data.records);
+      setTotalRewards(response.data.total); // 假设返回的总数
+    } catch (err) {
+      console.error("获取悬赏失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取悬赏失败",
+      });
+    }
+  };
+
+  // 发布悬赏弹窗
+  const [visible, setVisible] = useState(false);
+  const [formData, setFormData] = useState({
+    rewardName: "",
+    rewardDescription: "",
+    rewardPicture: "",
+    price: "",
+  });
+
+  // 发布悬赏接口
+  const handleSubmit = async () => {
+    try {
+      const currentDate = new Date().toISOString();
+      const postData = {
+        userId, // 记得用户登录状态获取
+        rewardPicture: formData.rewardPicture,
+        rewardName: formData.rewardName,
+        rewardDescription: formData.rewardDescription,
+        createAt: currentDate.slice(0, 10),
+        lastUpdateAt: currentDate.slice(0, 10),
+        price: Number(formData.price),
+      };
+      // 发送POST请求
+      const response = await axios.post(
+        process.env.PUBLIC_URL + "/reward",
+        postData
+      );
+
+      if (response.status === 200) {
+        toast.current?.show({
+          severity: "success",
+          summary: "Success",
+          detail: "悬赏发布成功",
+        });
+        // 发帖成功
+        setVisible(false);
+        // 重置表单
+        setFormData({
+          rewardName: "",
+          rewardDescription: "",
+          rewardPicture: "",
+          price: "",
+        });
+        // 可以刷新帖子列表
         fetchRewards();
-    }, [first, rows, searchValue, activeOption]);
-
-    const fetchRewards = async () => {
-        try {
-            const pageNumber = first / rows + 1;
-            console.log("当前页" + pageNumber + "size" + rows + "搜索内容" + searchValue + "排序方式" + activeOption);
-            const response = await axios.get<RewardList>(
-                process.env.PUBLIC_URL + `/reward`, {
-                params: { pageNumber, rows, searchValue, option: options[activeOption] }
-            }
-            );
-            console.log('获取悬赏列表:', response.data.records);
-            setRewards(response.data.records);
-            setTotalRewards(response.data.total); // 假设返回的总数
-        } catch (err) {
-            console.error('获取悬赏失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取悬赏失败' });
-        }
-    };
-
-    // 发布悬赏弹窗
-    const [visible, setVisible] = useState(false);
-    const [formData, setFormData] = useState({
-        rewardName: '',
-        rewardDescription: '',
-        rewardPicture: '',
-        price: ''
-    });
-    // 图片上传消息通知
-    const onUpload = () => {
-        toast.current?.show({ severity: 'info', summary: 'Success', detail: 'File Uploaded' });
-    };
-
-    // 发布悬赏接口
-    const handleSubmit = async () => {
-        try {
-            const currentDate = new Date().toISOString();
-            const postData = {
-                userId, // 记得用户登录状态获取
-                rewardPicture: formData.rewardPicture,
-                rewardName: formData.rewardName,
-                rewardDescription: formData.rewardDescription,
-                createdAt: currentDate,
-                price: formData.price
-            };
-            // 发送POST请求
-            const response = await axios.post(process.env.PUBLIC_URL + '/reward', postData);
-
-            if (response.status === 200) {
-                toast.current?.show({ severity: 'success', summary: 'Success', detail: '悬赏发布成功' });
-                // 发帖成功
-                setVisible(false);
-                // 重置表单
-                setFormData({
-                    rewardName: '',
-                    rewardDescription: '',
-                    rewardPicture: '',
-                    price: ''
-                });
-                // 可以刷新帖子列表
-                fetchRewards();
-            }
-        } catch (error) {
-            console.error('发布悬赏失败:', error);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '悬赏发布失败' });
-        }
-    };
-    return (
-        <div className="reward">
-            <Toast ref={toast}></Toast>
-            {/* 悬赏标题和介绍 */}
-            <div className="reward-header">
-                <div className="title-section">
-                    <h1>悬赏排行</h1>
-                </div>
-                <div className="input">
-                    <div className="searchBar">
-                        <i className="pi pi-search" />
-                        <InputText type="search" className="search-helper" placeholder="搜索你的目标悬赏" onChange={(e) => { const target = e.target as HTMLInputElement; debouncedSearch(target.value); }} />
-                    </div>
-                    <div className="reward-buttons">
-                        <Button label="我的悬赏" onClick={() => router.push(`/user/悬赏`)} />
-                        <Button label="发布悬赏" onClick={() => setVisible(true)} />
-                    </div>
-                </div>
-            </div>
-
-            {/* 悬赏列表 */}
-            <TabView activeIndex={activeOption} onTabChange={(e) => setActiveOption(e.index)}>
-                <TabPanel header={options[0]} >
-                    <div className="rewards-list">
-                        {rewards.map((reward) => (
-                            <Card key={reward.rewardId} className="rewards-list-card" onClick={() => router.push(`/reward/reward-detail/${reward.rewardId}`)}>
-                                <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + reward.rewardPicture} className="reward-avatar" width="250" height="140" />
-                                <div className="reward-header">
-                                    <div className="reward-content">
-                                        <h3>{reward.rewardName}</h3>
-                                    </div>
-                                    <div className="reward-states">
-                                        <span className="price">$: {reward.price}</span>
-                                        <Button label="提交悬赏" />
-                                    </div>
-                                </div>
-                            </Card>
-                        ))}
-                        {totalRewards > 5 && <Paginator className="Paginator" first={first} rows={rows} totalRecords={totalRewards} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />}
-                    </div>
-                </TabPanel>
-                <TabPanel header={options[1]}>
-                    <div className="rewards-list">
-                        {rewards.map((reward) => (
-                            <Card key={reward.rewardId} className="rewards-list-card" onClick={() => router.push(`/reward/reward-detail/${reward.rewardId}`)}>
-                                <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + reward.rewardPicture} className="reward-avatar" width="250" height="140" />
-                                <div className="reward-header">
-                                    <div className="reward-content">
-                                        <h3>{reward.rewardName}</h3>
-                                    </div>
-                                    <div className="reward-states">
-                                        <span className="price">$: {reward.price}</span>
-                                        <Button label="提交悬赏" />
-                                    </div>
-                                </div>
-                            </Card>
-                        ))}
-                        {totalRewards > 5 && <Paginator className="Paginator" first={first} rows={rows} totalRecords={totalRewards} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />}
-                    </div>
-                </TabPanel>
-            </TabView>
-            {/* 发布悬赏弹窗 */}
-            <Dialog
-                header="发布新悬赏"
-                visible={visible}
-                onHide={() => setVisible(false)}
-                className="publish-dialog"
-                modal
-                footer={
-                    <div className="dialog-footer">
-                        <Button label="发布" icon="pi pi-check" onClick={handleSubmit} autoFocus />
-                        <Button label="取消" icon="pi pi-times" onClick={() => setVisible(false)} className="p-button-text" />
-                    </div>
-                }
-            >
-                <div className="publish-form">
-                    <div className="form-field">
-                        <label htmlFor="title">标题</label>
-                        <InputText
-                            id="title"
-                            value={formData.rewardName}
-                            onChange={(e) => setFormData(prev => ({ ...prev, title: e.target.value }))}
-                            placeholder="请输入悬赏标题"
-                            className="w-full"
-                        />
-                    </div>
-
-                    <div className="form-field">
-                        <label htmlFor="content">内容</label>
-                        <InputTextarea
-                            id="content"
-                            value={formData.rewardDescription}
-                            onChange={(e) => setFormData(prev => ({ ...prev, content: e.target.value }))}
-                            rows={5}
-                            placeholder="请输入悬赏需求"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <label htmlFor="price">赏金</label>
-                        <InputText
-                            id="price"
-                            value={formData.price}
-                            onChange={(e) => setFormData(prev => ({ ...prev, price: e.target.value }))}
-                            placeholder="请输入赏金金额"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <label>封面图片</label>
-                        <FileUpload
-                            mode="basic"
-                            name="thread-image"
-                            url={process.env.PUBLIC_URL + "/file"} // 与后端交互的URL
-                            accept="image/*"
-                            maxFileSize={10000000000}
-                            chooseLabel="选择悬赏封面"
-                            className="w-full"
-                            onUpload={onUpload}
-                        />
-                    </div>
-                </div>
-            </Dialog>
+      }
+    } catch (error) {
+      console.error("发布悬赏失败:", error);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "悬赏发布失败",
+      });
+    }
+  };
+  return (
+    <div className="reward">
+      <Toast ref={toast}></Toast>
+      {/* 悬赏标题和介绍 */}
+      <div className="reward-header">
+        <div className="title-section">
+          <h1>悬赏排行</h1>
         </div>
-    );
-}
\ No newline at end of file
+        <div className="input">
+          <div className="searchBar">
+            <i className="pi pi-search" />
+            <InputText
+              type="search"
+              className="search-helper"
+              placeholder="搜索你的目标悬赏"
+              onChange={(e) => {
+                const target = e.target as HTMLInputElement;
+                debouncedSearch(target.value);
+              }}
+            />
+          </div>
+          <div className="reward-buttons">
+            <Button
+              label="我的悬赏"
+              onClick={() => router.push(`/user/悬赏`)}
+            />
+            <Button label="发布悬赏" onClick={() => setVisible(true)} />
+          </div>
+        </div>
+      </div>
+
+      {/* 悬赏列表 */}
+      <TabView
+        activeIndex={activeOption}
+        onTabChange={(e) => setActiveOption(e.index)}
+      >
+        <TabPanel header={options[0]}>
+          <div className="rewards-list">
+            {rewards.map((reward) => (
+              <Card
+                key={reward.rewardId}
+                className="rewards-list-card"
+                onClick={() =>
+                  router.push(`/reward/reward-detail/${reward.rewardId}`)
+                }
+              >
+                <Image
+                  alt="avatar"
+                  src={reward.rewardPicture}
+                  className="reward-avatar"
+                  width="250"
+                  height="140"
+                />
+                <div className="reward-header">
+                  <div className="reward-content">
+                    <h3>{reward.rewardName}</h3>
+                  </div>
+                  <div className="reward-states">
+                    <span className="price">$: {reward.price}</span>
+                    <Button label="提交悬赏" />
+                  </div>
+                </div>
+              </Card>
+            ))}
+            {totalRewards > 5 && (
+              <Paginator
+                className="Paginator"
+                first={first}
+                rows={rows}
+                totalRecords={totalRewards}
+                rowsPerPageOptions={[5, 10]}
+                onPageChange={onPageChange}
+              />
+            )}
+          </div>
+        </TabPanel>
+        <TabPanel header={options[1]}>
+          <div className="rewards-list">
+            {rewards.map((reward) => (
+              <Card
+                key={reward.rewardId}
+                className="rewards-list-card"
+                onClick={() =>
+                  router.push(`/reward/reward-detail/${reward.rewardId}`)
+                }
+              >
+                <Image
+                  alt="avatar"
+                  src={reward.rewardPicture}
+                  className="reward-avatar"
+                  width="250"
+                  height="140"
+                />
+                <div className="reward-header">
+                  <div className="reward-content">
+                    <h3>{reward.rewardName}</h3>
+                  </div>
+                  <div className="reward-states">
+                    <span className="price">$: {reward.price}</span>
+                    <Button label="提交悬赏" />
+                  </div>
+                </div>
+              </Card>
+            ))}
+            {totalRewards > 5 && (
+              <Paginator
+                className="Paginator"
+                first={first}
+                rows={rows}
+                totalRecords={totalRewards}
+                rowsPerPageOptions={[5, 10]}
+                onPageChange={onPageChange}
+              />
+            )}
+          </div>
+        </TabPanel>
+      </TabView>
+      {/* 发布悬赏弹窗 */}
+      <Dialog
+        header="发布新悬赏"
+        visible={visible}
+        onHide={() => setVisible(false)}
+        className="publish-dialog"
+        modal
+        footer={
+          <div className="dialog-footer">
+            <Button
+              label="发布"
+              icon="pi pi-check"
+              onClick={handleSubmit}
+              autoFocus
+            />
+            <Button
+              label="取消"
+              icon="pi pi-times"
+              onClick={() => setVisible(false)}
+              className="p-button-text"
+            />
+          </div>
+        }
+      >
+        <div className="publish-form">
+          <div className="form-field">
+            <label htmlFor="title">标题</label>
+            <InputText
+              id="title"
+              value={formData.rewardName}
+              onChange={(e) =>
+                setFormData((prev) => ({ ...prev, rewardName: e.target.value }))
+              }
+              placeholder="请输入悬赏标题"
+              className="w-full"
+            />
+          </div>
+
+          <div className="form-field">
+            <label htmlFor="content">内容</label>
+            <InputTextarea
+              id="content"
+              value={formData.rewardDescription}
+              onChange={(e) =>
+                setFormData((prev) => ({
+                  ...prev,
+                  rewardDescription: e.target.value,
+                }))
+              }
+              rows={5}
+              placeholder="请输入悬赏需求"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <label htmlFor="price">赏金</label>
+            <InputText
+              id="price"
+              value={formData.price}
+              onChange={(e) =>
+                setFormData((prev) => ({ ...prev, price: e.target.value }))
+              }
+              placeholder="请输入赏金金额"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <label>封面图片</label>
+            <FileUpload
+              mode="advanced"
+              name="file"
+              customUpload
+              uploadHandler={async (e) => {
+                const formData = new FormData();
+                formData.append("file", e.files[0]);
+
+                try {
+                  const res = await axios.post(
+                    `${process.env.PUBLIC_URL}/file`,
+                    formData
+                  );
+
+                  const fileUrl = res.data;
+                  console.log(fileUrl);
+                  setFormData((prev) => ({ ...prev, rewardPicture: fileUrl }));
+                  toast.current?.show({
+                    severity: "success",
+                    summary: "上传成功",
+                  });
+                } catch (error) {
+                  console.log(error);
+                  toast.current?.show({
+                    severity: "error",
+                    summary: "上传失败",
+                  });
+                }
+              }}
+              auto
+              accept="image/*"
+              chooseLabel="上传帖子封面"
+            />
+          </div>
+        </div>
+      </Dialog>
+    </div>
+  );
+}
diff --git "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx" "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
index 0ba1a04..b6c60d4 100644
--- "a/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
+++ "b/src/app/reward/reward-detail/\133rewardId\135/page.tsx"
@@ -61,10 +61,10 @@
 // 新评论接口
 interface NewComment {
     userId: number;
-    threadId: number;
-    resourceId: number;
-    rewardId: number;
-    replyId: number;
+    threadId: number | null;
+    resourceId: number | null;
+    rewardId: number | null;
+    replyId: number | null;
     content: string;
     createAt: string;
 }
@@ -150,7 +150,7 @@
             const pageNumber = first / rows + 1;
             console.log("当前页" + pageNumber + "size" + rows);
             const response = await axios.get<CommentList>(
-                process.env.PUBLIC_URL + `/comments`, {
+                process.env.PUBLIC_URL + `/comment`, {
                 params: { id: rewardId, pageNumber, rows, type: 'reward' }
             }
             );
@@ -182,11 +182,11 @@
             const newComment: NewComment = {
                 userId,
                 rewardId: rewardInfo.rewardId,
-                threadId: 0,
-                resourceId: 0,
+                threadId: null,
+                resourceId: null,
                 replyId: commentId,
                 content: commentValue,
-                createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+                createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
             };
 
             const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -213,11 +213,11 @@
             const newComment: NewComment = {
                 userId,
                 rewardId: rewardInfo.rewardId,
-                threadId: 0,
-                resourceId: 0,
-                replyId: 0, // 直接评论,不是回复
+                threadId: null,
+                resourceId: null,
+                replyId: null, // 直接评论,不是回复
                 content: commentValue,
-                createAt: new Date().toISOString().slice(0, 19).replace('T', ' ')
+                createAt: new Date().toISOString().slice(0, 10).replace('T', ' ')
             };
 
             const response = await axios.post(process.env.PUBLIC_URL + '/comment', newComment);
@@ -276,7 +276,7 @@
             <div className="reward-content">
                 <div className="reward-info-container">
                     <div className="user-info">
-                        <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                        <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                         <div className="user-meta">
                             <h3>{userInfo.username}</h3>
                             <span>{userInfo.signature}</span>
@@ -293,7 +293,7 @@
                 {/* 右侧图片+价格+按钮 */}
                 <div className="reward-media">
                     <Image
-                        src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + rewardInfo.rewardPicture}
+                        src={ rewardInfo.rewardPicture}
                         alt={rewardInfo.rewardName}
                         width="500"
                         height="400"
@@ -310,7 +310,7 @@
                     <h2>评论 ({totalComments})</h2>
                 </div>
                 <div className="comments-input">
-                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                     <InputText value={commentValue} placeholder="发布你的评论" onChange={(e) => setCommentValue(e.target.value)} />
                     <Button label="发布评论" onClick={publishComment} disabled={!commentValue.trim()} />
                 </div>
@@ -319,7 +319,7 @@
                         <div key={comment.commentId} className="comment-item">
                             <div className="comment-user">
                                 <Avatar
-                                    image={comment.userId ? process.env.NEXT_PUBLIC_NGINX_URL + "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
+                                    image={comment.userId ?  "users/" + commentUserInfos.get(comment.userId)?.avatar : '/default-avatar.png'}
                                     size="normal"
                                     shape="circle"
                                 />
@@ -354,7 +354,7 @@
                             </OverlayPanel>
                             <Sidebar className='reply' header={ReplyHeader} visible={visibleReply} position="bottom" onHide={() => setVisibleReply(false)}>
                                 <div className="reply-input">
-                                    <Avatar image={process.env.NEXT_PUBLIC_NGINX_URL + "users/" + userInfo.avatar} size="large" shape="circle" />
+                                    <Avatar image={ "users/" + userInfo.avatar} size="large" shape="circle" />
                                     <InputText value={replyValue} placeholder="发布你的评论" onChange={(e) => setReplyValue(e.target.value)} />
                                     <Button label="发布评论" onClick={() => publishReply(comment.commentId)} disabled={!replyValue.trim()} />
                                 </div>
diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx
index 5f6642b..65d2465 100644
--- a/src/app/search/page.tsx
+++ b/src/app/search/page.tsx
@@ -81,7 +81,7 @@
           <Card key={item.resourceId} className="all-resources-card" onClick={() => router.push(`/resource/resource-detail/${item.resourceId}`)}>
             {/* 左侧图片 */}
             <Image
-              src={process.env.NEXT_PUBLIC_NGINX_URL + item.resourcePicture}
+              src={ item.resourcePicture}
               alt={item.resourceName}
               width="250" height="140"
               preview
diff --git a/src/app/user/component/userAvatar.tsx b/src/app/user/component/userAvatar.tsx
index ba164de..abc1b66 100644
--- a/src/app/user/component/userAvatar.tsx
+++ b/src/app/user/component/userAvatar.tsx
@@ -1,111 +1,159 @@
-'use client';
+"use client";
 
-import { useRef, useState } from 'react';
-import { Avatar } from 'primereact/avatar';
-import { Button } from 'primereact/button';
+import { useRef, useState } from "react";
+import { Avatar } from "primereact/avatar";
+import { Button } from "primereact/button";
 // 弹窗
-import { Dialog } from 'primereact/dialog';
+import { Dialog } from "primereact/dialog";
 // 头像下拉框
-import { OverlayPanel } from 'primereact/overlaypanel';
+import { OverlayPanel } from "primereact/overlaypanel";
 // 输入框
 import { FloatLabel } from "primereact/floatlabel";
-import { InputText } from 'primereact/inputtext';
+import { InputText } from "primereact/inputtext";
 // 页面跳转
-import Link from 'next/link';
+import Link from "next/link";
 // 文件上传
-import { FileUpload } from 'primereact/fileupload';
+import { FileUpload } from "primereact/fileupload";
 // 通知
-import { Toast } from 'primereact/toast';
+import { Toast } from "primereact/toast";
 // 接口传输
-import axios from 'axios';
-import { useLocalStorage } from '../../hook/useLocalStorage';
+import axios from "axios";
+import { useLocalStorage } from "../../hook/useLocalStorage";
 // 样式
-import './user-avatar.scss';
+import "./user-avatar.scss";
+
 interface User {
-    Id: number;
+  Id: number;
+  Avatar: string,
 }
+
 // 用户下拉框
 export default function UserAvatar() {
-    const user = useLocalStorage<User>('user');
-    const userId: number = user?.Id ?? -1;
+  const user = useLocalStorage<User>("user");
+  const userId: number = user?.Id ?? -1;
+  // 功能选项
+  const op = useRef<OverlayPanel>(null);
+  let hoverTimeout: NodeJS.Timeout;
+  // 通知
+  const toast = useRef<Toast>(null);
+  // 控制三个弹窗可见性
+  const [showEditSignature, setShowEditSignature] = useState(false);
+  const [showEditAvatar, setShowEditAvatar] = useState(false);
+  const [showEditPassword, setShowEditPassword] = useState(false);
+  // 头像URL
+  const [avatarUrl, setAvatar] = useState<string>("");
+  // 签名
+  const [signValue, setSignValue] = useState<string>("");
+  // 新密码
+  const [passwardValue, setPasswardValue] = useState<string>("");
+  const [newPasswardValue, setNewPasswardValue] = useState<string>("");
+  // 老密码
+  const [oldPasswardValue, setOldPasswardValue] = useState<string>("");
 
-    // 功能选项
-    const op = useRef<OverlayPanel>(null);
-    let hoverTimeout: NodeJS.Timeout;
-    // 通知
-    const toast = useRef<Toast>(null);
-    // 控制三个弹窗可见性
-    const [showEditSignature, setShowEditSignature] = useState(false);
-    const [showEditAvatar, setShowEditAvatar] = useState(false);
-    const [showEditPassword, setShowEditPassword] = useState(false);
-    // 头像URL
-    const [avatarUrl, setAvatar] = useState<string>('');
-    // 签名
-    const [signValue, setSignValue] = useState<string>('');
-    // 新密码
-    const [passwardValue, setPasswardValue] = useState<string>('');
-    const [newPasswardValue, setNewPasswardValue] = useState<string>('');
-    // 老密码
-    const [oldPasswardValue, setOldPasswardValue] = useState<string>('');
+  const handleMouseEnter = (event: React.MouseEvent) => {
+    clearTimeout(hoverTimeout);
+    op.current?.show(event, event.currentTarget);
+  };
 
+  const handleMouseLeave = () => {
+    hoverTimeout = setTimeout(() => {
+      op.current?.hide();
+    }, 300);
+  };
 
-    const handleMouseEnter = (event: React.MouseEvent) => {
-        clearTimeout(hoverTimeout);
-        op.current?.show(event, event.currentTarget);
-    };
-
-    const handleMouseLeave = () => {
-        hoverTimeout = setTimeout(() => {
-            op.current?.hide();
-        }, 300);
-    };
-
-
-    // 修改密码接口
-    const editPassward = async () => {
-        try {
-            await axios.put(process.env.PUBLIC_URL + `/user/password`, {
-                params: { userId, password: oldPasswardValue, newPassword: passwardValue }
-            });
-            toast.current?.show({ severity: 'success', summary: 'success', detail: '修改密码成功' });
-            setShowEditPassword(false);
-        } catch (err) {
-            console.error('修改密码失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '修改密码失败' });
-        }
+  // 修改密码接口
+  const editPassward = async () => {
+    try {
+      await axios.put(process.env.PUBLIC_URL + `/user/password`, {
+        body: {
+          userId,
+          password: oldPasswardValue,
+          newPassword: passwardValue,
+        },
+      });
+      toast.current?.show({
+        severity: "success",
+        summary: "success",
+        detail: "修改密码成功",
+      });
+      setShowEditPassword(false);
+    } catch (err) {
+      console.error("修改密码失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "修改密码失败",
+      });
     }
-    // 修改签名接口
-    const editSign = async () => {
-        try {
-            await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
-                params: { userId, signature: signValue }
-            });
-            toast.current?.show({ severity: 'success', summary: 'success', detail: '修改签名成功' });
-            setShowEditSignature(false);
-        } catch (err) {
-            console.error('修改签名失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '修改签名失败' });
-        }
-    }
+  };
 
-    // 修改头像接口
-    const editAvatar = async () => {
-        try {
-            await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
-                params: { userId, avatar: avatarUrl }
-            });
-            toast.current?.show({ severity: 'success', summary: 'success', detail: '修改头像成功' });
-            setShowEditAvatar(false);
-        } catch (err) {
-            console.error('修改头像失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '修改头像失败' });
-        }
+  // 修改签名接口
+  const editSign = async () => {
+    try {
+      await axios.put(process.env.PUBLIC_URL + `/user/signature`, {
+        params: { userId, signature: signValue },
+      });
+      toast.current?.show({
+        severity: "success",
+        summary: "success",
+        detail: "修改签名成功",
+      });
+      setShowEditSignature(false);
+    } catch (err) {
+      console.error("修改签名失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "修改签名失败",
+      });
     }
-    return (
+  };
+
+  // 修改头像接口
+  const editAvatar = async () => {
+    try {
+      await axios.put(process.env.PUBLIC_URL + `/user/avatar`, {
+        userId,
+        avatar: avatarUrl,
+      });
+      toast.current?.show({
+        severity: "success",
+        summary: "success",
+        detail: "修改头像成功",
+      });
+      setAvatar(avatarUrl);
+      setShowEditAvatar(false);
+      localStorage.setItem("user", JSON.stringify({...user, Avatar: avatarUrl}))
+    } catch (err) {
+      console.error("修改头像失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "修改头像失败",
+      });
+    }
+  };
+  return (
+    <div
+      onMouseEnter={handleMouseEnter}
+      onMouseLeave={handleMouseLeave}
+      className="user-avatar-wrapper"
+    >
+      <Toast ref={toast}></Toast>
+      <Link href="/user" className="no-underline">
+        <Avatar
+          image={useLocalStorage<User>("user")?.Avatar}
+          size="large"
+          shape="circle"
+          className="user-avatar-link"
+        />
+      </Link>
+
+      <OverlayPanel ref={op} dismissable={false}>
         <div
-            onMouseEnter={handleMouseEnter}
-            onMouseLeave={handleMouseLeave}
-            className="user-avatar-wrapper"
+          onMouseEnter={() => clearTimeout(hoverTimeout)}
+          onMouseLeave={handleMouseLeave}
+          className="user-overlay-panel"
         >
             <Toast ref={toast}></Toast>
             <Link href="/user" className="no-underline">
@@ -199,7 +247,7 @@
                             try {
                                 const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
 
-                                const fileUrl = res.data.url;
+                                const fileUrl = res.data;
                                 console.log(fileUrl);
                                 setAvatar(fileUrl);
                                 toast.current?.show({ severity: 'success', summary: '上传成功' });
@@ -283,6 +331,179 @@
                 </div>
             </Dialog>
         </div>
-    );
+      </OverlayPanel>
 
+      {/* 修改签名弹窗 */}
+      <Dialog
+        header="修改签名"
+        visible={showEditSignature}
+        style={{ width: "30vw" }}
+        onHide={() => {
+          setSignValue("");
+          setShowEditSignature(false);
+        }}
+        modal
+      >
+        <div className="dialog-container">
+          <div className="dialog-input-group">
+            <FloatLabel>
+              <InputText
+                id="username"
+                value={signValue}
+                onChange={(e) => setSignValue(e.target.value)}
+              />
+              <label htmlFor="username">个性签名</label>
+            </FloatLabel>
+          </div>
+          <div className="dialog-button-group">
+            <Button
+              label="确定"
+              className="p-button-sm"
+              onClick={() => editSign()}
+            />
+            <Button
+              label="取消"
+              className="p-button-secondary p-button-sm"
+              onClick={() => {
+                setSignValue("");
+                setShowEditSignature(false);
+              }}
+            />
+          </div>
+        </div>
+      </Dialog>
+
+      {/* 修改头像弹窗 */}
+      <Dialog
+        header="修改头像"
+        visible={showEditAvatar}
+        style={{ display: "flex", flexDirection: "column", width: "30vw" }}
+        onHide={() => {
+          setAvatar("");
+          setShowEditAvatar(false);
+        }}
+        modal
+      >
+        <div className="dialog-container">
+          <FileUpload
+            mode="advanced"
+            name="file"
+            customUpload
+            uploadHandler={async (e) => {
+              const formData = new FormData();
+              formData.append("file", e.files[0]);
+
+              try {
+                const res = await axios.post(
+                  `${process.env.PUBLIC_URL}/file`,
+                  formData
+                );
+                const fileUrl = res.data;
+                console.log(fileUrl);
+                setAvatar(fileUrl);
+                toast.current?.show({
+                  severity: "success",
+                  summary: "上传成功",
+                });
+              } catch (error) {
+                console.log(error);
+                toast.current?.show({ severity: "error", summary: "上传失败" });
+              }
+            }}
+            auto
+            accept="image/*"
+            chooseLabel="上传头像"
+          />
+
+          <div className="dialog-button-group">
+            <Button
+              label="确定"
+              className="p-button-sm"
+              onClick={() => editAvatar()}
+            />
+            <Button
+              label="取消"
+              className="p-button-secondary p-button-sm"
+              onClick={() => setShowEditAvatar(false)}
+            />
+          </div>
+        </div>
+      </Dialog>
+
+      {/* 修改密码弹窗 */}
+      <Dialog
+        header="修改密码"
+        visible={showEditPassword}
+        style={{ width: "30vw" }}
+        onHide={() => {
+          setOldPasswardValue("");
+          setPasswardValue("");
+          setNewPasswardValue("");
+          setShowEditPassword(false);
+        }}
+        modal
+      >
+        <div className="dialog-container">
+          <div className="dialog-input-group">
+            <FloatLabel>
+              <InputText
+                id="username"
+                value={oldPasswardValue}
+                onChange={(e) => setOldPasswardValue(e.target.value)}
+              />
+              <label htmlFor="username">输入旧密码</label>
+            </FloatLabel>
+          </div>
+          <div className="dialog-input-group">
+            <FloatLabel>
+              <InputText
+                id="username"
+                value={passwardValue}
+                onChange={(e) => setPasswardValue(e.target.value)}
+              />
+              <label htmlFor="username">更新密码</label>
+            </FloatLabel>
+          </div>
+          <div className="dialog-input-group">
+            <FloatLabel>
+              <InputText
+                id="username"
+                value={newPasswardValue}
+                onChange={(e) => setNewPasswardValue(e.target.value)}
+              />
+              <label htmlFor="username">确认密码</label>
+            </FloatLabel>
+          </div>
+          <div className="dialog-button-group">
+            <Button
+              label="确定"
+              className="p-button-sm"
+              onClick={() => {
+                if (passwardValue !== newPasswardValue) {
+                  toast.current?.show({
+                    severity: "warn",
+                    summary: "两次密码不一致",
+                    detail: "请确保新密码和确认密码一致",
+                  });
+                  return;
+                } else {
+                  editPassward();
+                }
+              }}
+            />
+            <Button
+              label="取消"
+              className="p-button-secondary p-button-sm"
+              onClick={() => {
+                setOldPasswardValue("");
+                setPasswardValue("");
+                setNewPasswardValue("");
+                setShowEditPassword(false);
+              }}
+            />
+          </div>
+        </div>
+      </Dialog>
+    </div>
+  );
 }
diff --git a/src/app/user/manage/resources/page.tsx b/src/app/user/manage/resources/page.tsx
index 4d0d03f..0bfa184 100644
--- a/src/app/user/manage/resources/page.tsx
+++ b/src/app/user/manage/resources/page.tsx
@@ -195,7 +195,7 @@
                     <Card key={resourceList.resourceId} className="resources-list-card"
                         onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
                         <Image alt="avatar"
-                            src={process.env.NEXT_PUBLIC_NGINX_URL + "resource/" + resourceList.resourcePicture}
+                            src={ "resource/" + resourceList.resourcePicture}
                             className="resource-avatar" width="250" height="140" />
                         <div className="resource-header">
                             <div className="resource-content">
diff --git a/src/app/user/page.tsx b/src/app/user/page.tsx
index d534cd5..0402059 100644
--- a/src/app/user/page.tsx
+++ b/src/app/user/page.tsx
@@ -1,1076 +1,1382 @@
-'use client';
+"use client";
 
-import React, { useEffect, useState, useRef } from 'react';
-import { TabView, TabPanel } from 'primereact/tabview';
-import { Avatar } from 'primereact/avatar';
-import { Button } from 'primereact/button';
-import { Card } from 'primereact/card';
+import React, { useEffect, useState, useRef } from "react";
+import { TabView, TabPanel } from "primereact/tabview";
+import { Avatar } from "primereact/avatar";
+import { Button } from "primereact/button";
+import { Card } from "primereact/card";
 import { Image } from "primereact/image";
 // 发布资源
-import { Dialog } from 'primereact/dialog';
+import { Dialog } from "primereact/dialog";
 import { InputText } from "primereact/inputtext";
 import { InputTextarea } from "primereact/inputtextarea";
 import { FileUpload } from "primereact/fileupload";
 // 资源分类
 import { RadioButton, RadioButtonChangeEvent } from "primereact/radiobutton";
 // 资源标签
-import { MultiSelect, MultiSelectChangeEvent } from 'primereact/multiselect';
+import { MultiSelect, MultiSelectChangeEvent } from "primereact/multiselect";
 // 浮动按钮
-import { SpeedDial } from 'primereact/speeddial';
+import { SpeedDial } from "primereact/speeddial";
 // 评分图标
-import { Fire } from '@icon-park/react';
+import { Fire } from "@icon-park/react";
 // 消息提醒
-import { Toast } from 'primereact/toast';
+import { Toast } from "primereact/toast";
 // 页面跳转
 import { useRouter } from "next/navigation";
 // 类型转换
-import {toNumber} from "lodash";
+import { toNumber } from "lodash";
 // 分页
-import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
+import { Paginator, type PaginatorPageChangeEvent } from "primereact/paginator";
 
 // 接口传输
 import axios from "axios";
-import { useLocalStorage } from '../hook/useLocalStorage';
+import { useLocalStorage } from "../hook/useLocalStorage";
 // 样式
-import './user.scss';
+import "./user.scss";
 
 interface User {
-    Id: number;
-};
+  Id: number;
+}
 
 // 用户信息
 interface UserInfo {
-    userId: number;
-    username: string;
-    password: string;
-    avatar: string;
-    followerCount: number;// 粉丝数
-    subscriberCount: number;// 关注数
-    signature: string;// 个性签名
-    uploadAmount: number;
-    purchaseAmount: number;
-    credits: number;
+  userId: number;
+  username: string;
+  password: string;
+  avatar: string;
+  followerCount: number; // 粉丝数
+  subscriberCount: number; // 关注数
+  signature: string; // 个性签名
+  uploadAmount: number;
+  purchaseAmount: number;
+  credits: number;
 }
 
 // 用户数据
 interface UserData {
-    subscriberCount: number; // 关注数
-    uploadAmount: number; // 上传量(资源个数)
-    beDownloadedAmount: number; // 上传资源被下载量
-    seedPercentageList: number[]; // 上传资源类型百分比列表,按材质包、模组、整合包、地图的顺序返回
+  subscriberCount: number; // 关注数
+  uploadAmount: number; // 上传量(资源个数)
+  beDownloadedAmount: number; // 上传资源被下载量
+  seedPercentageList: number[]; // 上传资源类型百分比列表,按材质包、模组、整合包、地图的顺序返回
 }
 
 // 用户发布过的资源
 interface Resource {
-    resourceId: number;
-    resourceName: string;
-    resourcePicture: string;
-    resourceSummary: string; // 资源简介(一句话)
-    resourceDetail: string; // 资源介绍
-    uploadTime: string; // 上传时间
-    lastUpdateTime: string; // 最近更新时间
-    price: number;
-    downloads: number;
-    likes: number;
-    collections: number;
-    comments: number;
-    seeds: number; // 种子数
-    classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
+  resourceId: number;
+  resourceName: string;
+  resourcePicture: string;
+  resourceSummary: string; // 资源简介(一句话)
+  resourceDetail: string; // 资源介绍
+  uploadTime: string; // 上传时间
+  lastUpdateTime: string; // 最近更新时间
+  price: number;
+  downloads: number;
+  likes: number;
+  collections: number;
+  comments: number;
+  seeds: number; // 种子数
+  classify: string; // 资源分类(材质包:resourcePack,模组:mod,整合包:modPack ,地图:map
 }
 
 // 用户发布过的资源列表
 interface ResourceList {
-    records: Resource[];
+  records: Resource[];
 }
 
 // 帖子
 interface Thread {
-    threadId: number;
-    userId:  number;
-    threadPicture:   string;
-    title: string;
-    likes:  number;
-    createAt:  string;
+  threadId: number;
+  userId: number;
+  threadPicture: string;
+  title: string;
+  likes: number;
+  createAt: string;
 }
 
 // 发布帖子列表
 interface ThreadList {
-    records: Thread[];
-    total: number;
-    pages: number;
-    current: number;
-    size: number;
+  records: Thread[];
+  total: number;
+  pages: number;
+  current: number;
+  size: number;
 }
 
 // 悬赏
 interface Reward {
-    rewardId: number;
-    userId: number;
-    rewardPicture: string;
-    rewardName: string;
-    createAt: string;
-    rewardDescription: string;
-    price: number;
+  rewardId: number;
+  userId: number;
+  rewardPicture: string;
+  rewardName: string;
+  createAt: string;
+  rewardDescription: string;
+  price: number;
 }
 
 // 我的悬赏列表
 interface RewardList {
-    rewardList: Reward[];
-    total: number; // 总记录数
+  rewardList: Reward[];
+  total: number; // 总记录数
 }
 
 // 资源标签
 interface GameplayOption {
-    name: string;
-    code: number;
+  name: string;
+  code: number;
 }
 
 // 资源标签选项
 const gameplayOptions: GameplayOption[] = [
-    { name: '科技', code: 1 },
-    { name: '魔法', code: 2 },
-    { name: '建筑', code: 3 },
-    { name: '风景', code: 4 },
-    { name: '竞技', code: 5 },
-    { name: '生存', code: 6 },
-    { name: '冒险', code: 7 },
-    { name: '跑酷', code: 8 },
-    { name: '艺术', code: 9 },
-    { name: '剧情', code: 10 },
-    { name: '社交', code: 11 },
-    { name: '策略', code: 12 },
-    { name: '极限', code: 13 }
+  { name: "科技", code: 1 },
+  { name: "魔法", code: 2 },
+  { name: "建筑", code: 3 },
+  { name: "风景", code: 4 },
+  { name: "竞技", code: 5 },
+  { name: "生存", code: 6 },
+  { name: "冒险", code: 7 },
+  { name: "跑酷", code: 8 },
+  { name: "艺术", code: 9 },
+  { name: "剧情", code: 10 },
+  { name: "社交", code: 11 },
+  { name: "策略", code: 12 },
+  { name: "极限", code: 13 },
 ];
 
 export default function UserPage() {
-    const user = useLocalStorage<User>('user');
-    const userId: number = user?.Id ?? -1;
+  const user = useLocalStorage<User>("user");
+  const userId: number = user?.Id ?? -1;
 
-    // 路由
-    const router = useRouter();
-    // 发布资源列表
-    const [resourceList, setResourceList] = useState<Resource[]>([]);
-    // 用户信息
-    const [userInfo, setUserInfo] = useState<UserInfo>();
-    // 用户数据
-    const [userData, setUserData] = useState<UserData>();
-    // 消息提醒
-    const toast = useRef<Toast>(null);
-    // 资源标签
-    const [selectedGameplay, setSelectedGameplay] = useState<GameplayOption[]>([]);
-    // 资源封面路径
-    const [resourcePictureUrl, setResourcePictureUrl] = useState<string>('');
-    // 主页发布帖子列表
-    const [homePageThread, setHomePageThread] = useState<ThreadList>();
-    // 我的帖子列表
-    const [threadList, setThreadList] = useState<Thread[]>([]);
-    // 我的悬赏列表
-    const [rewardList, setRewardList] = useState<Reward[]>([]);
-    // 控制Tab切换
-    const [activeIndex, setActiveIndex] = useState(0);
-    // 帖子分页
-    const [threadFirst, setThreadFirst] = useState(0);
-    const [threadRows, setThreadRows] = useState(6);
-    const [totalThreads, setTotalThreads] = useState<number>(0);
-    const onThreadPageChange = (event: PaginatorPageChangeEvent) => {
-        setThreadFirst(event.first);
-        setThreadRows(event.rows);
-    };
-    // 悬赏分页
-    const [rewardFirst, setRewardFirst] = useState(0);
-    const [rewardRows, setRewardRows] = useState(5);
-    const [totalRewards, setTotalRewards] = useState<number>(0);
-    const onRewardPageChange = (event: PaginatorPageChangeEvent) => {
-        setRewardFirst(event.first);
-        setRewardRows(event.rows);
-    };
+  // 路由
+  const router = useRouter();
+  // 发布资源列表
+  const [resourceList, setResourceList] = useState<Resource[]>([]);
+  // 用户信息
+  const [userInfo, setUserInfo] = useState<UserInfo>();
+  // 用户数据
+  const [userData, setUserData] = useState<UserData>();
+  // 消息提醒
+  const toast = useRef<Toast>(null);
+  // 资源标签
+  const [selectedGameplay, setSelectedGameplay] = useState<GameplayOption[]>(
+    []
+  );
+  // 资源封面路径
+  const [resourcePictureUrl, setResourcePictureUrl] = useState<string>("");
+  // 主页发布帖子列表
+  const [homePageThread, setHomePageThread] = useState<ThreadList>();
+  // 我的帖子列表
+  const [threadList, setThreadList] = useState<Thread[]>([]);
+  // 我的悬赏列表
+  const [rewardList, setRewardList] = useState<Reward[]>([]);
+  // 控制Tab切换
+  const [activeIndex, setActiveIndex] = useState(0);
+  // 帖子分页
+  const [threadFirst, setThreadFirst] = useState(0);
+  const [threadRows, setThreadRows] = useState(6);
+  const [totalThreads, setTotalThreads] = useState<number>(0);
+  const onThreadPageChange = (event: PaginatorPageChangeEvent) => {
+    setThreadFirst(event.first);
+    setThreadRows(event.rows);
+  };
+  const [torrentUrl, setTorrentUrl] = useState<string>(""); // 上传 .torrent 后得到的 URL
 
-    useEffect(() => {
-        fetchUserInfo();
-        fetchUserData();
-        fetchResourceList();
-    }, []);
+  // 悬赏分页
+  const [rewardFirst, setRewardFirst] = useState(0);
+  const [rewardRows, setRewardRows] = useState(5);
+  const [totalRewards, setTotalRewards] = useState<number>(0);
+  const onRewardPageChange = (event: PaginatorPageChangeEvent) => {
+    setRewardFirst(event.first);
+    setRewardRows(event.rows);
+  };
 
-    // 获取用户信息
-    const fetchUserInfo = async () => {
-        try {
-            const response = await axios.get<UserInfo>(process.env.PUBLIC_URL + `/user/info`, {
-                params: { userId }
-            });
-            console.log('获取用户信息:', response.data);
-            setUserInfo(response.data);
-        } catch (err) {
-            console.error('获取用户信息失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取用户信息失败' });
+  useEffect(() => {
+    fetchUserInfo();
+    fetchUserData();
+    fetchResourceList();
+  }, []);
+
+  // 获取用户信息
+  const fetchUserInfo = async () => {
+    try {
+      const response = await axios.get<UserInfo>(
+        process.env.PUBLIC_URL + `/user/info`,
+        {
+          params: { userId },
         }
-    };
-
-    // 获取用户数据
-    const fetchUserData = async () => {
-        try {
-            const response = await axios.get<UserData>(process.env.PUBLIC_URL + `/user/data`, {
-                params: { userId }
-            });
-            console.log('获取用户数据:', response.data);
-            setUserData(response.data);
-        } catch (err) {
-            console.error('获取用户数据失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取用户数据失败' });
-        }
-    };
-
-    // 格式化数字显示 (3000 -> 3k)
-    const formatCount = (count?: number): string => {
-        if (count == null) return "0"; // 同时处理 undefined/null
-
-        const absCount = Math.abs(count); // 处理负数
-
-        const format = (num: number, suffix: string) => {
-            const fixed = num.toFixed(1);
-            return fixed.endsWith('.0')
-                ? `${Math.floor(num)}${suffix}`
-                : `${fixed}${suffix}`;
-        };
-
-        if (absCount >= 1e6) return format(count / 1e6, "m");
-        if (absCount >= 1e3) return format(count / 1e3, "k");
-        return count.toString();
-    };
-
-    // 获取发布资源
-    const fetchResourceList = async () => {
-        try {
-            const response = await axios.get<ResourceList>(process.env.PUBLIC_URL + `/user/upload`, {
-                params: { userId, pageNumber: 1, rows: 3 }
-            });
-            console.log('获取发布资源列表:', response.data.records);
-            setResourceList(response.data.records);
-        } catch (err) {
-            console.error('获取发布资源失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取发布资源失败' });
-        }
-    };
-
-    useEffect(() => {
-        fetchHomePageThread();
-    }, []);
-
-    // 获取主页部分的发布帖子
-    const fetchHomePageThread = async () => {
-        try {
-            const response = await axios.get<ThreadList>(process.env.PUBLIC_URL + `/user/thread`, {
-                params: { userId: userId,  pageNumber: 1, rows: 3 }
-            })
-            console.log('获取主页发布帖子:', response.data);
-            setHomePageThread(response.data);
-
-        } catch (err) {
-            console.error('获取主页发布帖子失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取主页发布帖子失败' });
-        }
+      );
+      console.log("获取用户信息:", response.data);
+      setUserInfo(response.data);
+    } catch (err) {
+      console.error("获取用户信息失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取用户信息失败",
+      });
     }
+  };
 
-    useEffect(() => {
-        fetchThreadList();
-    }, [threadFirst, threadRows]);
-
-    // 获取用户发布的所有帖子
-    const fetchThreadList = async () => {
-        try {
-            const pageNumber = threadFirst / threadRows + 1;
-            const response = await axios.get<ThreadList>(process.env.PUBLIC_URL + `/user/thread`, {
-                params: { userId: userId,  pageNumber: pageNumber, rows: threadRows }
-            })
-            console.log('获取我的帖子:', response.data);
-            setThreadList(response.data.records);
-            setTotalThreads(response.data.total)
-        }catch (err) {
-            console.error('获取我的帖子失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取我的帖子失败' });
+  // 获取用户数据
+  const fetchUserData = async () => {
+    try {
+      const response = await axios.get<UserData>(
+        process.env.PUBLIC_URL + `/user/data`,
+        {
+          params: { userId },
         }
+      );
+      console.log("获取用户数据:", response.data);
+      setUserData(response.data);
+    } catch (err) {
+      console.error("获取用户数据失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取用户数据失败",
+      });
     }
+  };
 
-    useEffect(() => {
+  // 格式化数字显示 (3000 -> 3k)
+  const formatCount = (count?: number): string => {
+    if (count == null) return "0"; // 同时处理 undefined/null
+
+    const absCount = Math.abs(count); // 处理负数
+
+    const format = (num: number, suffix: string) => {
+      const fixed = num.toFixed(1);
+      return fixed.endsWith(".0")
+        ? `${Math.floor(num)}${suffix}`
+        : `${fixed}${suffix}`;
+    };
+
+    if (absCount >= 1e6) return format(count / 1e6, "m");
+    if (absCount >= 1e3) return format(count / 1e3, "k");
+    return count.toString();
+  };
+
+  // 获取发布资源
+  const fetchResourceList = async () => {
+    try {
+      const response = await axios.get<ResourceList>(
+        process.env.PUBLIC_URL + `/user/upload`,
+        {
+          params: { userId, pageNumber: 1, rows: 3 },
+        }
+      );
+      console.log("获取发布资源列表:", response.data.records);
+      setResourceList(response.data.records);
+    } catch (err) {
+      console.error("获取发布资源失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取发布资源失败",
+      });
+    }
+  };
+
+  useEffect(() => {
+    fetchHomePageThread();
+  }, []);
+
+  // 获取主页部分的发布帖子
+  const fetchHomePageThread = async () => {
+    try {
+      const response = await axios.get<ThreadList>(
+        process.env.PUBLIC_URL + `/user/thread`,
+        {
+          params: { userId: userId, pageNumber: 1, rows: 3 },
+        }
+      );
+      console.log("获取主页发布帖子:", response.data);
+      setHomePageThread(response.data);
+    } catch (err) {
+      console.error("获取主页发布帖子失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取主页发布帖子失败",
+      });
+    }
+  };
+
+  useEffect(() => {
+    fetchThreadList();
+  }, [threadFirst, threadRows]);
+
+  // 获取用户发布的所有帖子
+  const fetchThreadList = async () => {
+    try {
+      const pageNumber = threadFirst / threadRows + 1;
+      const response = await axios.get<ThreadList>(
+        process.env.PUBLIC_URL + `/user/thread`,
+        {
+          params: { userId: userId, pageNumber: pageNumber, rows: threadRows },
+        }
+      );
+      console.log("获取我的帖子:", response.data);
+      setThreadList(response.data.records);
+      setTotalThreads(response.data.total);
+    } catch (err) {
+      console.error("获取我的帖子失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取我的帖子失败",
+      });
+    }
+  };
+
+  useEffect(() => {
+    fetchRewardList();
+  }, [rewardFirst, rewardRows]);
+
+  // 获取用户发布的所有悬赏
+  const fetchRewardList = async () => {
+    try {
+      const pageNumber = rewardFirst / rewardRows + 1;
+      const response = await axios.get<RewardList>(
+        process.env.PUBLIC_URL + `/user/reward`,
+        {
+          params: { userId: userId, pageNumber: pageNumber, rows: rewardRows },
+        }
+      );
+      console.log("获取我的悬赏:", response.data);
+      setRewardList(response.data.rewardList);
+      setTotalRewards(response.data.total);
+    } catch (err) {
+      console.error("获取我的悬赏失败", err);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "获取我的悬赏失败",
+      });
+    }
+  };
+
+  // 浮动按钮的子模块
+  const actions = [
+    {
+      template: () => (
+        <Button
+          label="管理资源"
+          onClick={() => router.push(`/user/manage/resources/`)}
+        />
+      ),
+    },
+    {
+      template: () => (
+        <Button
+          label="已购资源"
+          onClick={() => router.push(`/user/purchased-resources/`)}
+        />
+      ),
+    },
+    {
+      template: () => (
+        <Button label="发布资源" onClick={() => setVisible(true)} />
+      ),
+    },
+    {
+      template: () => <Button label="编辑悬赏" />,
+    },
+  ];
+
+  // 发布资源弹窗
+  const [visible, setVisible] = useState(false);
+  const [resourceFormData, setResourceFormData] = useState({
+    resource: {
+      resourceName: "",
+      resourcePicture: "",
+      resourceSummary: "",
+      resourceDetail: "",
+      uploadTime: "",
+      lastUpdateTime: "",
+      price: "",
+      classify: "",
+    },
+    resourceVersionName: "",
+    gameplayList: [""],
+    completeRewardId: null,
+    userId: 0,
+  });
+  const [ingredient, setIngredient] = useState<string>("");
+
+  // 删除悬赏弹窗
+  const [deleteVisible, setDeleteVisible] = useState(false);
+  // 要删除悬赏的id
+  const [deleteRewardId, setDeleteResourceId] = useState<number>(0);
+  // 处理删除悬赏接口
+  const handleDeleteSubmit = async () => {
+    try {
+      // 发送DELETE请求
+      const response = await axios.delete(process.env.PUBLIC_URL + `/reward`, {
+        params: { rewardId: deleteRewardId },
+      });
+      console.log("用户" + userId + "要删除" + deleteRewardId + "号悬赏");
+
+      if (response.status === 204) {
+        console.log("用户成功删除悬赏");
+        toast.current?.show({
+          severity: "success",
+          summary: "Success",
+          detail: "删除悬赏成功",
+        });
+        setDeleteVisible(false);
+        // 重新拉取资源列表
         fetchRewardList();
-    }, [rewardFirst, rewardRows]);
-
-    // 获取用户发布的所有悬赏
-    const fetchRewardList = async () => {
-        try {
-            const pageNumber = rewardFirst / rewardRows + 1;
-            const response = await axios.get<RewardList>(process.env.PUBLIC_URL + `/user/reward`, {
-                params: { userId: userId,  pageNumber: pageNumber, rows: rewardRows }
-            })
-            console.log('获取我的悬赏:', response.data);
-            setRewardList(response.data.rewardList);
-            setTotalRewards(response.data.total)
-        }catch (err) {
-            console.error('获取我的悬赏失败', err);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '获取我的悬赏失败' });
-        }
+      }
+    } catch (error) {
+      console.error("资源删除失败:", error);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "密码错误,资源删除失败",
+      });
     }
+  };
 
-    // 浮动按钮的子模块
-    const actions = [
-        {
-            template: () => (
-                <Button label="管理资源" onClick={() => router.push(`/user/manage/resources/`)} />
-            )
-        },
-        {
-            template: () => (
-                <Button label="已购资源" onClick={() => router.push(`/user/purchased-resources/`)} />
-            )
-        },
-        {
-            template: () => (
-                <Button label="发布资源" onClick={() => setVisible(true)} />
-            )
-        },
-        {
-            template: () => (
-                <Button label="编辑悬赏" />
-            )
-        }
-    ];
+  // 编辑悬赏弹窗
+  const [editVisible, setEditVisible] = useState(false);
+  // 悬赏封面路径
+  const [rewardPictureUrl, setRewardPictureUrl] = useState<string>("");
+  const [editRewardFormData, setEditRewardFormData] = useState({
+    rewardId: 0,
+    rewardName: "",
+    price: "",
+    rewardDescription: "",
+  });
 
-    // 发布资源弹窗
-    const [visible, setVisible] = useState(false);
-    const [resourceFormData, setResourceFormData] = useState({
+  // 处理编辑资源接口
+  const handleEditSubmit = async () => {
+    try {
+      const postData = {
+        rewardId: editRewardFormData.rewardId,
+        rewardName: editRewardFormData.rewardName,
+        rewardPicture: rewardPictureUrl,
+        price: toNumber(editRewardFormData.price),
+        rewardDescription: editRewardFormData.rewardDescription,
+      };
+      // 发送POST请求
+      const response = await axios.put(
+        process.env.PUBLIC_URL + "/reward/info",
+        postData
+      );
+      console.log("编辑悬赏的信息:", postData);
+
+      if (response.status === 200) {
+        toast.current?.show({
+          severity: "success",
+          summary: "Success",
+          detail: "悬赏编辑成功",
+        });
+        // 编辑成功
+        setEditVisible(false);
+        fetchRewardList();
+      }
+    } catch (error) {
+      console.error("悬赏编辑失败:", error);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "悬赏编辑失败",
+      });
+    }
+  };
+
+  // 上传资源接口
+  const handleSubmit = async () => {
+    try {
+      // 规定用户必须输入的内容
+      if (resourceFormData.resource.resourceName == "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源名称",
+        });
+        return;
+      }
+      if (resourceFormData.resource.resourceSummary == "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源简介",
+        });
+        return;
+      }
+      if (resourceFormData.resourceVersionName == "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源版本名",
+        });
+        return;
+      }
+      if (resourceFormData.resource.price == "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源价格",
+        });
+        return;
+      }
+      if (resourceFormData.resource.classify == "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源分类",
+        });
+        return;
+      }
+      if (
+        resourceFormData.gameplayList.length === 1 &&
+        resourceFormData.gameplayList[0] === ""
+      ) {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源标签",
+        });
+        return;
+      }
+      if (resourcePictureUrl === "") {
+        toast.current?.show({
+          severity: "info",
+          summary: "error",
+          detail: "缺少资源封面",
+        });
+        return;
+      }
+
+      const currentDate = new Date().toISOString().split("T")[0];
+      const postData = {
         resource: {
-            resourceName: '',
-            resourcePicture: '',
-            resourceSummary: '',
-            resourceDetail: '',
-            uploadTime: '',
-            lastUpdateTime: '',
-            price: '',
-            classify: '',
+          resourceName: resourceFormData.resource.resourceName,
+          resourcePicture: resourcePictureUrl,
+          resourceSummary: resourceFormData.resource.resourceSummary,
+          resourceDetail: resourceFormData.resource.resourceDetail,
+          uploadTime: currentDate,
+          lastUpdateTime: currentDate,
+          price: toNumber(resourceFormData.resource.price),
+          classify: resourceFormData.resource.classify,
         },
-        gameplayList: [''],
+        gameplayList: resourceFormData.gameplayList,
+        resourceVersionName: resourceFormData.resourceVersionName,
         completeRewardId: null,
-        userId: 0,
-    });
-    const [ingredient, setIngredient] = useState<string>('');
+        userId, // 记得用户登录状态获取
+      };
+      // 发送POST请求
+      const response = await axios.post(
+        process.env.PUBLIC_URL + "/resource",
+        postData
+      );
+      console.log("上传资源的信息:", postData);
 
-    // 删除悬赏弹窗
-    const [deleteVisible, setDeleteVisible] = useState(false);
-    // 要删除悬赏的id
-    const [deleteRewardId, setDeleteResourceId] =  useState<number>(0);
-    // 处理删除悬赏接口
-    const handleDeleteSubmit = async () => {
+      if (response.status === 200) {
+        toast.current?.show({
+          severity: "success",
+          summary: "Success",
+          detail: "资源上传成功",
+        });
+        console.log(torrentUrl);
         try {
-            // 发送DELETE请求
-            const response = await axios.delete(process.env.PUBLIC_URL + `/reward`, {
-                params: {rewardId: deleteRewardId},
-            });
-            console.log("用户" + userId + "要删除" + deleteRewardId + "号悬赏");
-
-            if (response.status === 204) {
-                console.log("用户成功删除悬赏");
-                toast.current?.show({severity: 'success', summary: 'Success', detail: '删除悬赏成功'});
-                setDeleteVisible(false);
-                // 重新拉取资源列表
-                fetchRewardList();
+          const versionResponse = await axios.post(
+            `${process.env.PUBLIC_URL}/resource/version`,
+            {
+              resourceVersionName: postData.resourceVersionName,
+              resourceId: Number(response.data),
             }
-        } catch (error) {
-            console.error('资源删除失败:', error);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '密码错误,资源删除失败' });
+          );
+          // 上传资源文件
+          const btPayload = {
+            torrentUrl: torrentUrl,
+            infoHash: "8",
+            uploadTime: currentDate,
+            uploaderUserId: userId,
+            resourceVersionId: Number(versionResponse.data),
+          };
+
+          await axios.post(`${process.env.PUBLIC_URL}/file/bt`, btPayload);
+          toast.current?.show({
+            severity: "success",
+            summary: "资源登记成功",
+            detail: "已同步种子信息",
+          });
+        } catch (btError) {
+          console.error("种子登记失败:", btError);
+          toast.current?.show({
+            severity: "warn",
+            summary: "资源已上传",
+            detail: "但种子登记失败",
+          });
         }
-    };
 
+        // 上传成功
+        setVisible(false);
+        // 重置表单
+        setResourceFormData({
+          resource: {
+            resourceName: "",
+            resourcePicture: "",
+            resourceSummary: "",
+            resourceDetail: "",
+            uploadTime: "",
+            lastUpdateTime: "",
+            price: "",
+            classify: "",
+          },
+          resourceVersionName: "",
+          gameplayList: [],
+          completeRewardId: null,
+          userId: 0,
+        });
+        // 重置资源分类
+        setIngredient("");
+        // 重置资源标签
+        setSelectedGameplay([]);
+        // 重置资源封面
+        setResourcePictureUrl("");
+        setTorrentUrl("");
+      }
+    } catch (error) {
+      console.error("资源上传失败:", error);
+      toast.current?.show({
+        severity: "error",
+        summary: "error",
+        detail: "资源上传失败",
+      });
+    }
+  };
 
-    // 编辑悬赏弹窗
-    const [editVisible, setEditVisible] = useState(false);
-    // 悬赏封面路径
-    const [rewardPictureUrl, setRewardPictureUrl] = useState<string>('');
-    const [editRewardFormData, setEditRewardFormData] = useState({
-        rewardId: 0,
-        rewardName: '',
-        price: '',
-        rewardDescription: '',
-    });
-
-    // 处理编辑资源接口
-    const handleEditSubmit = async () => {
-        try {
-            const postData = {
-                rewardId: editRewardFormData.rewardId,
-                rewardName: editRewardFormData.rewardName,
-                rewardPicture: rewardPictureUrl,
-                price: toNumber(editRewardFormData.price),
-                rewardDescription: editRewardFormData.rewardDescription,
-            };
-            // 发送POST请求
-            const response = await axios.put(process.env.PUBLIC_URL + '/reward/info', postData);
-            console.log("编辑悬赏的信息:", postData);
-
-            if (response.status === 200) {
-                toast.current?.show({ severity: 'success', summary: 'Success', detail: '悬赏编辑成功' });
-                // 编辑成功
-                setEditVisible(false);
-                fetchRewardList();
-            }
-        } catch (error) {
-            console.error('悬赏编辑失败:', error);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '悬赏编辑失败' });
-        }
-    };
-
-    // 上传资源接口
-    const handleSubmit = async () => {
-        try {
-            // 规定用户必须输入的内容
-            if (resourceFormData.resource.resourceName == '') {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源名称' });
-                return;
-            }
-            if (resourceFormData.resource.resourceSummary == '') {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源简介' });
-                return;
-            }
-            if (resourceFormData.resource.price == '') {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源价格' });
-                return;
-            }
-            if (resourceFormData.resource.classify == '') {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源分类' });
-                return;
-            }
-            if (
-                resourceFormData.gameplayList.length === 1 &&
-                resourceFormData.gameplayList[0] === ''
-            ) {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源标签' });
-                return;
-            }
-            if (resourcePictureUrl === '') {
-                toast.current?.show({ severity: 'info', summary: 'error', detail: '缺少资源封面' });
-                return;
-            }
-
-            const currentDate = new Date().toISOString().split('T')[0];
-            const postData = {
-                resource: {
-                    resourceName: resourceFormData.resource.resourceName,
-                    resourcePicture: resourcePictureUrl,
-                    resourceSummary: resourceFormData.resource.resourceSummary,
-                    resourceDetail: resourceFormData.resource.resourceDetail,
-                    uploadTime: currentDate,
-                    lastUpdateTime: currentDate,
-                    price: toNumber(resourceFormData.resource.price),
-                    classify: resourceFormData.resource.classify,
-                },
-                gameplayList: resourceFormData.gameplayList,
-                completeRewardId: null,
-                userId, // 记得用户登录状态获取
-            };
-            // 发送POST请求
-            const response = await axios.post(process.env.PUBLIC_URL + '/resource', postData);
-            console.log("上传资源的信息:", postData);
-
-            if (response.status === 200) {
-                toast.current?.show({ severity: 'success', summary: 'Success', detail: '资源上传成功' });
-                // 上传成功
-                setVisible(false);
-                // 重置表单
-                setResourceFormData({
-                    resource: {
-                        resourceName: '',
-                        resourcePicture: '',
-                        resourceSummary: '',
-                        resourceDetail: '',
-                        uploadTime: '',
-                        lastUpdateTime: '',
-                        price: '',
-                        classify: '',
-                    },
-                    gameplayList: [],
-                    completeRewardId: null,
-                    userId: 0,
-                });
-                // 重置资源分类
-                setIngredient("");
-                // 重置资源标签
-                setSelectedGameplay([]);
-                // 重置资源封面
-                setResourcePictureUrl('');
-            }
-        } catch (error) {
-            console.error('资源上传失败:', error);
-            toast.current?.show({ severity: 'error', summary: 'error', detail: '资源上传失败' });
-        }
-    };
-
-    return (
-        <div className="user-container">
-            <Toast ref={toast}></Toast>
-            {/*个人信息*/}
-            <div className="user-profile-card">
-                <Avatar
-                    image={`${process.env.NEXT_PUBLIC_NGINX_URL}/users/${userInfo?.avatar}`}
-                    className="user-avatar"
-                    shape="circle"
-                />
-                <div className="user-info">
-                    <div className="user-detail-info">
-                        <div className="name-container">
-                            <h2 className="name">{userInfo?.username}</h2>
-                            <span className="signature">{userInfo?.signature}</span>
-                        </div>
-
-                        <div className="stats-container">
-                            <div className="stats">
-                                <span className="stats-label">粉丝:</span>
-                                <span className="stats-value">{userInfo?.followerCount}</span>
-                            </div>
-                            <div className="stats">
-                                <span className="stats-label">累计上传量:</span>
-                                <span className="stats-value">{formatCount(userData?.uploadAmount)}</span>
-                            </div>
-                            <div className="stats">
-                                <span className="stats-label">关注:</span>
-                                <span className="stats-value">{userInfo?.subscriberCount}</span>
-                            </div>
-                            <div className="stats">
-                                <span className="stats-label">累计被下载量:</span>
-                                <span className="stats-value">{formatCount(userData?.beDownloadedAmount)}</span>
-                            </div>
-                        </div>
-                    </div>
-
-                    <Button label="关注" className="action-button" />
-                </div>
+  return (
+    <div className="user-container">
+      <Toast ref={toast}></Toast>
+      {/*个人信息*/}
+      <div className="user-profile-card">
+        <Avatar
+          image={userInfo?.avatar}
+          className="user-avatar"
+          shape="circle"
+        />
+        <div className="user-info">
+          <div className="user-detail-info">
+            <div className="name-container">
+              <h2 className="name">{userInfo?.username}</h2>
+              <span className="signature">{userInfo?.signature}</span>
             </div>
 
-            {/*个人内容*/}
-            <TabView activeIndex={activeIndex} onTabChange={(e) => setActiveIndex(e.index)}>
-                <TabPanel header="主页" >
-                    {/*发布资源*/}
-                    <div className="homepage-item">
-                        <div className="section-header">
-                            <h1>发布资源</h1>
-                            <Button
-                                label="显示更多"
-                                link
-                                onClick={() => router.push('/user/manage/resources/')}
-                            />
-                        </div>
-                        <div className="resource-grid">
-                            {resourceList.map((resourceList) => (
-                                <Card key={resourceList.resourceId} className="resource-card" onClick={() => router.push(`/resource/resource-detail/${resourceList.resourceId}`)}>
-                                    <Image
-                                        src={process.env.NEXT_PUBLIC_NGINX_URL + resourceList.resourcePicture}
-                                        alt={resourceList.resourceName}
-                                        width="368"
-                                        height="200"
-                                    />
-                                    <div className="card-content">
-                                        <h3>{resourceList.resourceName}</h3>
-                                        <div className="view-count">
-                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
-                                            <span>{resourceList.likes}</span>
-                                        </div>
-                                    </div>
-                                </Card>
-                            ))}
-                        </div>
-                    </div>
-
-                    {/*发布帖子*/}
-                    <div className="homepage-item">
-                        <div className="section-header">
-                            <h1>发布帖子</h1>
-                            <Button
-                                label="显示更多"
-                                link
-                                onClick={() => setActiveIndex(1)}
-                            />
-                        </div>
-                        <div className="resource-grid">
-                            {homePageThread?.records.map((homePageThread) => (
-                                <Card key={homePageThread.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${homePageThread.threadId}`)}>
-                                    <Image
-                                        src={process.env.NEXT_PUBLIC_NGINX_URL + homePageThread.threadPicture}
-                                        alt={homePageThread.title}
-                                        width="368"
-                                        height="200"
-                                    />
-                                    <div className="card-content">
-                                        <h3>{homePageThread.title}</h3>
-                                        <div className="view-count">
-                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
-                                            <span>{homePageThread.likes}</span>
-                                        </div>
-                                    </div>
-                                </Card>
-                            ))}
-                        </div>
-                    </div>
-                </TabPanel>
-
-                <TabPanel header="帖子">
-                    {/*我的帖子*/}
-                    <div className="homepage-item">
-                        <div className="section-header">
-                            <h1>我的帖子</h1>
-                        </div>
-                        <div className="resource-grid">
-                            {threadList.map((threadList) => (
-                                <Card key={threadList.threadId} className="resource-card" onClick={() => router.push(`/community/thread-detail/${threadList.threadId}`)}>
-                                    <Image
-                                        src={process.env.NEXT_PUBLIC_NGINX_URL + threadList.threadPicture}
-                                        alt={threadList.title}
-                                        width="368"
-                                        height="200"
-                                    />
-                                    <div className="card-content">
-                                        <h3>{threadList.title}</h3>
-                                        <div className="view-count">
-                                            <Fire theme="outline" size="16" fill="#FF8D1A" />
-                                            <span>{threadList.likes}</span>
-                                        </div>
-                                    </div>
-                                </Card>
-                            ))}
-                        </div>
-                        {totalThreads > 6 && <Paginator
-                            className="Paginator"
-                            first={threadFirst}
-                            rows={threadRows}
-                            totalRecords={totalThreads}
-                            rowsPerPageOptions={[6, 12]}
-                            onPageChange={onThreadPageChange}
-                        />}
-                    </div>
-                </TabPanel>
-
-                <TabPanel header="收藏">
-
-                </TabPanel>
-
-                <TabPanel header="数据">
-
-                </TabPanel>
-
-                <TabPanel header="悬赏">
-                    <div className="section-header">
-                        <h1>我的悬赏</h1>
-                    </div>
-
-                    <div className="resource-list">
-                        {rewardList.map((rewardItem) => (
-                            <Card key={rewardItem.rewardId} className="resources-list-card"
-                                  onClick={() => router.push(`/reward/reward-detail/${rewardItem.rewardId}`)}>
-                                <Image alt="avatar"
-                                       src={process.env.NEXT_PUBLIC_NGINX_URL + "rewards/" + rewardItem.rewardPicture}
-                                       className="resource-avatar" width="250" height="140"/>
-                                <div className="resource-header">
-                                    <div className="resource-content">
-                                        <h3>{rewardItem.rewardName}</h3>
-                                    </div>
-
-                                    <div className="resource-operation">
-                                        <Button
-                                            label="编辑"
-                                            onClick={(e) => {
-                                                e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
-                                                setEditVisible(true);
-
-                                                setEditRewardFormData({
-                                                    rewardId: rewardItem.rewardId,
-                                                    rewardName: rewardItem.rewardName,
-                                                    price: rewardItem.price.toString(),
-                                                    rewardDescription: rewardItem.rewardDescription,
-                                                });
-                                                console.log("用户编辑悬赏");
-                                            }}
-                                        />
-                                        <Button
-                                            label="删除"
-                                            onClick={(e) => {
-                                                e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
-                                                setDeleteResourceId(rewardItem.rewardId);
-                                                setDeleteVisible(true);
-                                            }}
-                                            style={{backgroundColor: "rgba(255, 87, 51, 1)"}}
-                                        />
-                                    </div>
-                                </div>
-                            </Card>
-                        ))}
-
-                        {totalRewards > 5 && <Paginator
-                            className="Paginator"
-                            first={rewardFirst}
-                            rows={rewardRows}
-                            totalRecords={totalRewards}
-                            rowsPerPageOptions={[5, 10]}
-                            onPageChange={onRewardPageChange}
-                        />}
-                    </div>
-                </TabPanel>
-            </TabView>
-
-            {/*浮动按钮*/}
-            <div className="card">
-                <SpeedDial
-                    model={actions}
-                    direction="up"
-                    style={{ position: 'fixed', bottom: '2rem', right: '2rem' }}
-                    showIcon="pi pi-plus"
-                    hideIcon="pi pi-times"
-                    buttonClassName="custom-speeddial-button"
-                />
+            <div className="stats-container">
+              <div className="stats">
+                <span className="stats-label">粉丝:</span>
+                <span className="stats-value">{userInfo?.followerCount}</span>
+              </div>
+              <div className="stats">
+                <span className="stats-label">累计上传量:</span>
+                <span className="stats-value">
+                  {formatCount(userData?.uploadAmount)}
+                </span>
+              </div>
+              <div className="stats">
+                <span className="stats-label">关注:</span>
+                <span className="stats-value">{userInfo?.subscriberCount}</span>
+              </div>
+              <div className="stats">
+                <span className="stats-label">累计被下载量:</span>
+                <span className="stats-value">
+                  {formatCount(userData?.beDownloadedAmount)}
+                </span>
+              </div>
             </div>
+          </div>
 
-            {/*发布资源弹窗*/}
-            <Dialog
-                header="发布资源"
-                visible={visible}
-                onHide={() => setVisible(false)}
-                className="publish-dialog"
-                modal
-                footer={
-                    <div className="dialog-footer">
-                        <Button label="发布" icon="pi pi-check" onClick={handleSubmit} autoFocus />
-                        <Button label="取消" icon="pi pi-times" onClick={() => setVisible(false)} className="p-button-text" />
-                    </div>
-                }
-            >
-                <div className="publish-form">
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label htmlFor="name">资源名称</label>
-                        </div>
-                        <InputText
-                            id="name"
-                            value={resourceFormData.resource.resourceName}
-                            onChange={(e) => setResourceFormData(prev => ({
-                                ...prev, // 复制顶层所有属性
-                                resource: {
-                                    ...prev.resource, // 复制resource对象的所有属性
-                                    resourceName: e.target.value  // 只更新resourceName
-                                }
-                            }))}
-                            placeholder="请输入资源名称"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label htmlFor="summary">资源简介</label>
-                        </div>
-                        <InputText
-                            id="summary"
-                            value={resourceFormData.resource.resourceSummary}
-                            onChange={(e) => setResourceFormData(prev => ({
-                                ...prev, // 复制顶层所有属性
-                                resource: {
-                                    ...prev.resource, // 复制resource对象的所有属性
-                                    resourceSummary: e.target.value
-                                }
-                            }))}
-                            placeholder="请输入资源简介(一句话)"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <label htmlFor="detail">资源介绍</label>
-                        </div>
-                        <InputTextarea
-                            id="detail"
-                            value={resourceFormData.resource.resourceDetail}
-                            onChange={(e) => setResourceFormData(prev => ({
-                                ...prev, // 复制顶层所有属性
-                                resource: {
-                                    ...prev.resource, // 复制resource对象的所有属性
-                                    resourceDetail: e.target.value
-                                }
-                            }))}
-                            rows={5}
-                            placeholder="请输入资源介绍"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label htmlFor="price">价格</label>
-                        </div>
-                        <InputText
-                            id="price"
-                            value={resourceFormData.resource.price}
-                            onChange={(e) => setResourceFormData(prev => ({
-                                ...prev, // 复制顶层所有属性
-                                resource: {
-                                    ...prev.resource, // 复制resource对象的所有属性
-                                    price: e.target.value
-                                }
-                            }))}
-                            placeholder="请输入资源价格"
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label htmlFor="classify">资源分类(请选择一项)</label>
-                        </div>
-                        <div className="form-field-classify">
-                            <div className="flex align-items-center">
-                                <RadioButton
-                                    inputId="ingredient1"
-                                    name="pizza"
-                                    value="resourcePack"
-                                    onChange={(e: RadioButtonChangeEvent) => {
-                                        setResourceFormData(prev => ({
-                                            ...prev, // 复制顶层所有属性
-                                            resource: {
-                                                ...prev.resource, // 复制resource对象的所有属性
-                                                classify: e.target.value
-                                            }
-                                        }));
-                                        setIngredient(e.value);
-                                        console.log(ingredient);
-                                        // console.log(resourceFormData.resource.classify);
-                                    }}
-                                    checked={ingredient === 'resourcePack'}
-                                />
-                                <label htmlFor="ingredient1" className="ml-2">材质包</label>
-                            </div>
-                            <div className="flex align-items-center">
-                                <RadioButton
-                                    inputId="ingredient2"
-                                    name="pizza"
-                                    value="modPack"
-                                    onChange={(e: RadioButtonChangeEvent) => {
-                                        setResourceFormData(prev => ({
-                                            ...prev, // 复制顶层所有属性
-                                            resource: {
-                                                ...prev.resource, // 复制resource对象的所有属性
-                                                classify: e.target.value
-                                            }
-                                        }));
-                                        setIngredient(e.value);
-                                    }}
-                                    checked={ingredient === 'modPack'}
-                                />
-                                <label htmlFor="ingredient2" className="ml-2">整合包</label>
-                            </div>
-                            <div className="flex align-items-center">
-                                <RadioButton
-                                    inputId="ingredient3"
-                                    name="pizza"
-                                    value="mod"
-                                    onChange={(e: RadioButtonChangeEvent) => {
-                                        setResourceFormData(prev => ({
-                                            ...prev, // 复制顶层所有属性
-                                            resource: {
-                                                ...prev.resource, // 复制resource对象的所有属性
-                                                classify: e.target.value
-                                            }
-                                        }));
-                                        setIngredient(e.value);
-                                    }}
-                                    checked={ingredient === 'mod'}
-                                />
-                                <label htmlFor="ingredient3" className="ml-2">模组</label>
-                            </div>
-                            <div className="flex align-items-center">
-                                <RadioButton
-                                    inputId="ingredient4"
-                                    name="pizza"
-                                    value="map"
-                                    onChange={(e: RadioButtonChangeEvent) => {
-                                        setResourceFormData(prev => ({
-                                            ...prev, // 复制顶层所有属性
-                                            resource: {
-                                                ...prev.resource, // 复制resource对象的所有属性
-                                                classify: e.target.value
-                                            }
-                                        }));
-                                        setIngredient(e.value);
-                                    }}
-                                    checked={ingredient === 'map'}
-                                />
-                                <label htmlFor="ingredient4" className="ml-2">地图</label>
-                            </div>
-                        </div>
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label htmlFor="gameplayList">资源标签</label>
-                        </div>
-                        <MultiSelect
-                            value={selectedGameplay}
-                            onChange={(e: MultiSelectChangeEvent) => {
-                                const selectedOptions = e.value as GameplayOption[];
-                                // 提取选中项的 name 属性组成字符串数组
-                                const selectedNames = selectedOptions.map(item => item.name);
-
-                                setResourceFormData(prev => ({
-                                    ...prev,
-                                    gameplayList: selectedNames
-                                }));
-                                setSelectedGameplay(selectedOptions);
-                            }}
-                            options={gameplayOptions}
-                            display="chip"
-                            optionLabel="name"
-                            placeholder="请选择资源标签"
-                            className="w-full md:w-20rem"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label>封面图片</label>
-                        </div>
-                        <FileUpload
-                            mode="advanced"
-                            name="resource-image"
-                            customUpload
-                            uploadHandler={async (e) => {
-                                const formData = new FormData();
-                                formData.append("file", e.files[0]);
-
-                                try {
-                                    const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
-
-                                    const fileUrl = res.data.url;
-                                    console.log(fileUrl);
-                                    setResourcePictureUrl(fileUrl);
-                                    toast.current?.show({ severity: 'success', summary: '上传成功' });
-                                } catch (error) {
-                                    console.log(error);
-                                    toast.current?.show({ severity: 'error', summary: '上传失败' });
-                                }
-                            }}
-                            auto
-                            accept="image/*"
-                            chooseLabel="上传资源封面"
-                        />
-                    </div>
-                </div>
-            </Dialog>
-
-            {/*删除悬赏弹窗*/}
-            <Dialog
-                header="删除悬赏"
-                visible={deleteVisible}
-                onHide={() => setDeleteVisible(false)}
-                className="resource-delete-dialog"
-                modal
-                footer={
-                    <div className="dialog-footer">
-                        <Button label="确认" icon="pi pi-check" onClick={handleDeleteSubmit} autoFocus />
-                        <Button label="取消" icon="pi pi-times" onClick={() => setDeleteVisible(false)} className="p-button-text" />
-                    </div>
-                }
-            >
-                <div className="dialog-form">
-                    <span style={{marginBottom: "10px"}}>
-                        确认是否删除该悬赏?
-                    </span>
-                </div>
-            </Dialog>
-
-            {/*编辑资源弹窗*/}
-            <Dialog
-                header="编辑资源"
-                visible={editVisible}
-                onHide={() => setEditVisible(false)}
-                className="resource-edit-dialog"
-                modal
-                footer={
-                    <div className="dialog-footer">
-                        <Button label="确认" icon="pi pi-check" onClick={handleEditSubmit} autoFocus />
-                        <Button label="取消" icon="pi pi-times" onClick={() => setEditVisible(false)} className="p-button-text" />
-                    </div>
-                }
-            >
-                <div className="dialog-form">
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <label htmlFor="name">更改标题</label>
-                        </div>
-                        <InputText
-                            id="name"
-                            value={editRewardFormData.rewardName}
-                            onChange={(e) => setEditRewardFormData(prev => ({
-                                ...prev,
-                                rewardName:  e.target.value
-                            }))}
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <label htmlFor="price">更改定价</label>
-                        </div>
-                        <InputText
-                            id="price"
-                            value={editRewardFormData.price}
-                            onChange={(e) => setEditRewardFormData(prev => ({
-                                ...prev,
-                                price:  e.target.value
-                            }))}
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <label htmlFor="description">更改需求</label>
-                        </div>
-                        <InputTextarea
-                            id="description"
-                            value={editRewardFormData.rewardDescription}
-                            onChange={(e) => setEditRewardFormData(prev => ({
-                                ...prev,
-                                rewardDescription:  e.target.value
-                            }))}
-                            rows={5}
-                            className="w-full"
-                        />
-                    </div>
-                    <div className="form-field">
-                        <div className="form-field-header">
-                            <span className="form-field-sign">*</span>
-                            <label>封面图片</label>
-                        </div>
-                        <FileUpload
-                            mode="advanced"
-                            name="reward-image"
-                            customUpload
-                            uploadHandler={async (e) => {
-                                const formData = new FormData();
-                                formData.append("file", e.files[0]);
-
-                                try {
-                                    const res = await axios.post(`${process.env.PUBLIC_URL}/file`, formData);
-
-                                    const fileUrl = res.data.url;
-                                    console.log(fileUrl);
-                                    setRewardPictureUrl(fileUrl);
-                                    toast.current?.show({ severity: 'success', summary: '上传成功' });
-                                } catch (error) {
-                                    console.log(error);
-                                    toast.current?.show({ severity: 'error', summary: '上传失败' });
-                                }
-                            }}
-                            auto
-                            accept="image/*"
-                            chooseLabel="选择悬赏封面"
-                        />
-                    </div>
-                </div>
-            </Dialog>
+          <Button label="关注" className="action-button" />
         </div>
-    );
-};
+      </div>
 
+      {/*个人内容*/}
+      <TabView
+        activeIndex={activeIndex}
+        onTabChange={(e) => setActiveIndex(e.index)}
+      >
+        <TabPanel header="主页">
+          {/*发布资源*/}
+          <div className="homepage-item">
+            <div className="section-header">
+              <h1>发布资源</h1>
+              <Button
+                label="显示更多"
+                link
+                onClick={() => router.push("/user/manage/resources/")}
+              />
+            </div>
+            <div className="resource-grid">
+              {resourceList.map((resourceList) => (
+                <Card
+                  key={resourceList.resourceId}
+                  className="resource-card"
+                  onClick={() =>
+                    router.push(
+                      `/resource/resource-detail/${resourceList.resourceId}`
+                    )
+                  }
+                >
+                  <Image
+                    src={resourceList.resourcePicture}
+                    alt={resourceList.resourceName}
+                    width="368"
+                    height="200"
+                  />
+                  <div className="card-content">
+                    <h3>{resourceList.resourceName}</h3>
+                    <div className="view-count">
+                      <Fire theme="outline" size="16" fill="#FF8D1A" />
+                      <span>{resourceList.likes}</span>
+                    </div>
+                  </div>
+                </Card>
+              ))}
+            </div>
+          </div>
+
+          {/*发布帖子*/}
+          <div className="homepage-item">
+            <div className="section-header">
+              <h1>发布帖子</h1>
+              <Button label="显示更多" link onClick={() => setActiveIndex(1)} />
+            </div>
+            <div className="resource-grid">
+              {homePageThread?.records.map((homePageThread) => (
+                <Card
+                  key={homePageThread.threadId}
+                  className="resource-card"
+                  onClick={() =>
+                    router.push(
+                      `/community/thread-detail/${homePageThread.threadId}`
+                    )
+                  }
+                >
+                  <Image
+                    src={homePageThread.threadPicture}
+                    alt={homePageThread.title}
+                    width="368"
+                    height="200"
+                  />
+                  <div className="card-content">
+                    <h3>{homePageThread.title}</h3>
+                    <div className="view-count">
+                      <Fire theme="outline" size="16" fill="#FF8D1A" />
+                      <span>{homePageThread.likes}</span>
+                    </div>
+                  </div>
+                </Card>
+              ))}
+            </div>
+          </div>
+        </TabPanel>
+
+        <TabPanel header="帖子">
+          {/*我的帖子*/}
+          <div className="homepage-item">
+            <div className="section-header">
+              <h1>我的帖子</h1>
+            </div>
+            <div className="resource-grid">
+              {threadList.map((threadList) => (
+                <Card
+                  key={threadList.threadId}
+                  className="resource-card"
+                  onClick={() =>
+                    router.push(
+                      `/community/thread-detail/${threadList.threadId}`
+                    )
+                  }
+                >
+                  <Image
+                    src={threadList.threadPicture}
+                    alt={threadList.title}
+                    width="368"
+                    height="200"
+                  />
+                  <div className="card-content">
+                    <h3>{threadList.title}</h3>
+                    <div className="view-count">
+                      <Fire theme="outline" size="16" fill="#FF8D1A" />
+                      <span>{threadList.likes}</span>
+                    </div>
+                  </div>
+                </Card>
+              ))}
+            </div>
+            {totalThreads > 6 && (
+              <Paginator
+                className="Paginator"
+                first={threadFirst}
+                rows={threadRows}
+                totalRecords={totalThreads}
+                rowsPerPageOptions={[6, 12]}
+                onPageChange={onThreadPageChange}
+              />
+            )}
+          </div>
+        </TabPanel>
+
+        <TabPanel header="收藏"></TabPanel>
+
+        <TabPanel header="数据"></TabPanel>
+
+        <TabPanel header="悬赏">
+          <div className="section-header">
+            <h1>我的悬赏</h1>
+          </div>
+
+          <div className="resource-list">
+            {rewardList.map((rewardItem) => (
+              <Card
+                key={rewardItem.rewardId}
+                className="resources-list-card"
+                onClick={() =>
+                  router.push(`/reward/reward-detail/${rewardItem.rewardId}`)
+                }
+              >
+                <Image
+                  alt="avatar"
+                  src={"rewards/" + rewardItem.rewardPicture}
+                  className="resource-avatar"
+                  width="250"
+                  height="140"
+                />
+                <div className="resource-header">
+                  <div className="resource-content">
+                    <h3>{rewardItem.rewardName}</h3>
+                  </div>
+
+                  <div className="resource-operation">
+                    <Button
+                      label="编辑"
+                      onClick={(e) => {
+                        e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
+                        setEditVisible(true);
+
+                        setEditRewardFormData({
+                          rewardId: rewardItem.rewardId,
+                          rewardName: rewardItem.rewardName,
+                          price: rewardItem.price.toString(),
+                          rewardDescription: rewardItem.rewardDescription,
+                        });
+                        console.log("用户编辑悬赏");
+                      }}
+                    />
+                    <Button
+                      label="删除"
+                      onClick={(e) => {
+                        e.stopPropagation(); // 关键修复:阻止事件冒泡,避免触发Card的点击事件
+                        setDeleteResourceId(rewardItem.rewardId);
+                        setDeleteVisible(true);
+                      }}
+                      style={{ backgroundColor: "rgba(255, 87, 51, 1)" }}
+                    />
+                  </div>
+                </div>
+              </Card>
+            ))}
+
+            {totalRewards > 5 && (
+              <Paginator
+                className="Paginator"
+                first={rewardFirst}
+                rows={rewardRows}
+                totalRecords={totalRewards}
+                rowsPerPageOptions={[5, 10]}
+                onPageChange={onRewardPageChange}
+              />
+            )}
+          </div>
+        </TabPanel>
+      </TabView>
+
+      {/*浮动按钮*/}
+      <div className="card">
+        <SpeedDial
+          model={actions}
+          direction="up"
+          style={{ position: "fixed", bottom: "2rem", right: "2rem" }}
+          showIcon="pi pi-plus"
+          hideIcon="pi pi-times"
+          buttonClassName="custom-speeddial-button"
+        />
+      </div>
+
+      {/*发布资源弹窗*/}
+      <Dialog
+        header="发布资源"
+        visible={visible}
+        onHide={() => setVisible(false)}
+        className="publish-dialog"
+        modal
+        footer={
+          <div className="dialog-footer">
+            <Button
+              label="发布"
+              icon="pi pi-check"
+              onClick={handleSubmit}
+              autoFocus
+            />
+            <Button
+              label="取消"
+              icon="pi pi-times"
+              onClick={() => setVisible(false)}
+              className="p-button-text"
+            />
+          </div>
+        }
+      >
+        <div className="publish-form">
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="name">资源名称</label>
+            </div>
+            <InputText
+              id="name"
+              value={resourceFormData.resource.resourceName}
+              onChange={(e) =>
+                setResourceFormData((prev) => ({
+                  ...prev, // 复制顶层所有属性
+                  resource: {
+                    ...prev.resource, // 复制resource对象的所有属性
+                    resourceName: e.target.value, // 只更新resourceName
+                  },
+                }))
+              }
+              placeholder="请输入资源名称"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="summary">资源简介</label>
+            </div>
+            <InputText
+              id="summary"
+              value={resourceFormData.resource.resourceSummary}
+              onChange={(e) =>
+                setResourceFormData((prev) => ({
+                  ...prev, // 复制顶层所有属性
+                  resource: {
+                    ...prev.resource, // 复制resource对象的所有属性
+                    resourceSummary: e.target.value,
+                  },
+                }))
+              }
+              placeholder="请输入资源简介(一句话)"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="summary">资源版本名</label>
+            </div>
+            <InputText
+              id="summary"
+              value={resourceFormData.resourceVersionName}
+              onChange={(e) =>
+                setResourceFormData((prev) => ({
+                  ...prev, // 复制顶层所有属性
+                  resourceVersionName: e.target.value,
+                }))
+              }
+              placeholder="请输入资源版本名"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <label htmlFor="detail">资源介绍</label>
+            </div>
+            <InputTextarea
+              id="detail"
+              value={resourceFormData.resource.resourceDetail}
+              onChange={(e) =>
+                setResourceFormData((prev) => ({
+                  ...prev, // 复制顶层所有属性
+                  resource: {
+                    ...prev.resource, // 复制resource对象的所有属性
+                    resourceDetail: e.target.value,
+                  },
+                }))
+              }
+              rows={5}
+              placeholder="请输入资源介绍"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="price">价格</label>
+            </div>
+            <InputText
+              id="price"
+              value={resourceFormData.resource.price}
+              onChange={(e) =>
+                setResourceFormData((prev) => ({
+                  ...prev, // 复制顶层所有属性
+                  resource: {
+                    ...prev.resource, // 复制resource对象的所有属性
+                    price: e.target.value,
+                  },
+                }))
+              }
+              placeholder="请输入资源价格"
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="classify">资源分类(请选择一项)</label>
+            </div>
+            <div className="form-field-classify">
+              <div className="flex align-items-center">
+                <RadioButton
+                  inputId="ingredient1"
+                  name="pizza"
+                  value="resourcePack"
+                  onChange={(e: RadioButtonChangeEvent) => {
+                    setResourceFormData((prev) => ({
+                      ...prev, // 复制顶层所有属性
+                      resource: {
+                        ...prev.resource, // 复制resource对象的所有属性
+                        classify: e.target.value,
+                      },
+                    }));
+                    setIngredient(e.value);
+                    console.log(ingredient);
+                    // console.log(resourceFormData.resource.classify);
+                  }}
+                  checked={ingredient === "resourcePack"}
+                />
+                <label htmlFor="ingredient1" className="ml-2">
+                  材质包
+                </label>
+              </div>
+              <div className="flex align-items-center">
+                <RadioButton
+                  inputId="ingredient2"
+                  name="pizza"
+                  value="modPack"
+                  onChange={(e: RadioButtonChangeEvent) => {
+                    setResourceFormData((prev) => ({
+                      ...prev, // 复制顶层所有属性
+                      resource: {
+                        ...prev.resource, // 复制resource对象的所有属性
+                        classify: e.target.value,
+                      },
+                    }));
+                    setIngredient(e.value);
+                  }}
+                  checked={ingredient === "modPack"}
+                />
+                <label htmlFor="ingredient2" className="ml-2">
+                  整合包
+                </label>
+              </div>
+              <div className="flex align-items-center">
+                <RadioButton
+                  inputId="ingredient3"
+                  name="pizza"
+                  value="mod"
+                  onChange={(e: RadioButtonChangeEvent) => {
+                    setResourceFormData((prev) => ({
+                      ...prev, // 复制顶层所有属性
+                      resource: {
+                        ...prev.resource, // 复制resource对象的所有属性
+                        classify: e.target.value,
+                      },
+                    }));
+                    setIngredient(e.value);
+                  }}
+                  checked={ingredient === "mod"}
+                />
+                <label htmlFor="ingredient3" className="ml-2">
+                  模组
+                </label>
+              </div>
+              <div className="flex align-items-center">
+                <RadioButton
+                  inputId="ingredient4"
+                  name="pizza"
+                  value="map"
+                  onChange={(e: RadioButtonChangeEvent) => {
+                    setResourceFormData((prev) => ({
+                      ...prev, // 复制顶层所有属性
+                      resource: {
+                        ...prev.resource, // 复制resource对象的所有属性
+                        classify: e.target.value,
+                      },
+                    }));
+                    setIngredient(e.value);
+                  }}
+                  checked={ingredient === "map"}
+                />
+                <label htmlFor="ingredient4" className="ml-2">
+                  地图
+                </label>
+              </div>
+            </div>
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label htmlFor="gameplayList">资源标签</label>
+            </div>
+            <MultiSelect
+              value={selectedGameplay}
+              onChange={(e: MultiSelectChangeEvent) => {
+                const selectedOptions = e.value as GameplayOption[];
+                // 提取选中项的 name 属性组成字符串数组
+                const selectedNames = selectedOptions.map((item) => item.name);
+
+                setResourceFormData((prev) => ({
+                  ...prev,
+                  gameplayList: selectedNames,
+                }));
+                setSelectedGameplay(selectedOptions);
+              }}
+              options={gameplayOptions}
+              display="chip"
+              optionLabel="name"
+              placeholder="请选择资源标签"
+              className="w-full md:w-20rem"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label>封面图片</label>
+            </div>
+            <FileUpload
+              mode="advanced"
+              name="resource-image"
+              customUpload
+              uploadHandler={async (e) => {
+                const formData = new FormData();
+                formData.append("file", e.files[0]);
+
+                try {
+                  const res = await axios.post(
+                    `${process.env.PUBLIC_URL}/file`,
+                    formData
+                  );
+
+                  const fileUrl = res.data.url;
+                  console.log(fileUrl);
+                  setResourcePictureUrl(fileUrl);
+                  toast.current?.show({
+                    severity: "success",
+                    summary: "上传成功",
+                  });
+                } catch (error) {
+                  console.log(error);
+                  toast.current?.show({
+                    severity: "error",
+                    summary: "上传失败",
+                  });
+                }
+              }}
+              auto
+              chooseLabel="上传资源封面"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label>上传资源文件</label>
+            </div>
+            <FileUpload
+              mode="advanced"
+              name="resource-file"
+              customUpload
+              uploadHandler={async (e) => {
+                const formData = new FormData();
+                formData.append("file", e.files[0]);
+
+                try {
+                  const res = await axios.post(
+                    `${process.env.PUBLIC_URL}/file`,
+                    formData
+                  );
+                  const fileUrl = res.data;
+                  console.log("上传的 torrent 文件 URL:", fileUrl);
+                  setTorrentUrl(fileUrl);
+                  toast.current?.show({
+                    severity: "success",
+                    summary: "上传成功",
+                    detail: "资源文件已上传",
+                  });
+                } catch (error) {
+                  console.error("上传资源文件失败:", error);
+                  toast.current?.show({
+                    severity: "error",
+                    summary: "上传失败",
+                    detail: "资源文件上传失败",
+                  });
+                }
+              }}
+              auto
+              chooseLabel="上传资源文件(.torrent)"
+            />
+          </div>
+        </div>
+      </Dialog>
+
+      {/*删除悬赏弹窗*/}
+      <Dialog
+        header="删除悬赏"
+        visible={deleteVisible}
+        onHide={() => setDeleteVisible(false)}
+        className="resource-delete-dialog"
+        modal
+        footer={
+          <div className="dialog-footer">
+            <Button
+              label="确认"
+              icon="pi pi-check"
+              onClick={handleDeleteSubmit}
+              autoFocus
+            />
+            <Button
+              label="取消"
+              icon="pi pi-times"
+              onClick={() => setDeleteVisible(false)}
+              className="p-button-text"
+            />
+          </div>
+        }
+      >
+        <div className="dialog-form">
+          <span style={{ marginBottom: "10px" }}>确认是否删除该悬赏?</span>
+        </div>
+      </Dialog>
+
+      {/*编辑资源弹窗*/}
+      <Dialog
+        header="编辑资源"
+        visible={editVisible}
+        onHide={() => setEditVisible(false)}
+        className="resource-edit-dialog"
+        modal
+        footer={
+          <div className="dialog-footer">
+            <Button
+              label="确认"
+              icon="pi pi-check"
+              onClick={handleEditSubmit}
+              autoFocus
+            />
+            <Button
+              label="取消"
+              icon="pi pi-times"
+              onClick={() => setEditVisible(false)}
+              className="p-button-text"
+            />
+          </div>
+        }
+      >
+        <div className="dialog-form">
+          <div className="form-field">
+            <div className="form-field-header">
+              <label htmlFor="name">更改标题</label>
+            </div>
+            <InputText
+              id="name"
+              value={editRewardFormData.rewardName}
+              onChange={(e) =>
+                setEditRewardFormData((prev) => ({
+                  ...prev,
+                  rewardName: e.target.value,
+                }))
+              }
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <label htmlFor="price">更改定价</label>
+            </div>
+            <InputText
+              id="price"
+              value={editRewardFormData.price}
+              onChange={(e) =>
+                setEditRewardFormData((prev) => ({
+                  ...prev,
+                  price: e.target.value,
+                }))
+              }
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <label htmlFor="description">更改需求</label>
+            </div>
+            <InputTextarea
+              id="description"
+              value={editRewardFormData.rewardDescription}
+              onChange={(e) =>
+                setEditRewardFormData((prev) => ({
+                  ...prev,
+                  rewardDescription: e.target.value,
+                }))
+              }
+              rows={5}
+              className="w-full"
+            />
+          </div>
+          <div className="form-field">
+            <div className="form-field-header">
+              <span className="form-field-sign">*</span>
+              <label>封面图片</label>
+            </div>
+            <FileUpload
+              mode="advanced"
+              name="reward-image"
+              customUpload
+              uploadHandler={async (e) => {
+                const formData = new FormData();
+                formData.append("file", e.files[0]);
+
+                try {
+                  const res = await axios.post(
+                    `${process.env.PUBLIC_URL}/file`,
+                    formData
+                  );
+
+                  const fileUrl = res.data.url;
+                  console.log(fileUrl);
+                  setRewardPictureUrl(fileUrl);
+                  toast.current?.show({
+                    severity: "success",
+                    summary: "上传成功",
+                  });
+                } catch (error) {
+                  console.log(error);
+                  toast.current?.show({
+                    severity: "error",
+                    summary: "上传失败",
+                  });
+                }
+              }}
+              auto
+              accept="image/*"
+              chooseLabel="选择悬赏封面"
+            />
+          </div>
+        </div>
+      </Dialog>
+    </div>
+  );
+}
diff --git a/src/app/user/purchased-resources/page.tsx b/src/app/user/purchased-resources/page.tsx
index c48b626..11284ff 100644
--- a/src/app/user/purchased-resources/page.tsx
+++ b/src/app/user/purchased-resources/page.tsx
@@ -1,12 +1,169 @@
 'use client';
-import React from 'react';
+import React, { useEffect, useState, useRef } from "react";
+import { Card } from 'primereact/card';
+import { Image } from 'primereact/image';
 
-const EmptyPage: React.FC = () => {
+import { Dialog } from 'primereact/dialog';
+// 页面跳转
+import { useRouter } from 'next/navigation';
+// 消息提醒
+import { Toast } from 'primereact/toast';
+// 分页
+import { Paginator, type PaginatorPageChangeEvent } from 'primereact/paginator';
+
+import { Button } from 'primereact/button';
+// 接口传输
+import axios from 'axios';
+// 标签
+import { Tag } from 'primereact/tag';
+
+
+import { useLocalStorage } from '../../hook/useLocalStorage';
+
+import "./purchased-resource.scss"
+interface User {
+  Id: number;
+}
+// 热门资源数据
+interface Torrent {
+  torrentRecordId: number;
+  torrentUrl: string;
+  infoHash: string;
+  uploadTime: string;
+  uploaderUserId: number;
+}
+
+interface ResourceVersion {
+  resourceVersionId: number;
+  resourceVersionName: string;
+  compatibleVersions: string[];
+  torrentList: Torrent[];
+  seeds: number;
+}
+
+interface Resource {
+  resourceId: number;
+  resourceName: string;
+  resourcePicture: string;
+  resourceSummary: string;
+  lastUpdateTime: string;
+  hot: number;
+  gameplayList: string[];
+  resourceVersionList: ResourceVersion[];
+}
+interface ResourceList {
+  records: Resource[];
+  total: number;
+}
+
+export default function PurchasedResource() {
+  const user = useLocalStorage<User>('user');
+  const userId: number = user?.Id ?? -1;
+  // 热门资源列表
+  const [resources, setResources] = useState<Resource[]>([]);
+  const [totalResource, setTotalResource] = useState(0);
+  const [visible, setVisible] = useState<boolean>(false);
+  const [selectedResource, setSelectedResource] = useState<Resource | null>(null);
+  // 消息提醒
+  const toast = useRef<Toast>(null);
+  const router = useRouter();
+
+  // 分页
+  const [first, setFirst] = useState(0);
+  const [rows, setRows] = useState(5);
+  const onPageChange = (event: PaginatorPageChangeEvent) => {
+    setFirst(event.first);
+    setRows(event.rows);
+  };
+  // 获取帖子列表
+  useEffect(() => {
+    handleSearch();
+  }, [first, rows]);
+
+  const handleSearch = async () => {
+
+    try {
+      const pageNumber = first / rows + 1;
+      const response = await axios.get<ResourceList>(process.env.PUBLIC_URL + `/user/purchase`, {
+        params: {
+          userId,
+          pageNumber,
+          rows
+        }
+      });
+      console.log(response.data.records);
+      setResources(response.data.records);
+      setTotalResource(response.data.total);
+    } catch (err) {
+      console.error('搜索资源失败', err);
+      toast.current?.show({ severity: 'error', summary: 'error', detail: '搜索资源失败' });
+    }
+  };
+
+
   return (
-    <div className="p-d-flex p-jc-center p-ai-center" style={{ height: '100vh' }}>
-      {"一个空页面"}
+    <div className="PurchasedResource">
+      <div className="header">
+        <h1>我的资源库</h1>
+      </div>
+      {/* 全部社区 */}
+      <div className="all-resources-list">
+        {resources.map((resource) => (
+          <Card key={resource.resourceId} className="all-resources-card">
+            <Image alt="avatar" src={process.env.NEXT_PUBLIC_NGINX_URL + "Resource/" + resource.resourcePicture} className="resource-avatar" width="250" height="140" onClick={() => router.push(`/resource/resource-detail/${resource.resourceId}`)} />
+            <div className="resource-header">
+              <div className="resource-content">
+                <h3>{resource.resourceName}</h3>
+                <div className="tags">
+                  {resource.gameplayList.map((tag, index) => (
+                    <Tag key={index} value={tag} />
+                  ))}
+                </div>
+              </div>
+              <div className="resources-states">
+                <Button
+                  label="下载"
+                  className="classificationButton"
+                  onClick={() => {
+                    setSelectedResource(resource);
+                    setVisible(true);
+                  }}
+                />
+              </div>
+            </div>
+          </Card>
+        ))}
+      </div>
+      {totalResource > 5 && (<Paginator className="Paginator" first={first} rows={rows} totalRecords={totalResource} rowsPerPageOptions={[5, 10]} onPageChange={onPageChange} />)}
+      <Dialog
+        header="选择版本并下载"
+        visible={visible}
+        style={{ width: '50vw' }}
+        onHide={() => {
+          setVisible(false);
+          setSelectedResource(null);
+        }}
+      >
+        {selectedResource?.resourceVersionList.map((version) => (
+          <div key={version.resourceVersionId} style={{ marginBottom: '1.5rem' }}>
+            <h4>{version.resourceVersionName}</h4>
+            <p>兼容版本: {version.compatibleVersions.join(', ')}</p>
+            <div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
+              {version.torrentList.map((torrent) => (
+                <Button
+                  key={torrent.torrentRecordId}
+                  label={`种子:${torrent.torrentUrl}`}
+                  onClick={() => {
+                    window.open(torrent.torrentUrl, '_blank');
+                  }}
+                  className="p-button-sm"
+                />
+              ))}
+            </div>
+          </div>
+        ))}
+      </Dialog>
     </div>
   );
 };
 
-export default EmptyPage;
diff --git a/src/app/user/purchased-resources/purchased-resource.scss b/src/app/user/purchased-resources/purchased-resource.scss
new file mode 100644
index 0000000..5e466b6
--- /dev/null
+++ b/src/app/user/purchased-resources/purchased-resource.scss
@@ -0,0 +1,5 @@
+.PurchasedResource {
+    max-width: 1200px;
+    margin: 0 auto;
+    padding: 0 2rem;
+}
\ No newline at end of file