帖子的评论的前端
Change-Id: Ida12e1874052498f22e40d0604e936f0d65d5fb6
diff --git a/src/components/Comment.jsx b/src/components/Comment.jsx
new file mode 100644
index 0000000..704636e
--- /dev/null
+++ b/src/components/Comment.jsx
@@ -0,0 +1,290 @@
+import React, { useState, useEffect } from 'react';
+import {
+ getCommentsByPostId,
+ createComment,
+ deleteComment,
+ likeComment,
+ unlikeComment,
+} from '../api/comment';
+
+import {
+ Card,
+ Button,
+ Input,
+ List,
+ Avatar,
+ Popconfirm,
+ message,
+ Space,
+ Tooltip
+} from 'antd';
+
+import {
+ LikeOutlined,
+ LikeFilled,
+ DeleteOutlined
+} from '@ant-design/icons';
+
+import axios from 'axios';
+import './Comment.css';
+
+const { TextArea } = Input;
+
+const Comment = ({ postId, currentUser }) => {
+ const [comments, setComments] = useState([]);
+ const [newContent, setNewContent] = useState('');
+ const [loading, setLoading] = useState(false);
+ const [userInfoMap, setUserInfoMap] = useState({});
+ const [isCommenting, setIsCommenting] = useState(false);
+
+ useEffect(() => {
+ loadComments();
+ }, [postId, currentUser]);
+
+ const loadComments = async () => {
+ try {
+ if (!postId) return;
+
+ const commentList = await getCommentsByPostId(postId);
+ setComments(commentList);
+
+ // 修复1: 统一使用 userid 而不是 id
+ const userIds = [
+ ...new Set(commentList.map(c => c.userid))
+ ];
+
+ // 如果当前用户存在,添加其 userid
+ if (currentUser && currentUser.userid) {
+ userIds.push(currentUser.userid);
+ }
+
+ // 批量获取用户信息
+ const userInfoPromises = userIds.map(async (id) => {
+ try {
+ const res = await axios.get(`http://localhost:8080/user/getDecoration?userid=${id}`);
+ if (res.data?.success) {
+ return { id, data: res.data.data };
+ }
+ return { id, data: { username: `用户${id}`, image: '' } };
+ } catch (error) {
+ return { id, data: { username: `用户${id}`, image: '' } };
+ }
+ });
+
+ const userInfoResults = await Promise.all(userInfoPromises);
+
+ // 构建用户信息映射
+ const newUserInfoMap = {};
+ userInfoResults.forEach(({ id, data }) => {
+ newUserInfoMap[id] = data;
+ });
+
+ setUserInfoMap(newUserInfoMap);
+
+ } catch (error) {
+ console.error('加载评论失败:', error);
+ message.error('加载评论失败');
+ }
+ };
+
+ const handleCreate = async () => {
+ // 检查用户是否登录
+ if (!currentUser) {
+ message.error('请先登录后再评论');
+ return;
+ }
+
+ // 修复2: 确保当前用户有 userid 属性
+ if (!currentUser.userid) {
+ message.error('用户信息异常,请重新登录');
+ return;
+ }
+
+ if (!newContent.trim()) {
+ message.warning('评论内容不能为空');
+ return;
+ }
+
+ setIsCommenting(true);
+ setLoading(true);
+
+ // 修复3: 使用 currentUser.userid 而非 currentUser.id
+ const commentData = {
+ postid: postId,
+ userid: Number(currentUser.userid),
+ postCommentcontent: newContent,
+ commenttime: new Date().toISOString()
+ };
+
+ try {
+ await createComment(commentData);
+ setNewContent('');
+ await loadComments(); // 重新加载评论,确保新评论显示
+ message.success('评论发布成功');
+ } catch (error) {
+ console.error('发布评论失败:', error);
+ message.error('发布评论失败');
+ } finally {
+ setLoading(false);
+ setIsCommenting(false);
+ }
+ };
+
+ const handleDelete = async (commentid) => {
+ try {
+ await deleteComment(commentid);
+ message.success('删除成功');
+ loadComments();
+ } catch (error) {
+ console.error('删除评论失败:', error);
+ message.error('删除失败');
+ }
+ };
+
+ const handleLike = async (commentid) => {
+ try {
+ await likeComment(commentid);
+ loadComments();
+ } catch (error) {
+ console.error('点赞失败:', error);
+ message.error('操作失败');
+ }
+ };
+
+ const handleUnlike = async (commentid) => {
+ try {
+ await unlikeComment(commentid);
+ loadComments();
+ } catch (error) {
+ console.error('取消点赞失败:', error);
+ message.error('操作失败');
+ }
+ };
+
+ // 获取用户信息(包括当前登录用户)
+ const getUserInfo = (userId) => {
+ // 修复4: 使用 currentUser.userid 而非 currentUser.id
+ if (currentUser && currentUser.userid && userId === currentUser.userid) {
+ return {
+ username: currentUser.username || `用户${userId}`,
+ image: currentUser.image || '',
+ decoration: currentUser.decoration || ''
+ };
+ }
+
+ // 对于其他用户,从userInfoMap中获取
+ return userInfoMap[userId] || {
+ username: `用户${userId}`,
+ image: '',
+ decoration: ''
+ };
+ };
+
+ return (
+ <Card title="评论区" bordered={false} className="comment-card">
+ {/* 评论输入框 - 根据用户登录状态调整 */}
+ {currentUser ? (
+ <>
+ <TextArea
+ rows={3}
+ placeholder={`${currentUser.username},留下你的评论...`}
+ value={newContent}
+ onChange={(e) => setNewContent(e.target.value)}
+ className="comment-textarea"
+ disabled={loading}
+ />
+ <div className="text-right mt-2">
+ <Button
+ type="primary"
+ onClick={handleCreate}
+ loading={loading || isCommenting}
+ disabled={isCommenting}
+ >
+ {isCommenting ? '发布中...' : '发布评论'}
+ </Button>
+ </div>
+ </>
+ ) : (
+ <div className="login-prompt">
+ 请<a href="/login" className="login-link">登录</a>后发表评论
+ </div>
+ )}
+
+ {/* 评论列表 */}
+ <List
+ itemLayout="vertical"
+ dataSource={comments}
+ locale={{ emptyText: '暂无评论' }}
+ className="mt-6"
+ renderItem={(item) => {
+ const user = getUserInfo(item.userid);
+ // 修复5: 使用 userid 而非 id 比较当前用户
+ const isCurrentUser = currentUser && currentUser.userid === item.userid;
+
+ return (
+ <List.Item
+ key={item.commentid}
+ className={isCurrentUser ? "current-user-comment" : ""}
+ actions={[
+ <Tooltip title="点赞" key="like">
+ <Space>
+ <Button
+ icon={<LikeOutlined />}
+ size="small"
+ onClick={() => handleLike(item.commentid)}
+ />
+ {item.likes}
+ </Space>
+ </Tooltip>,
+ <Tooltip title="取消点赞" key="unlike">
+ <Button
+ icon={<LikeFilled style={{ color: '#fadb14' }} />}
+ size="small"
+ onClick={() => handleUnlike(item.commentid)}
+ />
+ </Tooltip>,
+ isCurrentUser && (
+ <Popconfirm
+ title="确定要删除这条评论吗?"
+ onConfirm={() => handleDelete(item.commentid)}
+ okText="删除"
+ cancelText="取消"
+ key="delete"
+ >
+ <Button icon={<DeleteOutlined />} size="small" danger />
+ </Popconfirm>
+ )
+ ]}
+ extra={
+ <div className="comment-time">
+ {new Date(item.commenttime).toLocaleString()}
+ </div>
+ }
+ >
+ <List.Item.Meta
+ avatar={
+ <Avatar
+ src={user.image || undefined}
+ alt={user.username}
+ className="comment-avatar"
+ >
+ {!user.image && user.username ? user.username.charAt(0).toUpperCase() : ''}
+ </Avatar>
+ }
+ title={
+ <span className="comment-username">
+ {user.username || `用户${item.userid}`}
+ {isCurrentUser && <span className="current-user-tag">(我)</span>}
+ </span>
+ }
+ description={<div className="comment-content">{item.postCommentcontent}</div>}
+ />
+ </List.Item>
+ );
+ }}
+ />
+ </Card>
+ );
+};
+
+export default Comment;
\ No newline at end of file