feat(admin): 实现管理员登录和删除功能
- 新增管理员登录接口和相关逻辑
- 实现帖子和评论的删除功能
- 更新用户权限检查逻辑
- 优化登录页面,增加管理员登录入口
- 调整论坛页面布局,增加删除按钮
Change-Id: I6b81fa7296ec9642ca14e249ede517f2fec3d077
diff --git a/src/features/forum/pages/ForumPage.jsx b/src/features/forum/pages/ForumPage.jsx
index 54638fc..2f3b8d7 100644
--- a/src/features/forum/pages/ForumPage.jsx
+++ b/src/features/forum/pages/ForumPage.jsx
@@ -13,7 +13,8 @@
Input,
Spin,
} from "antd";
-import { getPosts, createPost } from "@/api/forum";
+import { DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
+import { getPosts, createPost, deletePost } from "@/api/forum";
import { useAuth } from "@/features/auth/contexts/AuthContext";
const { Title, Paragraph, Text } = Typography;
@@ -26,7 +27,10 @@
const [form] = Form.useForm();
// 使用 AuthProvider 获取用户信息
- const { user, isAuthenticated } = useAuth();
+ const { user, isAuthenticated, hasRole } = useAuth();
+
+ // 判断是否为管理员
+ const isAdmin = hasRole('admin') || (user && user.uid && user.uid.includes('admin'));
// 加载帖子数据
useEffect(() => {
@@ -95,6 +99,43 @@
}
};
+ // 删除帖子(管理员功能)
+ const handleDeletePost = (post) => {
+ Modal.confirm({
+ title: '确认删除帖子',
+ icon: <ExclamationCircleOutlined />,
+ content: (
+ <div>
+ <p>您确定要删除这篇帖子吗?</p>
+ <p><strong>标题:</strong>{post.title}</p>
+ <p><strong>作者:</strong>{post.author}</p>
+ <p className="text-red-500 mt-2">此操作不可撤销!</p>
+ </div>
+ ),
+ okText: '确认删除',
+ okType: 'danger',
+ cancelText: '取消',
+ async onOk() {
+ try {
+ const params = {
+ username: user.username,
+ pid: post.pid,
+ };
+ const response = await deletePost(params);
+ if (response.message) {
+ message.success(response.message || '帖子删除成功');
+ fetchPosts(); // 重新加载帖子列表
+ } else {
+ message.error(response.message || '删除帖子失败');
+ }
+ } catch (error) {
+ console.error('删除帖子失败:', error);
+ message.error(error.message || '删除帖子失败');
+ }
+ },
+ });
+ };
+
// 如果用户未认证,显示提示信息
if (!isAuthenticated) {
return (
@@ -158,6 +199,18 @@
extra={
<Space>
<Text type="secondary">{item.publishDate}</Text>
+ {isAdmin && (
+ <Button
+ type="text"
+ danger
+ icon={<DeleteOutlined />}
+ onClick={() => handleDeletePost(item)}
+ title="删除帖子(管理员)"
+ size="small"
+ >
+ 删除
+ </Button>
+ )}
</Space>
}
>
diff --git a/src/features/forum/pages/PostDetailPage.jsx b/src/features/forum/pages/PostDetailPage.jsx
index 5e28820..ba4da2f 100644
--- a/src/features/forum/pages/PostDetailPage.jsx
+++ b/src/features/forum/pages/PostDetailPage.jsx
@@ -13,10 +13,11 @@
Spin,
Space,
Tag,
- Empty
+ Empty,
+ Modal
} from 'antd';
-import { ArrowLeftOutlined, MessageOutlined, UserOutlined, CommentOutlined } from '@ant-design/icons';
-import { getComments, addComment } from '@/api/forum';
+import { ArrowLeftOutlined, MessageOutlined, UserOutlined, CommentOutlined, DeleteOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
+import { getComments, addComment, deleteComment } from '@/api/forum';
import { useAuth } from '@/features/auth/contexts/AuthContext';
const { Title, Paragraph, Text } = Typography;
@@ -25,7 +26,10 @@
const PostDetailPage = () => {
const { postId } = useParams();
const navigate = useNavigate();
- const { user, isAuthenticated } = useAuth();
+ const { user, isAuthenticated, hasRole } = useAuth();
+
+ // 判断是否为管理员
+ const isAdmin = hasRole('admin') || (user && user.uid && user.uid.includes('admin'));
const [loading, setLoading] = useState(true);
const [commenting, setCommenting] = useState(false);
const [postContent, setPostContent] = useState('');
@@ -159,6 +163,43 @@
replyForms.resetFields();
};
+ // 删除评论(管理员功能)
+ const handleDeleteComment = (comment) => {
+ Modal.confirm({
+ title: '确认删除评论',
+ icon: <ExclamationCircleOutlined />,
+ content: (
+ <div>
+ <p>您确定要删除这条评论吗?</p>
+ <p><strong>作者:</strong>{comment.writer}</p>
+ <p><strong>内容:</strong>{comment.content.length > 50 ? comment.content.substring(0, 50) + '...' : comment.content}</p>
+ <p className="text-red-500 mt-2">此操作不可撤销!</p>
+ </div>
+ ),
+ okText: '确认删除',
+ okType: 'danger',
+ cancelText: '取消',
+ async onOk() {
+ try {
+ const params = {
+ username: user.username,
+ commentId: comment.commentId
+ };
+ const response = await deleteComment(params);
+ if (response.message) {
+ message.success(response.message || '评论删除成功');
+ fetchPostAndComments(); // 重新加载评论
+ } else {
+ message.error(response.message || '删除评论失败');
+ }
+ } catch (error) {
+ console.error('删除评论失败:', error);
+ message.error(error.message || '删除评论失败');
+ }
+ },
+ });
+ };
+
// 格式化日期
const formatDate = (dateString) => {
try {
@@ -299,6 +340,19 @@
回复 #{comment.reviewerId}
</Tag>
)}
+ {isAdmin && (
+ <Button
+ type="text"
+ danger
+ size="small"
+ icon={<DeleteOutlined />}
+ onClick={() => handleDeleteComment(comment)}
+ title="删除评论(管理员)"
+ className="ml-2"
+ >
+ 删除
+ </Button>
+ )}
</div>
}
description={