blob: 7fd39c41178d37a9a8f11adc8bc6e0ead95ddf47 [file] [log] [blame]
223010143d966302025-06-07 22:54:40 +08001import React, { useState, useEffect } from 'react';
2import { List, Button, Form, Input, message, Avatar, Typography, Modal, Pagination } from 'antd';
3import { LikeOutlined, MessageOutlined } from '@ant-design/icons';
4import CommentAPI from '../api/commentApi';
5import type { Comment } from '../api/otherType';
6
7const { Text } = Typography;
8const { TextArea } = Input;
9
10interface DiscussionSectionProps {
11 workId: number;
12}
13
14const DiscussionSection: React.FC<DiscussionSectionProps> = ({ workId }) => {
15 const [comments, setComments] = useState<Comment[]>([]);
16 const [loading, setLoading] = useState(false);
17 const [modalVisible, setModalVisible] = useState(false);
18 const [form] = Form.useForm();
19 const [currentPage, setCurrentPage] = useState(1);
20 const [pageSize, setPageSize] = useState(5); // 每页显示5条
21
22 // 加载评论
23 useEffect(() => {
24 const loadComments = async () => {
25 try {
26 setLoading(true);
27 const commentList = await CommentAPI.getCommentsByPostId(workId);
28 setComments(commentList);
29 } catch (error) {
30 message.error('加载评论失败');
31 } finally {
32 setLoading(false);
33 }
34 };
35
36 loadComments();
37 }, [workId]);
38
39 // 获取当前页的评论数据
40 const getCurrentPageComments = () => {
41 const startIndex = (currentPage - 1) * pageSize;
42 const endIndex = startIndex + pageSize;
43 return comments.slice(startIndex, endIndex);
44 };
45
46 // 提交新评论
47 const handleSubmit = async (values: { title: string; content: string }) => {
48 try {
49 await CommentAPI.addComment({
50 postId: workId,
51 content: values.content
52 });
53 message.success('评论添加成功');
54 form.resetFields();
55 setModalVisible(false);
56 // 重新加载评论
57 const commentList = await CommentAPI.getCommentsByPostId(workId);
58 setComments(commentList);
59 // 重置到第一页
60 setCurrentPage(1);
61 } catch (error) {
62 message.error('评论添加失败');
63 }
64 };
65
66 // 点赞评论
67 const handleLikeComment = async (commentId: number) => {
68 try {
69 await CommentAPI.likeComment(commentId);
70 setComments(prev => prev.map(comment =>
71 comment.id === commentId
72 ? { ...comment, likes: (comment.likes || 0) + 1 }
73 : comment
74 ));
75 } catch (error) {
76 message.error('点赞失败');
77 }
78 };
79
80 return (
81 <div className="discussion-section">
82 <Button
83 type="primary"
84 icon={<MessageOutlined />}
85 onClick={() => setModalVisible(true)}
86 style={{ marginBottom: 16 }}
87 >
88 新建讨论
89 </Button>
90
91 <List
92 dataSource={getCurrentPageComments()}
93 loading={loading}
94 renderItem={comment => (
95 <List.Item className="comment-item">
96 <div className="comment-content">
97 <div className="comment-header">
98 <Avatar size="small">
99 {comment.author?.charAt(0) || '?'}
100 </Avatar>
101 <Text strong>{comment.author || '匿名用户'}</Text>
102 <Text type="secondary">
103 {comment.createTime ? new Date(comment.createTime).toLocaleString() : '未知时间'}
104 </Text>
105 </div>
106 <div className="comment-body">
107 <Text>{comment.content}</Text>
108 </div>
109 <div className="comment-actions">
110 <Button
111 type="text"
112 icon={<LikeOutlined />}
113 onClick={() => handleLikeComment(comment.id)}
114 >
115 {comment.likes || 0}
116 </Button>
117 </div>
118 </div>
119 </List.Item>
120 )}
121 />
122
123 <div style={{ textAlign: 'right', marginTop: 16 }}>
124 <Pagination
125 current={currentPage}
126 pageSize={pageSize}
127 total={comments.length}
128 onChange={(page, size) => {
129 setCurrentPage(page);
130 setPageSize(size);
131 }}
132 showSizeChanger
133 showQuickJumper
134 showTotal={total => `共 ${total} 条`}
135 />
136 </div>
137
138 <Modal
139 title={
140 <span>
141 <MessageOutlined style={{ marginRight: 8 }} />
142 新建讨论
143 </span>
144 }
145 visible={modalVisible}
146 onCancel={() => setModalVisible(false)}
147 footer={[
148 <Button key="cancel" onClick={() => setModalVisible(false)}>
149 取消
150 </Button>,
151 <Button
152 key="submit"
153 type="primary"
154 onClick={() => {
155 form.validateFields()
156 .then(values => handleSubmit(values))
157 .catch(() => message.error('请填写完整信息'));
158 }}
159 >
160 创建讨论
161 </Button>,
162 ]}
163 >
164 <Form form={form} layout="vertical">
165 <Form.Item
166 name="title"
167 label="讨论主题"
168 rules={[{ required: true, message: '请输入讨论主题' }]}
169 >
170 <Input placeholder="输入讨论主题" />
171 </Form.Item>
172
173 <Form.Item
174 name="content"
175 label="讨论内容"
176 rules={[{ required: true, message: '请输入讨论内容' }]}
177 >
178 <TextArea
179 rows={6}
180 placeholder="详细描述你想讨论的内容..."
181 />
182 </Form.Item>
183 </Form>
184 </Modal>
185 </div>
186 );
187};
188
189
190export default DiscussionSection;