diff --git a/src/components/EventCommentSection/CommentItem.js b/src/components/EventCommentSection/CommentItem.js
index 6ebea5a8..9fe3ddf8 100644
--- a/src/components/EventCommentSection/CommentItem.js
+++ b/src/components/EventCommentSection/CommentItem.js
@@ -1,29 +1,63 @@
// src/components/EventCommentSection/CommentItem.js
/**
* 单条评论组件
- * 功能:显示用户头像、昵称、时间、评论内容
+ * 功能:显示用户头像、昵称、时间、评论内容、删除按钮
*/
-import React from 'react';
+import React, { useState } from 'react';
import {
Box,
HStack,
VStack,
Avatar,
Text,
+ IconButton,
useColorModeValue,
+ Tooltip,
+ AlertDialog,
+ AlertDialogBody,
+ AlertDialogFooter,
+ AlertDialogHeader,
+ AlertDialogContent,
+ AlertDialogOverlay,
+ Button,
+ useDisclosure,
} from '@chakra-ui/react';
+import { DeleteIcon } from '@chakra-ui/icons';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
dayjs.locale('zh-cn');
-const CommentItem = ({ comment }) => {
+const CommentItem = ({ comment, currentUserId, onDelete }) => {
+ const { isOpen, onOpen, onClose } = useDisclosure();
+ const cancelRef = React.useRef();
+ const [isDeleting, setIsDeleting] = useState(false);
const itemBg = useColorModeValue('gray.50', 'gray.700');
const usernameColor = useColorModeValue('gray.800', 'gray.100');
const timeColor = useColorModeValue('gray.500', 'gray.400');
const contentColor = useColorModeValue('gray.700', 'gray.300');
+ // 判断当前用户是否可以删除此评论
+ const canDelete = currentUserId && (
+ comment.author?.id === currentUserId ||
+ comment.user_id === currentUserId
+ );
+
+ // 处理删除
+ const handleDelete = async () => {
+ if (!onDelete) return;
+ setIsDeleting(true);
+ try {
+ await onDelete(comment.id);
+ onClose();
+ } catch (error) {
+ // 错误由父组件处理
+ } finally {
+ setIsDeleting(false);
+ }
+ };
+
// 格式化时间
const formatTime = (timestamp) => {
const now = dayjs();
@@ -46,43 +80,99 @@ const CommentItem = ({ comment }) => {
};
return (
-
-
- {/* 用户头像 */}
-
+ <>
+
+
+ {/* 用户头像 */}
+
- {/* 评论内容区 */}
-
- {/* 用户名和时间 */}
-
-
- {comment.author?.username || 'Anonymous'}
-
-
- {formatTime(comment.created_at)}
-
-
+ {/* 评论内容区 */}
+
+ {/* 用户名和时间 */}
+
+
+
+ {comment.author?.username || 'Anonymous'}
+
+
+ {formatTime(comment.created_at)}
+
+
- {/* 评论内容 */}
-
- {comment.content}
-
-
-
-
+ {/* 删除按钮 - 只对自己的评论显示 */}
+ {canDelete && (
+
+ }
+ size="xs"
+ variant="ghost"
+ colorScheme="red"
+ aria-label="删除评论"
+ onClick={onOpen}
+ opacity={0.6}
+ _hover={{ opacity: 1 }}
+ />
+
+ )}
+
+
+ {/* 评论内容 */}
+
+ {comment.content}
+
+
+
+
+
+ {/* 删除确认对话框 */}
+
+
+
+
+ 删除评论
+
+
+
+ 确定要删除这条评论吗?此操作不可撤销。
+
+
+
+
+
+
+
+
+
+ >
);
};
diff --git a/src/components/EventCommentSection/CommentList.js b/src/components/EventCommentSection/CommentList.js
index 0a08078f..0770e112 100644
--- a/src/components/EventCommentSection/CommentList.js
+++ b/src/components/EventCommentSection/CommentList.js
@@ -16,7 +16,7 @@ import {
import { ChatIcon } from '@chakra-ui/icons';
import CommentItem from './CommentItem';
-const CommentList = ({ comments, loading }) => {
+const CommentList = ({ comments, loading, currentUserId, onDelete }) => {
const emptyTextColor = useColorModeValue('gray.500', 'gray.400');
const emptyBgColor = useColorModeValue('gray.50', 'gray.700');
@@ -58,7 +58,12 @@ const CommentList = ({ comments, loading }) => {
return (
{comments.map((comment) => (
-
+
))}
);
diff --git a/src/components/EventCommentSection/EventCommentSection.tsx b/src/components/EventCommentSection/EventCommentSection.tsx
index 47e4dad1..d69a56f6 100644
--- a/src/components/EventCommentSection/EventCommentSection.tsx
+++ b/src/components/EventCommentSection/EventCommentSection.tsx
@@ -144,8 +144,9 @@ const EventCommentSection: React.FC = ({ eventId }) =>
content_type: 'text',
author: {
id: user?.id || 'current_user',
- username: user?.username || '当前用户',
- avatar: user?.avatar || null,
+ // 与导航区保持一致:优先显示昵称
+ username: user?.nickname || user?.username || user?.email || '当前用户',
+ avatar: user?.avatar_url || null,
},
created_at: new Date().toISOString(),
likes_count: 0,
@@ -187,6 +188,51 @@ const EventCommentSection: React.FC = ({ eventId }) =>
}
}, [eventId, commentText, toast, user, setComments, setTotalCount]);
+ /**
+ * 删除评论
+ */
+ const handleDeleteComment = useCallback(async (commentId: string | number) => {
+ try {
+ const result = await eventService.deletePost(commentId);
+
+ if (result.success) {
+ // 从本地 state 中移除该评论
+ setComments((prevComments) =>
+ prevComments.filter((comment) => comment.id !== commentId)
+ );
+ // 总评论数 -1
+ setTotalCount((prevTotal) => Math.max(0, prevTotal - 1));
+
+ toast({
+ title: '评论已删除',
+ status: 'success',
+ duration: 2000,
+ isClosable: true,
+ });
+
+ logger.info('EventCommentSection', '评论删除成功', {
+ eventId,
+ commentId,
+ });
+ } else {
+ throw new Error(result.message || '删除评论失败');
+ }
+ } catch (error: any) {
+ logger.error('EventCommentSection', 'handleDeleteComment', error, {
+ eventId,
+ commentId,
+ });
+ toast({
+ title: '删除评论失败',
+ description: error.message || '请稍后重试',
+ status: 'error',
+ duration: 3000,
+ isClosable: true,
+ });
+ throw error; // 重新抛出让 CommentItem 知道删除失败
+ }
+ }, [eventId, toast, setComments, setTotalCount]);
+
return (
{/* 标题栏 */}
@@ -203,7 +249,12 @@ const EventCommentSection: React.FC = ({ eventId }) =>
{/* 评论列表 */}
-
+
{/* 加载更多按钮(仅当有更多评论时显示) */}
diff --git a/src/mocks/handlers/event.js b/src/mocks/handlers/event.js
index a8f488e5..95c23f6d 100644
--- a/src/mocks/handlers/event.js
+++ b/src/mocks/handlers/event.js
@@ -5,6 +5,7 @@ import { http, HttpResponse } from 'msw';
import { getEventRelatedStocks, generateMockEvents, generateHotEvents, generatePopularKeywords, generateDynamicNewsEvents } from '../data/events';
import { getMockFutureEvents, getMockEventCountsForMonth, toggleEventFollowStatus, isEventFollowed } from '../data/account';
import { generatePopularConcepts } from './concept';
+import { getCurrentUser } from '../data/users';
// 模拟网络延迟
const delay = (ms = 300) => new Promise(resolve => setTimeout(resolve, ms));
@@ -1498,15 +1499,19 @@ export const eventHandlers = [
console.log('[Mock] 发表评论, eventId:', eventId, 'content:', body.content);
try {
+ // 获取当前登录用户信息
+ const currentUser = getCurrentUser();
+
// 模拟创建新评论
const newComment = {
id: `comment_${eventId}_${Date.now()}`,
content: body.content,
content_type: body.content_type || 'text',
author: {
- id: 'current_user',
- username: '当前用户',
- avatar: null,
+ id: currentUser?.id || 'current_user',
+ // 与导航区保持一致:优先显示昵称
+ username: currentUser?.nickname || currentUser?.username || currentUser?.email || '当前用户',
+ avatar: currentUser?.avatar_url || null,
},
created_at: new Date().toISOString(),
likes_count: 0,