feat(api): 重构 API 调用并优化用户认证流程

- 新增 auth、forum 和 user API 文件夹,重新组织 API 调用结构
- 重构 AuthContext,使用新 API 进行用户认证和信息管理
- 更新 AdminPanel、ForumPage 等组件,使用新的 API 调用
- 删除旧的 authApi.js 文件,清理冗余代码
- 优化用户登录、注册和登出流程,改进错误处理和用户提示

Change-Id: If664193e1bf30036c197f164edc5b10df75f1331
diff --git a/src/api/auth.js b/src/api/auth.js
new file mode 100644
index 0000000..81a7d9b
--- /dev/null
+++ b/src/api/auth.js
@@ -0,0 +1,45 @@
+import request from "@/utils/request";
+
+// 用户认证相关API
+export const userLogin = (params) => {
+  return request.post("/user/login", {...params});
+};
+
+export const adminLogin = (params) => {
+  return request.post("/admin/login", {...params});
+};
+
+export const registerUser = (params) => {
+  return request.post("/user/register", {...params});
+};
+
+export const updateUsername = (params) => {
+  return request.post("/user/update/username", {...params});
+};
+
+export const updatePassword = (params) => {
+  return request.post("/user/update/password", {...params});
+};
+
+export const updateEmail = (params) => {
+  return request.post("/user/update/email", {...params});
+};
+
+export const getUserList = (params) => {
+  return request.get('/user/list', {params});
+};
+
+export const deleteUser = (params) => {
+  return request.delete("/user/delete", {params});
+};
+
+export const logoutUser = () => {
+  // 清除本地存储
+  localStorage.removeItem("token");
+  localStorage.removeItem("user");
+
+  return Promise.resolve({
+    success: true,
+    message: "注销成功",
+  });
+}; 
\ No newline at end of file
diff --git a/src/api/forum.js b/src/api/forum.js
new file mode 100644
index 0000000..61518be
--- /dev/null
+++ b/src/api/forum.js
@@ -0,0 +1,31 @@
+import request from "@/utils/request";
+
+// 帖子相关API
+export const createPost = (params) => {
+  return request.post("/posts/create", {...params});
+};
+
+export const getPosts = (params) => {
+  return request.get("/posts/list", {params});
+};
+
+export const deletePost = (username, pid) => {
+  return request.delete("/posts/delete", {
+    data: { username, pid },
+  });
+};
+
+// 评论相关API
+export const addComment = (params) => {
+  return request.post("/comment/add", {...params});
+};
+
+export const getComments = (params) => {
+  return request.get('/comment/get', {params});
+};
+
+export const deleteComment = (username, commentId) => {
+  return request.delete("/comment/delete", {
+    data: { username, commentId },
+  });
+}; 
\ No newline at end of file
diff --git a/src/api/user.js b/src/api/user.js
new file mode 100644
index 0000000..7ac2d72
--- /dev/null
+++ b/src/api/user.js
@@ -0,0 +1,35 @@
+import request from "@/utils/request";
+
+// 用户资料相关API
+export const getUserProfile = (username) => {
+  return request.get(`/user/profile/${username}`);
+};
+
+export const updateUserProfile = (userData) => {
+  return request.put("/user/profile", userData);
+};
+
+export const uploadAvatar = (formData) => {
+  return request.post("/user/avatar", formData, {
+    headers: {
+      'Content-Type': 'multipart/form-data',
+    },
+  });
+};
+
+// PT站统计信息API
+export const getUserStats = (username) => {
+  return request.get(`/user/stats/${username}`);
+};
+
+export const getUserTorrents = (username, type = 'all') => {
+  return request.get(`/user/torrents/${username}`, {
+    params: { type } // type: 'seeding', 'leeching', 'completed', 'all'
+  });
+};
+
+export const getUserHistory = (username, page = 1, limit = 10) => {
+  return request.get(`/user/history/${username}`, {
+    params: { page, limit }
+  });
+}; 
\ No newline at end of file
diff --git a/src/assets/react.svg b/src/assets/react.svg
deleted file mode 100644
index 6c87de9..0000000
--- a/src/assets/react.svg
+++ /dev/null
@@ -1 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="35.93" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 228"><path fill="#00D8FF" d="M210.483 73.824a171.49 171.49 0 0 0-8.24-2.597c.465-1.9.893-3.777 1.273-5.621c6.238-30.281 2.16-54.676-11.769-62.708c-13.355-7.7-35.196.329-57.254 19.526a171.23 171.23 0 0 0-6.375 5.848a155.866 155.866 0 0 0-4.241-3.917C100.759 3.829 77.587-4.822 63.673 3.233C50.33 10.957 46.379 33.89 51.995 62.588a170.974 170.974 0 0 0 1.892 8.48c-3.28.932-6.445 1.924-9.474 2.98C17.309 83.498 0 98.307 0 113.668c0 15.865 18.582 31.778 46.812 41.427a145.52 145.52 0 0 0 6.921 2.165a167.467 167.467 0 0 0-2.01 9.138c-5.354 28.2-1.173 50.591 12.134 58.266c13.744 7.926 36.812-.22 59.273-19.855a145.567 145.567 0 0 0 5.342-4.923a168.064 168.064 0 0 0 6.92 6.314c21.758 18.722 43.246 26.282 56.54 18.586c13.731-7.949 18.194-32.003 12.4-61.268a145.016 145.016 0 0 0-1.535-6.842c1.62-.48 3.21-.974 4.76-1.488c29.348-9.723 48.443-25.443 48.443-41.52c0-15.417-17.868-30.326-45.517-39.844Zm-6.365 70.984c-1.4.463-2.836.91-4.3 1.345c-3.24-10.257-7.612-21.163-12.963-32.432c5.106-11 9.31-21.767 12.459-31.957c2.619.758 5.16 1.557 7.61 2.4c23.69 8.156 38.14 20.213 38.14 29.504c0 9.896-15.606 22.743-40.946 31.14Zm-10.514 20.834c2.562 12.94 2.927 24.64 1.23 33.787c-1.524 8.219-4.59 13.698-8.382 15.893c-8.067 4.67-25.32-1.4-43.927-17.412a156.726 156.726 0 0 1-6.437-5.87c7.214-7.889 14.423-17.06 21.459-27.246c12.376-1.098 24.068-2.894 34.671-5.345a134.17 134.17 0 0 1 1.386 6.193ZM87.276 214.515c-7.882 2.783-14.16 2.863-17.955.675c-8.075-4.657-11.432-22.636-6.853-46.752a156.923 156.923 0 0 1 1.869-8.499c10.486 2.32 22.093 3.988 34.498 4.994c7.084 9.967 14.501 19.128 21.976 27.15a134.668 134.668 0 0 1-4.877 4.492c-9.933 8.682-19.886 14.842-28.658 17.94ZM50.35 144.747c-12.483-4.267-22.792-9.812-29.858-15.863c-6.35-5.437-9.555-10.836-9.555-15.216c0-9.322 13.897-21.212 37.076-29.293c2.813-.98 5.757-1.905 8.812-2.773c3.204 10.42 7.406 21.315 12.477 32.332c-5.137 11.18-9.399 22.249-12.634 32.792a134.718 134.718 0 0 1-6.318-1.979Zm12.378-84.26c-4.811-24.587-1.616-43.134 6.425-47.789c8.564-4.958 27.502 2.111 47.463 19.835a144.318 144.318 0 0 1 3.841 3.545c-7.438 7.987-14.787 17.08-21.808 26.988c-12.04 1.116-23.565 2.908-34.161 5.309a160.342 160.342 0 0 1-1.76-7.887Zm110.427 27.268a347.8 347.8 0 0 0-7.785-12.803c8.168 1.033 15.994 2.404 23.343 4.08c-2.206 7.072-4.956 14.465-8.193 22.045a381.151 381.151 0 0 0-7.365-13.322Zm-45.032-43.861c5.044 5.465 10.096 11.566 15.065 18.186a322.04 322.04 0 0 0-30.257-.006c4.974-6.559 10.069-12.652 15.192-18.18ZM82.802 87.83a323.167 323.167 0 0 0-7.227 13.238c-3.184-7.553-5.909-14.98-8.134-22.152c7.304-1.634 15.093-2.97 23.209-3.984a321.524 321.524 0 0 0-7.848 12.897Zm8.081 65.352c-8.385-.936-16.291-2.203-23.593-3.793c2.26-7.3 5.045-14.885 8.298-22.6a321.187 321.187 0 0 0 7.257 13.246c2.594 4.48 5.28 8.868 8.038 13.147Zm37.542 31.03c-5.184-5.592-10.354-11.779-15.403-18.433c4.902.192 9.899.29 14.978.29c5.218 0 10.376-.117 15.453-.343c-4.985 6.774-10.018 12.97-15.028 18.486Zm52.198-57.817c3.422 7.8 6.306 15.345 8.596 22.52c-7.422 1.694-15.436 3.058-23.88 4.071a382.417 382.417 0 0 0 7.859-13.026a347.403 347.403 0 0 0 7.425-13.565Zm-16.898 8.101a358.557 358.557 0 0 1-12.281 19.815a329.4 329.4 0 0 1-23.444.823c-7.967 0-15.716-.248-23.178-.732a310.202 310.202 0 0 1-12.513-19.846h.001a307.41 307.41 0 0 1-10.923-20.627a310.278 310.278 0 0 1 10.89-20.637l-.001.001a307.318 307.318 0 0 1 12.413-19.761c7.613-.576 15.42-.876 23.31-.876H128c7.926 0 15.743.303 23.354.883a329.357 329.357 0 0 1 12.335 19.695a358.489 358.489 0 0 1 11.036 20.54a329.472 329.472 0 0 1-11 20.722Zm22.56-122.124c8.572 4.944 11.906 24.881 6.52 51.026c-.344 1.668-.73 3.367-1.15 5.09c-10.622-2.452-22.155-4.275-34.23-5.408c-7.034-10.017-14.323-19.124-21.64-27.008a160.789 160.789 0 0 1 5.888-5.4c18.9-16.447 36.564-22.941 44.612-18.3ZM128 90.808c12.625 0 22.86 10.235 22.86 22.86s-10.235 22.86-22.86 22.86s-22.86-10.235-22.86-22.86s10.235-22.86 22.86-22.86Z"></path></svg>
\ No newline at end of file
diff --git a/src/features/admin/pages/AdminPanel.jsx b/src/features/admin/pages/AdminPanel.jsx
index 93d8d87..3717b52 100644
--- a/src/features/admin/pages/AdminPanel.jsx
+++ b/src/features/admin/pages/AdminPanel.jsx
@@ -1,7 +1,7 @@
 import React, { useState, useEffect } from 'react';
 import { Card, Table, Button, Space, Typography, message, Popconfirm, Spin } from 'antd';
 import { UserOutlined, UploadOutlined, SettingOutlined } from '@ant-design/icons';
