| import React, { useState, useEffect } from 'react'; |
| import { List, Button, Form, Input, message, Avatar, Typography, Modal, Pagination } from 'antd'; |
| import { LikeOutlined, MessageOutlined } from '@ant-design/icons'; |
| import CommentAPI from '../api/commentApi'; |
| import type { Comment } from '../api/otherType'; |
| |
| const { Text } = Typography; |
| const { TextArea } = Input; |
| |
| interface DiscussionSectionProps { |
| workId: number; |
| } |
| |
| const DiscussionSection: React.FC<DiscussionSectionProps> = ({ workId }) => { |
| const [comments, setComments] = useState<Comment[]>([]); |
| const [loading, setLoading] = useState(false); |
| const [modalVisible, setModalVisible] = useState(false); |
| const [form] = Form.useForm(); |
| const [currentPage, setCurrentPage] = useState(1); |
| const [pageSize, setPageSize] = useState(5); // 每页显示5条 |
| |
| // 加载评论 |
| useEffect(() => { |
| const loadComments = async () => { |
| try { |
| setLoading(true); |
| const commentList = await CommentAPI.getCommentsByPostId(workId); |
| setComments(commentList); |
| } catch (error) { |
| message.error('加载评论失败'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| loadComments(); |
| }, [workId]); |
| |
| // 获取当前页的评论数据 |
| const getCurrentPageComments = () => { |
| const startIndex = (currentPage - 1) * pageSize; |
| const endIndex = startIndex + pageSize; |
| return comments.slice(startIndex, endIndex); |
| }; |
| |
| // 提交新评论 |
| const handleSubmit = async (values: { title: string; content: string }) => { |
| try { |
| await CommentAPI.addComment({ |
| postId: workId, |
| content: values.content |
| }); |
| message.success('评论添加成功'); |
| form.resetFields(); |
| setModalVisible(false); |
| // 重新加载评论 |
| const commentList = await CommentAPI.getCommentsByPostId(workId); |
| setComments(commentList); |
| // 重置到第一页 |
| setCurrentPage(1); |
| } catch (error) { |
| message.error('评论添加失败'); |
| } |
| }; |
| |
| // 点赞评论 |
| const handleLikeComment = async (commentId: number) => { |
| try { |
| await CommentAPI.likeComment(commentId); |
| setComments(prev => prev.map(comment => |
| comment.id === commentId |
| ? { ...comment, likes: (comment.likes || 0) + 1 } |
| : comment |
| )); |
| } catch (error) { |
| message.error('点赞失败'); |
| } |
| }; |
| |
| return ( |
| <div className="discussion-section"> |
| <Button |
| type="primary" |
| icon={<MessageOutlined />} |
| onClick={() => setModalVisible(true)} |
| style={{ marginBottom: 16 }} |
| > |
| 新建讨论 |
| </Button> |
| |
| <List |
| dataSource={getCurrentPageComments()} |
| loading={loading} |
| renderItem={comment => ( |
| <List.Item className="comment-item"> |
| <div className="comment-content"> |
| <div className="comment-header"> |
| <Avatar size="small"> |
| {comment.author?.charAt(0) || '?'} |
| </Avatar> |
| <Text strong>{comment.author || '匿名用户'}</Text> |
| <Text type="secondary"> |
| {comment.createTime ? new Date(comment.createTime).toLocaleString() : '未知时间'} |
| </Text> |
| </div> |
| <div className="comment-body"> |
| <Text>{comment.content}</Text> |
| </div> |
| <div className="comment-actions"> |
| <Button |
| type="text" |
| icon={<LikeOutlined />} |
| onClick={() => handleLikeComment(comment.id)} |
| > |
| {comment.likes || 0} |
| </Button> |
| </div> |
| </div> |
| </List.Item> |
| )} |
| /> |
| |
| <div style={{ textAlign: 'right', marginTop: 16 }}> |
| <Pagination |
| current={currentPage} |
| pageSize={pageSize} |
| total={comments.length} |
| onChange={(page, size) => { |
| setCurrentPage(page); |
| setPageSize(size); |
| }} |
| showSizeChanger |
| showQuickJumper |
| showTotal={total => `共 ${total} 条`} |
| /> |
| </div> |
| |
| <Modal |
| title={ |
| <span> |
| <MessageOutlined style={{ marginRight: 8 }} /> |
| 新建讨论 |
| </span> |
| } |
| visible={modalVisible} |
| onCancel={() => setModalVisible(false)} |
| footer={[ |
| <Button key="cancel" onClick={() => setModalVisible(false)}> |
| 取消 |
| </Button>, |
| <Button |
| key="submit" |
| type="primary" |
| onClick={() => { |
| form.validateFields() |
| .then(values => handleSubmit(values)) |
| .catch(() => message.error('请填写完整信息')); |
| }} |
| > |
| 创建讨论 |
| </Button>, |
| ]} |
| > |
| <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 DiscussionSection; |