blob: 7e6e78f8ea17b2062c5d16c265b6bc37885e5277 [file] [log] [blame]
ybtda5978b2025-05-31 15:58:05 +08001import React, { useState, useEffect } from 'react';
2import { List, Avatar, Space, Tag, Typography, Button, message, Modal, Form, Input, Spin } from 'antd';
3import { getPosts, createPost } from '../services/forumApi';
4
5const { Title, Paragraph, Text } = Typography;
6const { TextArea } = Input;
7
8const ForumPage = () => {
9 const [posts, setPosts] = useState([]);
10 const [loading, setLoading] = useState(true);
11 const [isModalOpen, setIsModalOpen] = useState(false);
12 const [form] = Form.useForm();
13
14 // 获取用户信息
15 const user = JSON.parse(localStorage.getItem('user') || '{}');
16
17 // 加载帖子数据
18 useEffect(() => {
19 fetchPosts();
20 }, []);
21
22 // 获取帖子列表
23 const fetchPosts = async () => {
24 try {
25 setLoading(true);
26 const response = await getPosts({ username: user.username });
27 if (response.success) {
28 setPosts(response.data.posts || []);
29 }
30 } catch (error) {
31 message.error(error.message || '获取帖子列表失败');
32 } finally {
33 setLoading(false);
34 }
35 };
36
37 // 显示新建帖子对话框
38 const showModal = () => {
39 setIsModalOpen(true);
40 };
41
42 // 关闭对话框
43 const handleCancel = () => {
44 setIsModalOpen(false);
45 form.resetFields();
46 };
47
48 // 提交新帖子
49 const handleSubmit = async () => {
50 try {
51 const values = await form.validateFields();
52
53 // 添加作者信息
54 values.author = user.username;
55
56 const response = await createPost(values);
57 if (response.success) {
58 message.success('帖子发布成功');
59 setIsModalOpen(false);
60 form.resetFields();
61 fetchPosts(); // 重新加载帖子列表
62 }
63 } catch (error) {
64 message.error(error.message || '发布帖子失败');
65 }
66 };
67
68 return (
69 <div className="space-y-6">
70 <Title level={2}>社区论坛</Title>
71 <Paragraph className="text-slate-500">
72 欢迎来到我们的社区论坛,这里是会员交流分享的地方。
73 </Paragraph>
74
75 {loading ? (
76 <div className="flex justify-center py-8">
77 <Spin size="large" tip="加载中..." />
78 </div>
79 ) : (
80 <List
81 itemLayout="vertical"
82 size="large"
83 dataSource={posts}
84 renderItem={(item) => (
85 <List.Item
86 key={item.id}
87 extra={
88 <Space>
89 <Tag color="green">浏览: {item.views || 0}</Tag>
90 <Tag color="blue">点赞: {item.likes || 0}</Tag>
91 <Text type="secondary">{item.createTime}</Text>
92 </Space>
93 }
94 >
95 <List.Item.Meta
96 avatar={<Avatar src={`https://api.dicebear.com/7.x/avataaars/svg?seed=${item.author}`} />}
97 title={<a href={`/post/${item.id}`}>{item.title}</a>}
98 description={<Text type="secondary">作者: {item.author}</Text>}
99 />
100 <Paragraph ellipsis={{ rows: 2 }}>{item.content}</Paragraph>
101 </List.Item>
102 )}
103 />
104 )}
105
106 <div className="text-center mt-4">
107 <Button type="primary" onClick={showModal}>发布新主题</Button>
108 </div>
109
110 {/* 新建帖子对话框 */}
111 <Modal
112 title="发布新主题"
113 open={isModalOpen}
114 onOk={handleSubmit}
115 onCancel={handleCancel}
116 okText="发布"
117 cancelText="取消"
118 >
119 <Form
120 form={form}
121 layout="vertical"
122 >
123 <Form.Item
124 name="title"
125 label="标题"
126 rules={[{ required: true, message: '请输入标题' }]}
127 >
128 <Input placeholder="请输入标题" />
129 </Form.Item>
130 <Form.Item
131 name="content"
132 label="内容"
133 rules={[{ required: true, message: '请输入帖子内容' }]}
134 >
135 <TextArea rows={6} placeholder="请输入帖子内容" />
136 </Form.Item>
137 </Form>
138 </Modal>
139 </div>
140 );
141};
142
143export default ForumPage;