-import { getUserList, deleteUser } from '../../auth/services/authApi';
+import { getUserList, deleteUser } from '@/api/auth';
 
 const { Title } = Typography;
 
diff --git a/src/features/auth/contexts/AuthContext.jsx b/src/features/auth/contexts/AuthContext.jsx
index 5f9b37e..b0afd8e 100644
--- a/src/features/auth/contexts/AuthContext.jsx
+++ b/src/features/auth/contexts/AuthContext.jsx
@@ -1,7 +1,13 @@
-import React, { createContext, useContext, useState, useEffect, useCallback } from 'react';
-import { loginUser, registerUser, getUserInfo, logoutUser } from '../services/authApi';
-import { message } from 'antd';
-import { useNavigate } from 'react-router-dom'; // 导入 useNavigate
+import React, {
+  createContext,
+  useContext,
+  useState,
+  useEffect,
+  useCallback,
+} from "react";
+import { userLogin, registerUser, logoutUser } from "@/api/auth";
+import { message } from "antd";
+import { useNavigate } from "react-router-dom"; // 导入 useNavigate
 
 const AuthContext = createContext(null);
 
@@ -14,22 +20,27 @@
   const loadAuthData = useCallback(() => {
     setLoading(true);
     try {
-      const storedToken = localStorage.getItem('authToken'); // 假设您使用token
-      const storedUser = localStorage.getItem('user');
+      const storedToken = localStorage.getItem("token");
+      const storedUser = localStorage.getItem("user");
+
+      console.log("Loading auth data - token:", !!storedToken, "user:", !!storedUser);
 
       if (storedToken && storedUser) {
-        setUser(JSON.parse(storedUser));
-        setIsAuthenticated(true);
-        // 调用API获取最新的用户信息
-        getUserInfo().then(response => { 
-          if (response.data && response.data.user) {
-            setUser(response.data.user);
-            localStorage.setItem('user', JSON.stringify(response.data.user));
-          }
-        }).catch(error => {
-          console.error("获取用户信息失败", error);
-        });
+        try {
+          const userData = JSON.parse(storedUser);
+          // console.log("Parsed user data:", userData);
+          setUser(userData);
+          setIsAuthenticated(true);
+        } catch (parseError) {
+          console.error("Failed to parse stored user data:", parseError);
+          // 如果解析失败,清除损坏的数据
+          localStorage.removeItem("token");
+          localStorage.removeItem("user");
+          setIsAuthenticated(false);
+          setUser(null);
+        }
       } else {
+        console.log("No stored auth data found");
         setIsAuthenticated(false);
         setUser(null);
       }
@@ -46,23 +57,32 @@
     loadAuthData();
   }, [loadAuthData]);
 
-  const login = async (credentials) => {
+  const login = async (params) => {
     setLoading(true);
     try {
-      const response = await loginUser(credentials);
-      const { token, user: userData } = response.data;
-      
-      localStorage.setItem('authToken', token);
-      localStorage.setItem('user', JSON.stringify(userData));
-      setUser(userData);
-      setIsAuthenticated(true);
-      message.success('登录成功');
-      return userData;
+      const response = await userLogin(params);
+      // 检查响应是否成功
+      if (response && response.data) {
+        const token = response.data.token;
+        const userData = response.data;
+        
+        console.log("Saving token:", token);
+        console.log("Saving user data:", userData);
+        
+        localStorage.setItem("token", token);
+        localStorage.setItem("user", JSON.stringify(userData));
+        
+        setUser(userData);
+        setIsAuthenticated(true);
+        
+        message.success(response?.message || "登录成功");
+        return userData;
+      }
     } catch (error) {
-      console.error("Login failed", error);
+      console.log("login error", error);
       setIsAuthenticated(false);
       setUser(null);
-      message.error(error.message || '登录失败,请检查用户名和密码');
+      message.error(error.message || "登录失败,请检查用户名和密码");
     } finally {
       setLoading(false);
     }
@@ -72,17 +92,23 @@
     setLoading(true);
     try {
       const response = await registerUser(userData);
-      const { token, user: newUser } = response.data;
 
-      localStorage.setItem('authToken', token);
-      localStorage.setItem('user', JSON.stringify(newUser));
-      setUser(newUser);
-      setIsAuthenticated(true);
-      message.success('注册成功');
-      return newUser;
+      // 检查响应是否成功
+      if (response.data && response.data.success) {
+        const { token, user: newUser } = response.data.data;
+
+        localStorage.setItem("token", token);
+        localStorage.setItem("user", JSON.stringify(newUser));
+        setUser(newUser);
+        setIsAuthenticated(true);
+        message.success("注册成功");
+        return newUser;
+      } else {
+        throw new Error(response.data?.message || "注册失败");
+      }
     } catch (error) {
       console.error("Registration failed", error);
-      message.error(error.message || '注册失败,请稍后再试');
+      message.error(error.message || "注册失败,请稍后再试");
     } finally {
       setLoading(false);
     }
@@ -91,24 +117,27 @@
   const logout = async () => {
     try {
       await logoutUser();
-      localStorage.removeItem('authToken');
-      localStorage.removeItem('user');
-      localStorage.removeItem('permissions'); // 移除旧的权限存储
+      localStorage.removeItem("token");
+      localStorage.removeItem("user");
+      localStorage.removeItem("permissions"); // 移除旧的权限存储
       setUser(null);
       setIsAuthenticated(false);
-      message.success('已成功退出登录');
-      navigate('/login');
+      message.success("已成功退出登录");
+      navigate("/login");
       return true;
     } catch (error) {
       console.error("登出失败", error);
-      message.error('登出失败');
+      message.error("登出失败");
       return false;
     }
   };
 
-  const hasRole = useCallback((roleName) => {
-    return user?.role === roleName;
-  }, [user]);
+  const hasRole = useCallback(
+    (roleName) => {
+      return user?.role === roleName;
+    },
+    [user]
+  );
 
   const value = {
     user,
@@ -118,7 +147,7 @@
     register,
     logout,
     hasRole,
-    reloadAuthData: loadAuthData // 暴露一个重新加载数据的方法
+    reloadAuthData: loadAuthData, // 暴露一个重新加载数据的方法
   };
 
   return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
@@ -126,8 +155,9 @@
 
 export const useAuth = () => {
   const context = useContext(AuthContext);
-  if (context === undefined || context === null) { // 增加了对 null 的检查
-    throw new Error('useAuth must be used within an AuthProvider');
+  if (context === undefined || context === null) {
+    // 增加了对 null 的检查
+    throw new Error("useAuth must be used within an AuthProvider");
   }
   return context;
-};
\ No newline at end of file
+};
diff --git a/src/features/auth/pages/LoginPage.jsx b/src/features/auth/pages/LoginPage.jsx
index 19434a4..3a8cdbc 100644
--- a/src/features/auth/pages/LoginPage.jsx
+++ b/src/features/auth/pages/LoginPage.jsx
@@ -14,7 +14,6 @@
 } from "antd";
 import { UserOutlined, LockOutlined } from "@ant-design/icons";
 import { useAuth } from "../contexts/AuthContext"; // 使用新的 AuthContext
-// import { loginUser } from '../services/authApi'; // 如果不直接在 context 中调用 API
 
 const { Title, Text } = Typography;
 
@@ -33,10 +32,18 @@
   const onFinish = async (values) => {
     setLoading(true);
     try {
-      await login({ username: values.username, password: values.password });
-      // 登录成功后的导航由 AuthContext 内部或 ProtectedRoute 处理
-      // AuthContext 已经包含成功提示,这里不再重复提示
-      navigate("/"); // 或者根据用户角色导航到不同页面
+      const params = {
+        username: values.username,
+        password: values.password,
+      };
+      const userData = await login(params);
+      
+      // 根据用户角色导航到不同页面
+      if (userData && userData.role === 'admin') {
+        navigate("/admin"); // 管理员导航到管理面板
+      } else {
+        navigate("/"); // 普通用户导航到首页
+      }
     } catch (error) {
       // 错误消息由 AuthContext 中的 login 方法或 request 拦截器处理
       console.error("Login page error:", error);
diff --git a/src/features/auth/services/authApi.js b/src/features/auth/services/authApi.js
deleted file mode 100644
index dd40a80..0000000
--- a/src/features/auth/services/authApi.js
+++ /dev/null
@@ -1,165 +0,0 @@
-// src/features/auth/services/authApi.js
-import request from "../../../services/request";
-import { message } from "antd";
-
-// 使用API前缀
-const API_PREFIX = "/user";
-const ADMIN_PREFIX = "/admin";
-
-// 导出API函数
-export const loginUser = (credentials) => {
-  return request.post(`${API_PREFIX}/login`, credentials).then((response) => {
-    if (response.data && response.data.success) {
-      // 保存token和用户信息到localStorage
-      localStorage.setItem("token", response.data.data.token);
-      localStorage.setItem("user", JSON.stringify(response.data.data.user));
-      return response.data;
-    } else {
-      return Promise.reject(new Error(response.data.message || "登录失败"));
-    }
-  });
-};
-
-export const adminLogin = (credentials) => {
-  return request.post(`${ADMIN_PREFIX}/login`, credentials).then((response) => {
-    if (response.data && response.data.success) {
-      // 保存token和用户信息到localStorage
-      localStorage.setItem("token", response.data.data.token);
-      localStorage.setItem("user", JSON.stringify(response.data.data.user));
-      return response.data;
-    } else {
-      return Promise.reject(new Error(response.data.message || "管理员登录失败"));
-    }
-  });
-};
-
-export const registerUser = (userData) => {
-  return request.post(`${API_PREFIX}/register`, userData).then((response) => {
-    if (response.data && response.data.success) {
-      return response.data;
-    } else {
-      return Promise.reject(new Error(response.data.message || "注册失败"));
-    }
-  });
-};
-
-export const updateUsername = (username, newUsername) => {
-  const token = localStorage.getItem("token");
-  return request
-    .post(`${API_PREFIX}/update/username`, 
-    { username, newUsername }, 
-    { headers: { token } })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        // 更新本地存储的用户信息
-        const user = JSON.parse(localStorage.getItem("user") || "{}");
-        user.username = newUsername;
-        localStorage.setItem("user", JSON.stringify(user));
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "修改用户名失败")
-        );
-      }
-    });
-};
-
-export const updatePassword = (username, newPassword) => {
-  const token = localStorage.getItem("token");
-  return request
-    .post(`${API_PREFIX}/update/password`, 
-    { username, newPassword }, 
-    { headers: { token } })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "修改密码失败")
-        );
-      }
-    });
-};
-
-export const updateEmail = (username, newEmail) => {
-  const token = localStorage.getItem("token");
-  return request
-    .post(`${API_PREFIX}/update/email`, 
-    { username, newEmail }, 
-    { headers: { token } })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        // 更新本地存储的用户信息
-        const user = JSON.parse(localStorage.getItem("user") || "{}");
-        user.email = newEmail;
-        localStorage.setItem("user", JSON.stringify(user));
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "修改邮箱失败")
-        );
-      }
-    });
-};
-
-export const getUserInfo = (username) => {
-  const token = localStorage.getItem("token");
-  return request
-    .get(`${API_PREFIX}/get/info?username=${username}`, 
-    { headers: { token } })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "获取用户信息失败")
-        );
-      }
-    });
-};
-
-export const getUserList = (username) => {
-  const token = localStorage.getItem("token");
-  return request
-    .get(`/user/list?username=${username}`, 
-    { headers: { token } })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "获取用户列表失败")
-        );
-      }
-    });
-};
-
-export const deleteUser = (username, targetUsername) => {
-  const token = localStorage.getItem("token");
-  return request
-    .delete(`/user/delete`, 
-    { 
-      headers: { token },
-      data: { username, targetUsername }
-    })
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(
-          new Error(response.data.message || "删除用户失败")
-        );
-      }
-    });
-};
-
-export const logoutUser = () => {
-  // 清除本地存储
-  localStorage.removeItem("token");
-  localStorage.removeItem("user");
-
-  return Promise.resolve({
-    success: true,
-    message: "注销成功"
-  });
-};
diff --git a/src/features/forum/pages/ForumPage.jsx b/src/features/forum/pages/ForumPage.jsx
index 7e6e78f..54638fc 100644
--- a/src/features/forum/pages/ForumPage.jsx
+++ b/src/features/forum/pages/ForumPage.jsx
@@ -1,6 +1,20 @@
-import React, { useState, useEffect } from 'react';
-import { List, Avatar, Space, Tag, Typography, Button, message, Modal, Form, Input, Spin } from 'antd';
-import { getPosts, createPost } from '../services/forumApi';
+import React, { useState, useEffect } from "react";
+import { Link } from "react-router-dom";
+import {
+  List,
+  Avatar,
+  Space,
+  Tag,
+  Typography,
+  Button,
+  message,
+  Modal,
+  Form,
+  Input,
+  Spin,
+} from "antd";
+import { getPosts, createPost } from "@/api/forum";
+import { useAuth } from "@/features/auth/contexts/AuthContext";
 
 const { Title, Paragraph, Text } = Typography;
 const { TextArea } = Input;
