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

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

Change-Id: If664193e1bf30036c197f164edc5b10df75f1331
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: "注销成功"
-  });
-};