feat(api): 重构 API 调用并优化用户认证流程
- 新增 auth、forum 和 user API 文件夹,重新组织 API 调用结构
- 重构 AuthContext,使用新 API 进行用户认证和信息管理
- 更新 AdminPanel、ForumPage 等组件,使用新的 API 调用
- 删除旧的 authApi.js 文件,清理冗余代码
- 优化用户登录、注册和登出流程,改进错误处理和用户提示
Change-Id: If664193e1bf30036c197f164edc5b10df75f1331
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;