@@ -10,68 +24,125 @@
   const [loading, setLoading] = useState(true);
   const [isModalOpen, setIsModalOpen] = useState(false);
   const [form] = Form.useForm();
-  
-  // 获取用户信息
-  const user = JSON.parse(localStorage.getItem('user') || '{}');
-  
+
+  // 使用 AuthProvider 获取用户信息
+  const { user, isAuthenticated } = useAuth();
+
   // 加载帖子数据
   useEffect(() => {
-    fetchPosts();
-  }, []);
-  
+    // 只有在用户已认证且有用户信息时才获取帖子
+    if (isAuthenticated && user?.username) {
+      fetchPosts();
+    }
+  }, [isAuthenticated, user]);
+
   // 获取帖子列表
   const fetchPosts = async () => {
     try {
       setLoading(true);
+      console.log("正在获取帖子列表,用户名:", user.username);
       const response = await getPosts({ username: user.username });
-      if (response.success) {
-        setPosts(response.data.posts || []);
+      console.log("获取帖子列表响应:", response);
+
+      if (response) {
+        const posts = response.data?.posts || [];
+        console.log("获取到的帖子数量:", posts.length);
+        console.log("帖子数据结构:", posts[0]); // 查看第一个帖子的数据结构
+        setPosts(posts);
+      } else {
+        console.error("获取帖子列表失败:", response.data);
+        message.error(response.data?.message || "获取帖子列表失败");
       }
     } catch (error) {
-      message.error(error.message || '获取帖子列表失败');
+      message.error(error.message || "获取帖子列表失败");
     } finally {
       setLoading(false);
     }
   };
-  
+
   // 显示新建帖子对话框
   const showModal = () => {
     setIsModalOpen(true);
   };
-  
+
   // 关闭对话框
   const handleCancel = () => {
     setIsModalOpen(false);
     form.resetFields();
   };
-  
+
   // 提交新帖子
   const handleSubmit = async () => {
     try {
-      const values = await form.validateFields();
-      
+      const params = await form.validateFields();
+
       // 添加作者信息
-      values.author = user.username;
-      
-      const response = await createPost(values);
-      if (response.success) {
-        message.success('帖子发布成功');
+      params.author = user.username;
+      console.log("提交的帖子数据:", params);
+
+      const response = await createPost(params);
+      if (response.message === "Post created successfully") {
+        message.success("帖子发布成功");
         setIsModalOpen(false);
         form.resetFields();
         fetchPosts(); // 重新加载帖子列表
+      } else {
+        message.error(response.message || "发布帖子失败");
       }
     } catch (error) {
-      message.error(error.message || '发布帖子失败');
+      console.error("发布帖子失败:", error);
+      message.error(error.message || "发布帖子失败");
     }
   };
 
+  // 如果用户未认证,显示提示信息
+  if (!isAuthenticated) {
+    return (
+      <div className="text-center py-8">
+        <Title level={3}>请先登录</Title>
+        <Paragraph>您需要登录后才能查看论坛内容</Paragraph>
+      </div>
+    );
+  }
+
   return (
     <div className="space-y-6">
       <Title level={2}>社区论坛</Title>
       <Paragraph className="text-slate-500">
         欢迎来到我们的社区论坛,这里是会员交流分享的地方。
       </Paragraph>
-      
+      <div className="text-center mt-4">
+        <Button type="primary" onClick={showModal}>
+          发布新主题
+        </Button>
+      </div>
+
+      {/* 新建帖子对话框 */}
+      <Modal
+        title="发布新主题"
+        open={isModalOpen}
+        onOk={handleSubmit}
+        onCancel={handleCancel}
+        okText="发布"
+        cancelText="取消"
+      >
+        <Form form={form} layout="vertical">
+          <Form.Item
+            name="title"
+            label="标题"
+            rules={[{ required: true, message: "请输入标题" }]}
+          >
+            <Input placeholder="请输入标题" />
+          </Form.Item>
+          <Form.Item
+            name="content"
+            label="内容"
+            rules={[{ required: true, message: "请输入帖子内容" }]}
+          >
+            <TextArea rows={6} placeholder="请输入帖子内容" />
+          </Form.Item>
+        </Form>
+      </Modal>
       {loading ? (
         <div className="flex justify-center py-8">
           <Spin size="large" tip="加载中..." />
@@ -86,15 +157,24 @@
               key={item.id}
               extra={
                 <Space>
-                  <Tag color="green">浏览: {item.views || 0}</Tag>
-                  <Tag color="blue">点赞: {item.likes || 0}</Tag>
-                  <Text type="secondary">{item.createTime}</Text>
+                  <Text type="secondary">{item.publishDate}</Text>
                 </Space>
               }
             >
               <List.Item.Meta
-                avatar={<Avatar src={`https://api.dicebear.com/7.x/avataaars/svg?seed=${item.author}`} />}
-                title={<a href={`/post/${item.id}`}>{item.title}</a>}
+                avatar={
+                  <Avatar
+                    src={`https://api.dicebear.com/7.x/avataaars/svg?seed=${item.author}`}
+                  />
+                }
+                title={
+                  <Link 
+                    to={`/post/${item.pid}`}
+                    className="text-blue-600 hover:text-blue-800 hover:underline"
+                  >
+                    {item.title}
+                  </Link>
+                }
                 description={<Text type="secondary">作者: {item.author}</Text>}
               />
               <Paragraph ellipsis={{ rows: 2 }}>{item.content}</Paragraph>
@@ -102,42 +182,8 @@
           )}
         />
       )}
-      
-      <div className="text-center mt-4">
-        <Button type="primary" onClick={showModal}>发布新主题</Button>
-      </div>
-      
-      {/* 新建帖子对话框 */}
-      <Modal
-        title="发布新主题"
-        open={isModalOpen}
-        onOk={handleSubmit}
-        onCancel={handleCancel}
-        okText="发布"
-        cancelText="取消"
-      >
-        <Form
-          form={form}
-          layout="vertical"
-        >
-          <Form.Item
-            name="title"
-            label="标题"
-            rules={[{ required: true, message: '请输入标题' }]}
-          >
-            <Input placeholder="请输入标题" />
-          </Form.Item>
-          <Form.Item
-            name="content"
-            label="内容"
-            rules={[{ required: true, message: '请输入帖子内容' }]}
-          >
-            <TextArea rows={6} placeholder="请输入帖子内容" />
-          </Form.Item>
-        </Form>
-      </Modal>
     </div>
   );
 };
 
-export default ForumPage; 
\ No newline at end of file
+export default ForumPage;
diff --git a/src/features/forum/pages/PostDetailPage.jsx b/src/features/forum/pages/PostDetailPage.jsx
new file mode 100644
index 0000000..5e28820
--- /dev/null
+++ b/src/features/forum/pages/PostDetailPage.jsx
@@ -0,0 +1,407 @@
+import React, { useState, useEffect } from 'react';
+import { useParams, useNavigate } from 'react-router-dom';
+import {
+  Card,
+  Avatar,
+  Typography,
+  Divider,
+  List,
+  Form,
+  Input,
+  Button,
+  message,
+  Spin,
+  Space,
+  Tag,
+  Empty
+} from 'antd';
+import { ArrowLeftOutlined, MessageOutlined, UserOutlined, CommentOutlined } from '@ant-design/icons';
+import { getComments, addComment } from '@/api/forum';
+import { useAuth } from '@/features/auth/contexts/AuthContext';
+
+const { Title, Paragraph, Text } = Typography;
+const { TextArea } = Input;
+
+const PostDetailPage = () => {
+  const { postId } = useParams();
+  const navigate = useNavigate();
+  const { user, isAuthenticated } = useAuth();
+  const [loading, setLoading] = useState(true);
+  const [commenting, setCommenting] = useState(false);
+  const [postContent, setPostContent] = useState('');
+  const [comments, setComments] = useState([]);
+  const [form] = Form.useForm();
+  const [replyForms] = Form.useForm(); // 用于回复的表单
+  const [replyingTo, setReplyingTo] = useState(null); // 当前正在回复的评论ID
+  const [replying, setReplying] = useState(false); // 回复中状态
+
+  // 获取帖子详情和评论
+  useEffect(() => {
+    if (isAuthenticated && user?.username && postId) {
+      fetchPostAndComments();
+    }
+  }, [isAuthenticated, user, postId]);
+
+  // 监听ESC键取消回复
+  useEffect(() => {
+    const handleKeyDown = (event) => {
+      if (event.key === 'Escape' && replyingTo) {
+        cancelReply();
+      }
+    };
+
+    document.addEventListener('keydown', handleKeyDown);
+    return () => {
+      document.removeEventListener('keydown', handleKeyDown);
+    };
+  }, [replyingTo]);
+
+  const fetchPostAndComments = async () => {
+    try {
+      setLoading(true);
+      
+      const params = {
+        postId: postId,
+        username: user.username
+      }
+      const response = await getComments(params);
+
+      if (response && response.data) {
+        setPostContent(response.data.content || '');
+        // 直接按发布时间排序,最新的在前面
+        const allComments = response.data.comments || [];
+        const sortedComments = allComments.sort((a, b) => 
+          new Date(b.publishDate) - new Date(a.publishDate)
+        );
+        setComments(sortedComments);
+      } else {
+        message.error('获取帖子详情失败');
+      }
+    } catch (error) {
+      console.error('获取帖子详情失败:', error);
+      message.error(error.message || '获取帖子详情失败');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 提交主评论
+  const handleSubmitComment = async () => {
+    try {
+      const values = await form.validateFields();
+      setCommenting(true);
+
+      const params = {
+        content: values.comment,
+        username: user.username,
+        postId: postId
+      };
+
+      console.log('提交评论数据:', params);
+      const response = await addComment(params);
+      
+      if (response && response.message === 'Comment added successfully') {
+        message.success('评论发布成功');
+        form.resetFields();
+        fetchPostAndComments();
+      } else {
+        message.error('评论发布失败');
+      }
+    } catch (error) {
+      console.error('发布评论失败:', error);
+      message.error(error.message || '发布评论失败');
+    } finally {
+      setCommenting(false);
+    }
+  };
+
+  // 提交回复评论
+  const handleSubmitReply = async (reviewerId) => {
+    try {
+      const values = await replyForms.validateFields();
+      setReplying(true);
+
+      const replyData = {
+        content: values.reply,
+        username: user.username,
+        postId: postId,
+        reviewer: reviewerId
+      };
+
+      console.log('提交回复数据:', replyData);
+      const response = await addComment(replyData);
+      
+      if (response && response.message === 'Comment added successfully') {
+        message.success('回复发布成功');
+        replyForms.resetFields();
+        setReplyingTo(null);
+        fetchPostAndComments();
+      } else {
+        message.error('回复发布失败');
+      }
+    } catch (error) {
+      console.error('发布回复失败:', error);
+      message.error(error.message || '发布回复失败');
+    } finally {
+      setReplying(false);
+    }
+  };
+
+  // 开始回复评论
+  const startReply = (commentId) => {
+    setReplyingTo(commentId);
+    replyForms.resetFields();
+  };
+
+  // 取消回复
+  const cancelReply = () => {
+    setReplyingTo(null);
+    replyForms.resetFields();
+  };
+
+  // 格式化日期
+  const formatDate = (dateString) => {
+    try {
+      return new Date(dateString).toLocaleString('zh-CN', {
+        year: 'numeric',
+        month: '2-digit',
+        day: '2-digit',
+        hour: '2-digit',
+        minute: '2-digit'
+      });
+    } catch {
+      return dateString;
+    }
+  };
+
+  // 查找被回复的评论
+  const getReviewedComment = (reviewerId) => {
+    return comments.find(comment => comment.commentId === reviewerId);
+  };
+
+  // 如果用户未认证
+  if (!isAuthenticated) {
+    return (
+      <div className="text-center py-8">
+        <Title level={3}>请先登录</Title>
+        <Paragraph>您需要登录后才能查看帖子详情</Paragraph>
+      </div>
+    );
+  }
+
+  return (
+    <div className="max-w-4xl mx-auto space-y-6">
+      {/* 返回按钮 */}
+      <Button 
+        icon={<ArrowLeftOutlined />} 
+        onClick={() => navigate('/forum')}
+        className="mb-4"
+      >
+        返回论坛
+      </Button>
+
+      {loading ? (
+        <div className="flex justify-center py-8">
+          <Spin size="large" tip="加载中..." />
+        </div>
+      ) : (
+        <>
+          {/* 帖子内容 */}
+          <Card title={
+            <Space>
+              <MessageOutlined />
+              <span>帖子详情</span>
+            </Space>
+          }>
+            <div className="mb-4">
+              <Title level={4}>帖子内容</Title>
+              <Paragraph style={{ fontSize: '16px', lineHeight: 1.6 }}>
+                {postContent || '暂无内容'}
+              </Paragraph>
+            </div>
+            <Divider />
+            <div className="flex justify-between items-center text-sm text-gray-500">
+              <span>帖子ID: {postId}</span>
+              <Space>
+                <Tag color="blue">
+                  <MessageOutlined /> {comments.length} 条评论
+                </Tag>
+              </Space>
+            </div>
+          </Card>
+
+          {/* 评论区 */}
+          <Card title={
+            <Space>
+              <MessageOutlined />
+              <span>评论区 ({comments.length})</span>
+            </Space>
+          }>
+            {/* 发表评论 */}
+            <div className="mb-6">
+              <Title level={5}>发表评论</Title>
+              <Form form={form} layout="vertical">
+                <Form.Item
+                  name="comment"
+                  rules={[{ required: true, message: '请输入评论内容' }]}
+                >
+                  <TextArea 
+                    rows={4} 
+                    placeholder="请输入您的评论..."
+                    maxLength={500}
+                    showCount
+                  />
+                </Form.Item>
+                <Form.Item>
+                  <Button 
+                    type="primary" 
+                    onClick={handleSubmitComment}
+                    loading={commenting}
+                  >
+                    发布评论
+                  </Button>
+                </Form.Item>
+              </Form>
+            </div>
+
+            <Divider />
+
+            {/* 评论列表 */}
+            {comments.length > 0 ? (
+              <List
+                itemLayout="vertical"
+                dataSource={comments}
+                renderItem={(comment) => (
+                  <List.Item 
+                    key={comment.commentId}
+                    className={`border-l-2 pl-4 hover:bg-gray-50 transition-colors ${
+                      comment.reviewerId ? 'border-l-orange-200 bg-orange-50' : 'border-l-blue-100'
+                    }`}
+                  >
+                    <List.Item.Meta
+                      avatar={
+                        <Avatar 
+                          src={`https://api.dicebear.com/7.x/avataaars/svg?seed=${comment.writer || 'anonymous'}`}
+                          icon={<UserOutlined />}
+                        />
+                      }
+                      title={
+                        <div className="flex flex-wrap items-center gap-2">
+                          <Text strong>{comment.writer || '匿名用户'}</Text>
+                          <Text type="secondary" className="text-sm">
+                            {formatDate(comment.publishDate)}
+                          </Text>
+                          <Tag size="small" color="blue">
+                            #{comment.commentId}
+                          </Tag>
+                          {comment.reviewerId && (
+                            <Tag size="small" color="orange" className="ml-2">
+                              回复 #{comment.reviewerId}
+                            </Tag>
+                          )}
+                        </div>
+                      }
+                      description={
+                        <div>
+                          {/* 显示被回复的评论 */}
+                          {comment.reviewerId && (
+                            <div className="mb-3 p-3 bg-gray-100 rounded border-l-4 border-l-orange-400">
+                              <Text type="secondary" className="text-xs">
+                                回复 #{comment.reviewerId}:
+                              </Text>
+                              {(() => {
+                                const reviewedComment = getReviewedComment(comment.reviewerId);
+                                return reviewedComment ? (
+                                  <div className="mt-1">
+                                    <Text type="secondary" className="text-sm">
+                                      {reviewedComment.writer || '匿名用户'}: 
+                                    </Text>
+                                    <Text className="text-sm ml-1">
+                                      {reviewedComment.content.length > 50 
+                                        ? reviewedComment.content.substring(0, 50) + '...' 
+                                        : reviewedComment.content}
+                                    </Text>
+                                  </div>
+                                ) : (
+                                  <Text type="secondary" className="text-sm">
+                                    原评论已被删除
+                                  </Text>
+                                );
+                              })()}
+                            </div>
+                          )}
+                          
+                          <Paragraph className="mt-2 mb-3">
+                            {comment.content}
+                          </Paragraph>
+                          
+                          {/* 回复按钮 */}
+                          <div className="mb-3">
+                            <Button
+                              type="link"
+                              icon={<CommentOutlined />}
+                              onClick={() => startReply(comment.commentId)}
+                              size="small"
+                              disabled={replyingTo === comment.commentId}
+                              className="p-0"
+                            >
+                              {replyingTo === comment.commentId ? '回复中...' : '回复'}
+                            </Button>
+                          </div>
+                          
+                          {/* 回复表单 */}
+                          {replyingTo === comment.commentId && (
+                            <div className="mt-4 p-4 bg-gray-50 rounded-lg">
+                              <Form form={replyForms} layout="vertical">
+                                <Form.Item
+                                  name="reply"
+                                  rules={[{ required: true, message: '请输入回复内容' }]}
+                                >
+                                  <TextArea 
+                                    rows={3} 
+                                    placeholder={`回复 ${comment.writer || '匿名用户'}...`}
+                                    maxLength={500}
+                                    showCount
+                                  />
+                                </Form.Item>
+                                <Form.Item className="mb-0">
+                                  <Space>
+                                    <Button 
+                                      type="primary" 
+                                      size="small"
+                                      onClick={() => handleSubmitReply(comment.commentId)}
+                                      loading={replying}
+                                    >
+                                      发布回复
+                                    </Button>
+                                    <Button 
+                                      size="small"
+                                      onClick={cancelReply}
+                                    >
+                                      取消
+                                    </Button>
+                                  </Space>
+                                </Form.Item>
+                              </Form>
+                            </div>
+                          )}
+                        </div>
+                      }
+                    />
+                  </List.Item>
+                )}
+              />
+            ) : (
+              <Empty 
+                description="暂无评论,快来发表第一条评论吧!"
+                image={Empty.PRESENTED_IMAGE_SIMPLE}
+              />
+            )}
+          </Card>
+        </>
+      )}
+    </div>
+  );
+};
+
+export default PostDetailPage; 
\ No newline at end of file
diff --git a/src/features/forum/services/forumApi.js b/src/features/forum/services/forumApi.js
deleted file mode 100644
index 68feca1..0000000
--- a/src/features/forum/services/forumApi.js
+++ /dev/null
@@ -1,117 +0,0 @@
-import request from "../../../services/request";
-
-// 帖子相关API
-export const createPost = (postData) => {
-  const token = localStorage.getItem("token");
-  return request
-    .post(
-      "/posts/create", 
-      postData, 
-      { headers: { token } }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "创建帖子失败"));
-      }
-    });
-};
-
-export const getPosts = (filters) => {
-  const token = localStorage.getItem("token");
-  
-  // 构建查询参数
-  let queryParams = new URLSearchParams();
-  if (filters) {
-    if (filters.username) queryParams.append("username", filters.username);
-    if (filters.title) queryParams.append("title", filters.title);
-    if (filters.author) queryParams.append("author", filters.author);
-    if (filters.date) queryParams.append("date", filters.date);
-  }
-  
-  return request
-    .get(
-      `/posts/list?${queryParams.toString()}`, 
-      { headers: { token } }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "获取帖子列表失败"));
-      }
-    });
-};
-
-export const deletePost = (username, pid) => {
-  const token = localStorage.getItem("token");
-  return request
-    .delete(
-      "/posts/delete", 
-      { 
-        headers: { token },
-        data: { username, pid }
-      }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "删除帖子失败"));
-      }
-    });
-};
-
-// 评论相关API
-export const addComment = (commentData) => {
-  const token = localStorage.getItem("token");
-  return request
-    .post(
-      "/comment/add", 
-      commentData, 
-      { headers: { token } }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "添加评论失败"));
-      }
-    });
-};
-
-export const getComments = (postId, username) => {
-  const token = localStorage.getItem("token");
-  return request
-    .get(
-      `/comment/get?postId=${postId}&username=${username}`, 
-      { headers: { token } }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "获取评论失败"));
-      }
-    });
-};
-
-export const deleteComment = (username, commentId) => {
-  const token = localStorage.getItem("token");
-  return request
-    .delete(
-      "/comment/delete", 
-      { 
-        headers: { token },
-        data: { username, commentId }
-      }
-    )
-    .then((response) => {
-      if (response.data && response.data.success) {
-        return response.data;
-      } else {
-        return Promise.reject(new Error(response.data.message || "删除评论失败"));
-      }
-    });
-}; 
\ No newline at end of file
diff --git a/src/features/profile/pages/ProfilePage.jsx b/src/features/profile/pages/ProfilePage.jsx
index 79fbfe4..bdbdb0a 100644
--- a/src/features/profile/pages/ProfilePage.jsx
+++ b/src/features/profile/pages/ProfilePage.jsx
@@ -1,19 +1,365 @@
-import React from 'react';
-import { Typography, Button, Empty } from 'antd';
+import React, { useState, useEffect } from 'react';
+import {
+  Typography,
+  Card,
+  Avatar,
+  Statistic,
+  Row,
+  Col,
+  Tag,
+  Progress,
+  Button,
+  Divider,
+  Space,
+  Tooltip,
+  message,
+  Modal,
+  Form,
+  Input,
+  Upload
+} from 'antd';
+import {
+  UserOutlined,
+  EditOutlined,
+  UploadOutlined,
+  DownloadOutlined,
+  TrophyOutlined,
+  HeartOutlined,
+  WarningOutlined,
+  CheckCircleOutlined,
+  SyncOutlined,
+  GiftOutlined,
+  SettingOutlined,
+  CameraOutlined
+} from '@ant-design/icons';
+import { useAuth } from '@/features/auth/contexts/AuthContext';
+import { getUserStats, updateUserProfile, uploadAvatar } from '@/api/user';
 
-const { Title } = Typography;
+const { Title, Text, Paragraph } = Typography;
 
-const ProfilePage = () => (
-  <div className="space-y-6">
-    <Title level={2}>个人资料</Title>
+const ProfilePage = () => {
+  const { user } = useAuth();
+  const [loading, setLoading] = useState(false);
+  const [editModalVisible, setEditModalVisible] = useState(false);
+  const [form] = Form.useForm();
+
+  // PT站统计数据
+  const [ptStats, setPtStats] = useState({
+    uploadSize: 157.89, // GB
+    downloadSize: 89.32, // GB
+    ratio: 1.77,
+    points: 12580,
+    userClass: 'Power User',
+    seedingCount: 12,
+    leechingCount: 2,
+    completedCount: 156,
+    invites: 3,
+    warnings: 0,
+    hitAndRuns: 0,
+    joinDate: '2023-05-15',
+    lastActive: '2024-12-28 15:30:00'
+  });
+
+  // 获取用户统计信息
+  useEffect(() => {
+    if (user?.username) {
+      fetchUserStats();
+    }
+  }, [user]);
+
+  const fetchUserStats = async () => {
+    try {
+      setLoading(true);
+      const response = await getUserStats(user.username);
+      if (response && response.data) {
+        setPtStats(prevStats => ({
+          ...prevStats,
+          ...response.data
+        }));
+      }
+    } catch (error) {
+      console.error('获取用户统计信息失败:', error);
+      // 使用默认数据,不显示错误信息
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 格式化文件大小
+  const formatSize = (sizeInGB) => {
+    if (sizeInGB >= 1024) {
+      return `${(sizeInGB / 1024).toFixed(2)} TB`;
+    }
+    return `${sizeInGB.toFixed(2)} GB`;
+  };
+
+  // 获取分享率颜色
+  const getRatioColor = (ratio) => {
+    if (ratio >= 2.0) return '#52c41a'; // 绿色
+    if (ratio >= 1.0) return '#1890ff'; // 蓝色
+    if (ratio >= 0.5) return '#faad14'; // 橙色
+    return '#f5222d'; // 红色
+  };
+
+  // 获取用户等级颜色
+  const getUserClassColor = (userClass) => {
+    const classColors = {
+      'User': 'default',
+      'Power User': 'blue',
+      'Elite User': 'purple',
+      'Crazy User': 'gold',
+      'Insane User': 'red',
+      'Veteran User': 'green',
+      'Extreme User': 'volcano',
+      'VIP': 'magenta'
+    };
+    return classColors[userClass] || 'default';
+  };
+
+  // 显示编辑对话框
+  const showEditModal = () => {
+    form.setFieldsValue({
+      username: user?.username,
+      email: user?.email
+    });
+    setEditModalVisible(true);
+  };
+
+  // 处理编辑提交
+  const handleEditSubmit = async () => {
+    try {
+      const values = await form.validateFields();
+      setLoading(true);
+      
+      const response = await updateUserProfile({
+        username: user.username,
+        ...values
+      });
+      
+      if (response && response.data) {
+        message.success('资料更新成功');
+        setEditModalVisible(false);
+        // 可以触发AuthContext的用户信息更新
+      } else {
+        message.error('更新失败,请重试');
+      }
+      
+    } catch (error) {
+      console.error('更新失败:', error);
+      message.error(error.message || '更新失败,请重试');
+    } finally {
+      setLoading(false);
+    }
+  };
+
+  // 头像上传处理
+  const handleAvatarUpload = async (file) => {
+    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
+    if (!isJpgOrPng) {
+      message.error('只能上传 JPG/PNG 格式的图片!');
+      return false;
+    }
+    const isLt2M = file.size / 1024 / 1024 < 2;
+    if (!isLt2M) {
+      message.error('图片大小不能超过 2MB!');
+      return false;
+    }
+
+    try {
+      const formData = new FormData();
+      formData.append('avatar', file);
+      formData.append('username', user.username);
+      
+      const response = await uploadAvatar(formData);
+      if (response && response.data) {
+        message.success('头像上传成功');
+        // 可以触发AuthContext的用户信息更新或重新获取用户信息
+      } else {
+        message.error('头像上传失败');
+      }
+    } catch (error) {
+      console.error('头像上传失败:', error);
+      message.error('头像上传失败');
+    }
     
-    <div className="text-center py-12">
-      <Empty description="用户资料页面正在开发中" />
-      <Button type="primary" className="mt-4">
-        编辑资料
-      </Button>
+    return false; // 阻止默认上传行为
+  };
+
+  // 头像上传配置
+  const uploadProps = {
+    name: 'avatar',
+    showUploadList: false,
+    beforeUpload: handleAvatarUpload,
+  };
+
+  return (
+    <div className="space-y-6">
+      <div className="flex justify-between items-center">
+        <Title level={2}>个人资料</Title>
+        <Button 
+          type="primary" 
+          icon={<EditOutlined />} 
+          onClick={showEditModal}
+        >
+          编辑资料
+        </Button>
+      </div>
+
+      <Row gutter={[24, 24]}>
+        {/* 用户基本信息卡片 */}
+        <Col xs={24} lg={8}>
+          <Card>
+            <div className="text-center">
+              <div className="relative inline-block">
+                <Avatar 
+                  size={120} 
+                  src={user?.avatar} 
+                  icon={<UserOutlined />}
+                  className="mb-4"
+                />
+                <Upload {...uploadProps}>
+                  <Button 
+                    type="primary" 
+                    shape="circle" 
+                    icon={<CameraOutlined />}
+                    size="small"
+                    className="absolute bottom-0 right-0"
+                  />
+                </Upload>
+              </div>
+              
+              <Title level={3} className="mb-2">{user?.username || '用户'}</Title>
+              
+              <Space direction="vertical" className="w-full">
+                <Tag 
+                  color={getUserClassColor(ptStats.userClass)} 
+                  className="text-lg px-3 py-1"
+                >
+                  {ptStats.userClass}
+                </Tag>
+                
+                <Text type="secondary">邮箱:{user?.email || '未设置'}</Text>
+                <Text type="secondary">注册时间:{ptStats.joinDate}</Text>
+                <Text type="secondary">最后活跃:{ptStats.lastActive}</Text>
+              </Space>
+            </div>
+          </Card>
+        </Col>
+
+        {/* PT站统计信息 */}
+        <Col xs={24} lg={16}>
+          <Card title={
+            <Space>
+              <TrophyOutlined />
+              <span>PT站统计</span>
+            </Space>
+          }>
+            <Row gutter={[16, 16]}>
+              {/* 上传下载统计 */}
+              <Col xs={12} sm={6}>
+                <Statistic
+                  title="上传量"
+                  value={formatSize(ptStats.uploadSize)}
+                  prefix={<UploadOutlined style={{ color: '#52c41a' }} />}
+                  valueStyle={{ color: '#52c41a' }}
+                />
+              </Col>
+              <Col xs={12} sm={6}>
+                <Statistic
+                  title="下载量"
+                  value={formatSize(ptStats.downloadSize)}
+                  prefix={<DownloadOutlined style={{ color: '#1890ff' }} />}
+                  valueStyle={{ color: '#1890ff' }}
+                />
+              </Col>
+              <Col xs={12} sm={6}>
+                <Statistic
+                  title="分享率"
+                  value={ptStats.ratio}
+                  precision={2}
+                  valueStyle={{ color: getRatioColor(ptStats.ratio) }}
+                />
+              </Col>
+              <Col xs={12} sm={6}>
+                <Statistic
+                  title="积分"
+                  value={ptStats.points}
+                  prefix={<HeartOutlined style={{ color: '#eb2f96' }} />}
+                  valueStyle={{ color: '#eb2f96' }}
+                />
+              </Col>
+            </Row>
+          </Card>
+        </Col>
+      </Row>
+
+       {/* 分享率进度条 */}
+       <Card title="分享率分析">
+        <Row gutter={[24, 16]}>
+          <Col xs={24} md={12}>
+            <div className="mb-4">
+              <Text strong>当前分享率:{ptStats.ratio}</Text>
+              <Progress
+                percent={Math.min(ptStats.ratio * 50, 100)} // 转换为百分比显示
+                strokeColor={getRatioColor(ptStats.ratio)}
+                format={() => ptStats.ratio}
+              />
+            </div>
+            <Space wrap>
+              <Tag color="green">≥2.0 优秀</Tag>
+              <Tag color="blue">≥1.0 良好</Tag>
+              <Tag color="orange">≥0.5 及格</Tag>
+              <Tag color="red">&lt;0.5 需要改善</Tag>
+            </Space>
+          </Col>
+          <Col xs={24} md={12}>
+            <div className="space-y-2">
+              <Paragraph>
+                <Text strong>分享率说明:</Text>
+              </Paragraph>
+              <Paragraph type="secondary" className="text-sm">
+                • 分享率 = 上传量 ÷ 下载量<br/>
+                • 保持良好的分享率有助于维护账号状态<br/>
+                • 建议长期做种热门资源提升分享率<br/>
+                • 分享率过低可能导致账号受限
+              </Paragraph>
+            </div>
+          </Col>
+        </Row>
+      </Card>
+
+      {/* 编辑资料对话框 */}
+      <Modal
+        title="编辑个人资料"
+        open={editModalVisible}
+        onOk={handleEditSubmit}
+        onCancel={() => setEditModalVisible(false)}
+        confirmLoading={loading}
+        okText="保存"
+        cancelText="取消"
+      >
+        <Form form={form} layout="vertical">
+          <Form.Item
+            name="username"
+            label="用户名"
+            rules={[{ required: true, message: '请输入用户名' }]}
+          >
+            <Input placeholder="请输入用户名" />
+          </Form.Item>
+          <Form.Item
+            name="email"
+            label="邮箱"
+            rules={[
+              { required: true, message: '请输入邮箱' },
+              { type: 'email', message: '请输入有效的邮箱地址' }
+            ]}
+          >
+            <Input placeholder="请输入邮箱" />
+          </Form.Item>
+        </Form>
+      </Modal>
     </div>
-  </div>
-);
+  );
+};
 
 export default ProfilePage; 
\ No newline at end of file
diff --git a/src/main.jsx b/src/main.jsx
index e7047b3..566e330 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -2,7 +2,7 @@
 import ReactDOM from 'react-dom/client'
 import App from './App.jsx'
 import './index.css'
-// import './mock/index.js' // 注释掉 mock 服务
+import './mock/index.js' // 启用 mock 服务
 
 ReactDOM.createRoot(document.getElementById('root')).render(
   <React.StrictMode>
diff --git a/src/mock/index.js b/src/mock/index.js
index 46a5209..7812646 100644
--- a/src/mock/index.js
+++ b/src/mock/index.js
@@ -5,926 +5,5 @@
   timeout: '300-600'
 })
 
-// 模拟用户数据
-const users = [
-  {
-    id: 1,
-    username: 'LukasWu',
-    password: '060050bbb',
-    email: '22301102@bjtu.edu.cn',
-    role: 'user',
-    userType: 0, // 普通用户
-    avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=LukasWu',
-    createTime: '2025-05-13 17:51:08'
-  },
-  {
-    id: 2,
-    username: 'IcyIron',
-    password: '111111',
-    email: 'icyiron@example.com',
-    role: 'admin',
-    userType: 1, // 管理员
-    avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=IcyIron',
-    createTime: '2025-05-13 18:00:00'
-  },
-  {
-    id: 3,
-    username: 'tanzhennan727',
-    password: 'password123',
-    email: 'tanzhennan727@example.com',
-    role: 'user',
-    userType: 0,
-    avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=tanzhennan727',
-    createTime: '2025-05-14 10:00:00'
-  },
-  {
-    id: 4,
-    username: 'ybt',
-    password: 'ybt123',
-    email: 'ybt@example.com',
-    role: 'user',
-    userType: 0,
-    avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=ybt',
-    createTime: '2025-05-15 14:30:00'
-  }
-]
-
-// 模拟帖子数据
-const posts = [
-  {
-    id: 1,
-    title: '如何成为云顶高手',
-    content: '向icyiron学习',
-    author: 'LukasWu',
-    createTime: '2025-05-18 16:43:51',
-    views: 256,
-    likes: 57
-  },
-  {
-    id: 101,
-    title: '北京交通大学实训心得',
-    content: '实训非常有趣,学到了很多知识',
-    author: 'LukasWu',
-    createTime: '2025-05-17 09:30:00',
-    views: 128,
-    likes: 32
-  },
-  {
-    id: 102,
-    title: '前端开发技巧分享',
-    content: 'React和Vue的使用经验总结...',
-    author: 'IcyIron',
-    createTime: '2025-05-16 15:20:00',
-    views: 345,
-    likes: 89
-  },
-  {
-    id: 103,
-    title: '后端接口设计规范',
-    content: 'RESTful API设计的最佳实践...',
-    author: 'tanzhennan727',
-    createTime: '2025-05-15 11:10:00',
-    views: 210,
-    likes: 45
-  },
-  {
-    id: 104,
-    title: '数据库优化技巧',
-    content: 'MySQL索引优化与查询性能提升...',
-    author: 'ybt',
-    createTime: '2025-05-14 16:40:00',
-    views: 178,
-    likes: 36
-  },
-  {
-    id: 105,
-    title: '云顶之弈攻略',
-    content: '最强阵容搭配与装备选择...',
-    author: 'IcyIron',
-    createTime: '2025-05-13 20:15:00',
-    views: 567,
-    likes: 120
-  }
-]
-
-// 模拟评论数据
-const comments = [
-  {
-    id: 1001,
-    postId: 105,
-    content: '感谢分享,学到了很多!',
-    author: 'LukasWu',
-    createTime: '2025-05-19 12:30:15'
-  },
-  {
-    id: 1002,
-    postId: 105,
-    content: '这个阵容我试了,确实很强',
-    author: 'tanzhennan727',
-    createTime: '2025-05-19 14:25:30'
-  },
-  {
-    id: 1003,
-    postId: 101,
-    content: '实训课程安排得很合理',
-    author: 'ybt',
-    createTime: '2025-05-18 10:15:45'
-  },
-  {
-    id: 1004,
-    postId: 102,
-    content: 'React Hooks确实好用',
-    author: 'LukasWu',
-    createTime: '2025-05-17 16:40:20'
-  },
-  {
-    id: 1005,
-    postId: 103,
-    content: '接口文档写得很清晰',
-    author: 'IcyIron',
-    createTime: '2025-05-16 09:35:10'
-  }
-]
-
-// 生成JWT格式的token
-const generateToken = (username, userType) => {
-  const header = { alg: 'HS256', typ: 'JWT' };
-  const payload = {
-    username: username,
-    userType: userType,
-    exp: Math.floor(Date.now() / 1000) + 86400 // 24小时后过期
-  };
-  
-  // Base64编码
-  const encodeBase64 = (obj) => {
-    return btoa(JSON.stringify(obj)).replace(/=/g, '').replace(/\+/g, '-').replace(/\//g, '_');
-  };
-  
-  const headerEncoded = encodeBase64(header);
-  const payloadEncoded = encodeBase64(payload);
-  
-  // 在实际应用中应该使用正确的签名算法,这里简化处理
-  const signature = encodeBase64(`${username}-${Date.now()}`);
-  
-  return `${headerEncoded}.${payloadEncoded}.${signature}`;
-};
-
-// 验证token
-const verifyToken = (token) => {
-  if (!token) return false;
-  
-  try {
-    // 解析token的payload部分
-    const parts = token.split('.');
-    if (parts.length !== 3) return false;
-    
-    const payload = JSON.parse(atob(parts[1].replace(/-/g, '+').replace(/_/g, '/')));
-    const now = Math.floor(Date.now() / 1000);
-    
-    // 检查过期时间
-    if (payload.exp <= now) return false;
-    
-    // 检查用户是否存在
-    const user = users.find(u => u.username === payload.username);
-    if (!user) return false;
-    
-    return { valid: true, user, userType: payload.userType };
-  } catch (e) {
-    return false;
-  }
-};
-
-// 用户信息相关接口
-
-// 1. 用户登录
-Mock.mock('/user/login', 'post', (options) => {
-  const body = JSON.parse(options.body);
-  const { username, password } = body;
-  
-  const user = users.find(u => u.username === username && u.password === password);
-  
-  if (user) {
-    const token = generateToken(user.username, user.userType);
-    
-    return {
-      code: 200,
-      message: '登录成功',
-      success: true,
-      data: {
-        token,
-        user: {
-          id: user.id,
-          username: user.username,
-          email: user.email,
-          role: user.role,
-          userType: user.userType,
-          avatar: user.avatar
-        }
-      }
-    };
-  } else {
-    return {
-      code: 401,
-      message: '用户名或密码错误',
-      success: false
-    };
-  }
-});
-
-// 2. 用户注册
-Mock.mock('/user/register', 'post', (options) => {
-  const body = JSON.parse(options.body);
-  const { username, password, email } = body;
-  
-  // 检查用户名是否已存在
-  if (users.some(u => u.username === username)) {
-    return {
-      code: 400,
-      message: '用户名已存在',
-      success: false
-    };
-  }
-  
-  // 检查邮箱是否已存在
-  if (users.some(u => u.email === email)) {
-    return {
-      code: 400,
-      message: '邮箱已被注册',
-      success: false
-    };
-  }
-  
-  // 创建新用户
-  const newUser = {
-    id: users.length + 1,
-    username,
-    password,
-    email,
-    role: 'user',
-    userType: 0, // 普通用户
-    avatar: `https://api.dicebear.com/7.x/avataaars/svg?seed=${username}`,
-    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
-  };
-  
-  users.push(newUser);
-  
-  const token = generateToken(newUser.username, newUser.userType);
-  
-  return {
-    code: 200,
-    message: '注册成功',
-    success: true,
-    data: {
-      token,
-      user: {
-        id: newUser.id,
-        username: newUser.username,
-        email: newUser.email,
-        role: newUser.role,
-        userType: newUser.userType,
-        avatar: newUser.avatar
-      }
-    }
-  };
-});
-
-// 3. 修改用户名
-Mock.mock('/user/update/username', 'post', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, newUsername } = body;
-  
-  // 检查用户名是否存在
-  const userIndex = users.findIndex(u => u.username === username);
-  if (userIndex === -1) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  // 检查新用户名是否已被使用
-  if (users.some(u => u.username === newUsername && u.id !== users[userIndex].id)) {
-    return {
-      code: 400,
-      message: '用户名已存在',
-      success: false
-    };
-  }
-  
-  // 更新用户名
-  users[userIndex].username = newUsername;
-  users[userIndex].avatar = `https://api.dicebear.com/7.x/avataaars/svg?seed=${newUsername}`;
-  
-  return {
-    code: 200,
-    message: '用户名修改成功',
-    success: true,
-    data: {
-      user: {
-        id: users[userIndex].id,
-        username: users[userIndex].username,
-        email: users[userIndex].email,
-        role: users[userIndex].role,
-        userType: users[userIndex].userType,
-        avatar: users[userIndex].avatar
-      }
-    }
-  };
-});
-
-// 4. 修改密码
-Mock.mock('/user/update/password', 'post', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, newPassword } = body;
-  
-  // 检查用户名是否存在
-  const userIndex = users.findIndex(u => u.username === username);
-  if (userIndex === -1) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  // 更新密码
-  users[userIndex].password = newPassword;
-  
-  return {
-    code: 200,
-    message: '密码修改成功',
-    success: true
-  };
-});
-
-// 5. 修改邮箱
-Mock.mock('/user/update/email', 'post', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, newEmail } = body;
-  
-  // 检查用户名是否存在
-  const userIndex = users.findIndex(u => u.username === username);
-  if (userIndex === -1) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  // 检查邮箱是否已被使用
-  if (users.some(u => u.email === newEmail && u.id !== users[userIndex].id)) {
-    return {
-      code: 400,
-      message: '邮箱已被注册',
-      success: false
-    };
-  }
-  
-  // 更新邮箱
-  users[userIndex].email = newEmail;
-  
-  return {
-    code: 200,
-    message: '邮箱修改成功',
-    success: true,
-    data: {
-      user: {
-        id: users[userIndex].id,
-        username: users[userIndex].username,
-        email: users[userIndex].email,
-        role: users[userIndex].role,
-        userType: users[userIndex].userType,
-        avatar: users[userIndex].avatar
-      }
-    }
-  };
-});
-
-// 6. 获取用户信息
-Mock.mock(new RegExp('/user/get/info\\?username=.+'), 'get', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const url = options.url;
-  const username = url.split('username=')[1];
-  
-  const user = users.find(u => u.username === username);
-  if (!user) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  return {
-    code: 200,
-    message: '获取用户信息成功',
-    success: true,
-    data: {
-      user: {
-        id: user.id,
-        username: user.username,
-        email: user.email,
-        role: user.role,
-        userType: user.userType,
-        avatar: user.avatar,
-        createTime: user.createTime
-      }
-    }
-  };
-});
-
-// 帖子相关接口
-
-// 7. 新建帖子
-Mock.mock('/posts/create', 'post', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { title, content, author } = body;
-  
-  // 生成新帖子ID
-  const id = posts.length > 0 ? Math.max(...posts.map(p => p.id)) + 1 : 1;
-  
-  const newPost = {
-    id,
-    title,
-    content,
-    author,
-    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19),
-    views: 0,
-    likes: 0
-  };
-  
-  posts.push(newPost);
-  
-  return {
-    code: 200,
-    message: '帖子发布成功',
-    success: true,
-    data: { post: newPost }
-  };
-});
-
-// 8. 查询帖子
-Mock.mock(new RegExp('/posts/list\\?.*'), 'get', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const url = options.url;
-  const params = new URLSearchParams(url.split('?')[1]);
-  
-  const username = params.get('username');
-  const title = params.get('title');
-  const author = params.get('author');
-  const date = params.get('date');
-  
-  // 过滤帖子
-  let filteredPosts = [...posts];
-  
-  if (title) {
-    filteredPosts = filteredPosts.filter(p => p.title.includes(title));
-  }
-  
-  if (author) {
-    filteredPosts = filteredPosts.filter(p => p.author.includes(author));
-  }
-  
-  if (date) {
-    filteredPosts = filteredPosts.filter(p => p.createTime.startsWith(date));
-  }
-  
-  return {
-    code: 200,
-    message: '查询帖子成功',
-    success: true,
-    data: {
-      total: filteredPosts.length,
-      posts: filteredPosts
-    }
-  };
-});
-
-// 评论相关接口
-
-// 9. 获取帖子评论
-Mock.mock(new RegExp('/comment/get\\?.*'), 'get', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const url = options.url;
-  const params = new URLSearchParams(url.split('?')[1]);
-  
-  const postId = params.get('postId');
-  
-  if (!postId) {
-    return {
-      code: 400,
-      message: '参数错误',
-      success: false
-    };
-  }
-  
-  // 查找帖子
-  const post = posts.find(p => p.id === parseInt(postId));
-  if (!post) {
-    return {
-      code: 404,
-      message: '帖子不存在',
-      success: false
-    };
-  }
-  
-  // 获取帖子的评论
-  const postComments = comments.filter(c => c.postId === parseInt(postId));
-  
-  return {
-    code: 200,
-    message: '获取评论成功',
-    success: true,
-    data: {
-      total: postComments.length,
-      comments: postComments
-    }
-  };
-});
-
-// 10. 发布帖子评论
-Mock.mock('/comment/add', 'post', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid) {
-    return {
-      code: 401,
-      message: '未授权访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { content, username, postId } = body;
-  
-  // 检查帖子是否存在
-  const post = posts.find(p => p.id === parseInt(postId));
-  if (!post) {
-    return {
-      code: 404,
-      message: '帖子不存在',
-      success: false
-    };
-  }
-  
-  // 检查用户是否存在
-  const user = users.find(u => u.username === username);
-  if (!user) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  // 生成评论ID
-  const id = comments.length > 0 ? Math.max(...comments.map(c => c.id)) + 1 : 1001;
-  
-  const newComment = {
-    id,
-    postId: parseInt(postId),
-    content,
-    author: username,
-    createTime: new Date().toISOString().replace('T', ' ').substring(0, 19)
-  };
-  
-  comments.push(newComment);
-  
-  return {
-    code: 200,
-    message: '评论发布成功',
-    success: true,
-    data: { comment: newComment }
-  };
-});
-
-// 管理员相关接口
-
-// 11. 管理员登录
-Mock.mock('/admin/login', 'post', (options) => {
-  const body = JSON.parse(options.body);
-  const { username, password } = body;
-  
-  // 查找管理员用户
-  const admin = users.find(u => u.username === username && u.password === password && u.userType === 1);
-  
-  if (admin) {
-    const token = generateToken(admin.username, admin.userType);
-    
-    return {
-      code: 200,
-      message: '管理员登录成功',
-      success: true,
-      data: {
-        token,
-        user: {
-          id: admin.id,
-          username: admin.username,
-          email: admin.email,
-          role: admin.role,
-          userType: admin.userType,
-          avatar: admin.avatar
-        }
-      }
-    };
-  } else {
-    return {
-      code: 401,
-      message: '用户名或密码错误,或无管理员权限',
-      success: false
-    };
-  }
-});
-
-// 12. 获取用户列表 (管理员)
-Mock.mock(new RegExp('/user/list\\?.*'), 'get', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid || auth.userType !== 1) {
-    return {
-      code: 403,
-      message: '无权限访问',
-      success: false
-    };
-  }
-  
-  // 返回除密码外的用户信息
-  const userList = users.map(user => ({
-    id: user.id,
-    username: user.username,
-    email: user.email,
-    role: user.role,
-    userType: user.userType,
-    avatar: user.avatar,
-    createTime: user.createTime
-  }));
-  
-  return {
-    code: 200,
-    message: '获取用户列表成功',
-    success: true,
-    data: {
-      total: userList.length,
-      users: userList
-    }
-  };
-});
-
-// 13. 删除指定用户 (管理员)
-Mock.mock('/user/delete', 'delete', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid || auth.userType !== 1) {
-    return {
-      code: 403,
-      message: '无权限访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, targetUsername } = body;
-  
-  // 确保操作者是管理员
-  const admin = users.find(u => u.username === username && u.userType === 1);
-  if (!admin) {
-    return {
-      code: 403,
-      message: '无权限操作',
-      success: false
-    };
-  }
-  
-  // 查找要删除的用户
-  const userIndex = users.findIndex(u => u.username === targetUsername);
-  if (userIndex === -1) {
-    return {
-      code: 404,
-      message: '用户不存在',
-      success: false
-    };
-  }
-  
-  // 不允许删除管理员
-  if (users[userIndex].userType === 1) {
-    return {
-      code: 403,
-      message: '不能删除管理员账户',
-      success: false
-    };
-  }
-  
-  // 删除用户
-  const deletedUser = users.splice(userIndex, 1)[0];
-  
-  return {
-    code: 200,
-    message: '用户删除成功',
-    success: true,
-    data: {
-      username: deletedUser.username
-    }
-  };
-});
-
-// 14. 删除帖子 (管理员)
-Mock.mock('/posts/delete', 'delete', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid || auth.userType !== 1) {
-    return {
-      code: 403,
-      message: '无权限访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, pid } = body;
-  
-  // 确保操作者是管理员
-  const admin = users.find(u => u.username === username && u.userType === 1);
-  if (!admin) {
-    return {
-      code: 403,
-      message: '无权限操作',
-      success: false
-    };
-  }
-  
-  // 查找要删除的帖子
-  const postIndex = posts.findIndex(p => p.id === parseInt(pid));
-  if (postIndex === -1) {
-    return {
-      code: 404,
-      message: '帖子不存在',
-      success: false
-    };
-  }
-  
-  // 删除帖子
-  const deletedPost = posts.splice(postIndex, 1)[0];
-  
-  // 同时删除该帖子的所有评论
-  const relatedComments = comments.filter(c => c.postId === parseInt(pid));
-  relatedComments.forEach(comment => {
-    const commentIndex = comments.findIndex(c => c.id === comment.id);
-    if (commentIndex !== -1) {
-      comments.splice(commentIndex, 1);
-    }
-  });
-  
-  return {
-    code: 200,
-    message: '帖子删除成功',
-    success: true,
-    data: {
-      title: deletedPost.title,
-      deletedComments: relatedComments.length
-    }
-  };
-});
-
-// 15. 删除帖子评论 (管理员)
-Mock.mock('/comment/delete', 'delete', (options) => {
-  const headers = options.headers || {};
-  const token = headers.token;
-  const auth = verifyToken(token);
-  
-  if (!auth || !auth.valid || auth.userType !== 1) {
-    return {
-      code: 403,
-      message: '无权限访问',
-      success: false
-    };
-  }
-  
-  const body = JSON.parse(options.body);
-  const { username, commentId } = body;
-  
-  // 确保操作者是管理员
-  const admin = users.find(u => u.username === username && u.userType === 1);
-  if (!admin) {
-    return {
-      code: 403,
-      message: '无权限操作',
-      success: false
-    };
-  }
-  
-  // 查找要删除的评论
-  const commentIndex = comments.findIndex(c => c.id === parseInt(commentId));
-  if (commentIndex === -1) {
-    return {
-      code: 404,
-      message: '评论不存在',
-      success: false
-    };
-  }
-  
-  // 删除评论
-  const deletedComment = comments.splice(commentIndex, 1)[0];
-  
-  return {
-    code: 200,
-    message: '评论删除成功',
-    success: true,
-    data: {
-      commentId: deletedComment.id,
-      postId: deletedComment.postId
-    }
-  };
-});
 
 export default Mock
\ No newline at end of file
diff --git a/src/routes/index.jsx b/src/routes/index.jsx
index e085801..f4b7942 100644
--- a/src/routes/index.jsx
+++ b/src/routes/index.jsx
@@ -14,6 +14,7 @@
 // 导入新创建的页面组件
 import HomePage from '../features/home/pages/HomePage';
 import ForumPage from '../features/forum/pages/ForumPage';
+import PostDetailPage from '../features/forum/pages/PostDetailPage';
 import PTPage from '../features/pt/pages/PTPage';
 import TorrentListPage from '../features/torrents/pages/TorrentListPage';
 import UploadTorrentPage from '../features/torrents/pages/UploadTorrentPage';
@@ -57,6 +58,17 @@
       />
       
       <Route 
+        path="/post/:postId" 
+        element={
+          <ProtectedRoute>
+            <MainLayout>
+              <PostDetailPage />
+            </MainLayout>
+          </ProtectedRoute>
+        } 
+      />
+      
+      <Route 
         path="/pt" 
         element={
           <ProtectedRoute>
diff --git a/src/services/request.js b/src/utils/request.js
similarity index 84%
rename from src/services/request.js
rename to src/utils/request.js
index 2395ba2..9e5df58 100644
--- a/src/services/request.js
+++ b/src/utils/request.js
@@ -3,12 +3,11 @@
 
 // 创建 axios 实例
 const request = axios.create({
-  baseURL: "/api",
+  baseURL: "http://192.168.10.174:8080/api",
   timeout: 10000,
 });
 
 // 请求拦截器
-// 请求拦截器中添加角色检查
 request.interceptors.request.use(
   (config) => {
     // 从 localStorage 获取 token
@@ -16,16 +15,15 @@
 
     // 如果有 token 则添加到请求头
     if (token) {
-      config.headers["Authorization"] = `Bearer ${token}`;
+      config.headers["token"] = token;
     }
 
     // 角色检查
-    // 例如,对特定API路径进行角色检查
     if (config.url.startsWith("/api/admin") && !hasAdminRole()) {
-      // 取消请求
       return Promise.reject(new Error("无权限执行此操作"));
     }
 
+    console.log("发出的请求", config);
     return config;
   },
   (error) => {
@@ -42,7 +40,7 @@
 // 响应拦截器
 request.interceptors.response.use(
   (response) => {
-    return response;
+    return response.data;
   },
   (error) => {
     if (error.response) {
@@ -62,7 +60,8 @@
         }
       } else {
         // 处理其他错误
-        message.error(data.message || "请求失败");
+        // message.error(data.message || "11111请求失败");
+        message.error(data.message || "11111请求失败");
       }
     } else if (error.request) {
       // 请求发出但没有收到响应
@@ -76,4 +75,4 @@
   }
 );
 
-export default request;
+export default request; 
\ No newline at end of file