From 256f2ea6494e9a42d4fb36f4d468effa8305ba99 Mon Sep 17 00:00:00 2001 From: Leo <98382335+gaoziman@users.noreply.github.com> Date: Thu, 9 Oct 2025 23:46:10 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9F=BA=E7=A1=80=E5=85=AC?= =?UTF-8?q?=E5=85=B1=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建非遗项目卡片组件(HeritageCard) - 创建传承人卡片组件(InheritorCard) - 创建自定义分页组件(CustomPagination) - 创建评论区组件(CommentSection) --- src/components/CommentSection/index.css | 101 ++++++++ src/components/CommentSection/index.tsx | 172 +++++++++++++ src/components/CustomPagination/index.css | 278 ++++++++++++++++++++++ src/components/CustomPagination/index.tsx | 196 +++++++++++++++ src/components/HeritageCard/index.css | 153 ++++++++++++ src/components/HeritageCard/index.tsx | 90 +++++++ src/components/InheritorCard/index.css | 113 +++++++++ src/components/InheritorCard/index.tsx | 69 ++++++ 8 files changed, 1172 insertions(+) create mode 100644 src/components/CommentSection/index.css create mode 100644 src/components/CommentSection/index.tsx create mode 100644 src/components/CustomPagination/index.css create mode 100644 src/components/CustomPagination/index.tsx create mode 100644 src/components/HeritageCard/index.css create mode 100644 src/components/HeritageCard/index.tsx create mode 100644 src/components/InheritorCard/index.css create mode 100644 src/components/InheritorCard/index.tsx diff --git a/src/components/CommentSection/index.css b/src/components/CommentSection/index.css new file mode 100644 index 0000000..d03166e --- /dev/null +++ b/src/components/CommentSection/index.css @@ -0,0 +1,101 @@ +/* 评论区组件样式 */ + +.comment-section { + margin-top: 40px; + padding: 24px; + background: #ffffff; + border-radius: 12px; +} + +.comment-header h3 { + font-size: 20px; + font-weight: 600; + margin-bottom: 24px; + color: #2c2c2c; +} + +/* 评论编辑器 */ +.comment-editor { + margin-bottom: 32px; + padding: 20px; + background: #f5f0e8; + border-radius: 8px; +} + +.comment-rating { + margin-bottom: 16px; + display: flex; + align-items: center; + gap: 12px; +} + +.comment-rating span { + font-size: 14px; + color: #666666; +} + +.comment-editor .ant-input { + margin-bottom: 12px; +} + +.comment-actions { + display: flex; + justify-content: flex-end; +} + +.comment-login-tip { + padding: 40px 20px; + text-align: center; + background: #f5f0e8; + border-radius: 8px; + margin-bottom: 24px; +} + +.comment-login-tip p { + color: #666666; + margin: 0; +} + +/* 评论列表 */ +.comment-list .ant-list-item { + padding: 20px 0; + border-bottom: 1px solid #f0ebe3; +} + +.comment-list .ant-list-item:last-child { + border-bottom: none; +} + +.comment-title { + display: flex; + align-items: center; + gap: 12px; +} + +.comment-author { + font-size: 15px; + font-weight: 600; + color: #2c2c2c; +} + +.comment-content p { + font-size: 14px; + color: #666666; + line-height: 1.8; + margin: 8px 0; +} + +.comment-time { + font-size: 13px; + color: #999999; +} + +.comment-action { + color: #999999; + cursor: pointer; + transition: color 0.3s ease; +} + +.comment-action:hover { + color: #c8363d; +} diff --git a/src/components/CommentSection/index.tsx b/src/components/CommentSection/index.tsx new file mode 100644 index 0000000..4cc3b8c --- /dev/null +++ b/src/components/CommentSection/index.tsx @@ -0,0 +1,172 @@ +/** + * 评论区组件 + */ + +import React, { useState, useEffect } from 'react' +import { List, Avatar, Rate, Button, Input, message, Empty } from 'antd' +import { LikeOutlined, LikeFilled } from '@ant-design/icons' +import dayjs from 'dayjs' +import relativeTime from 'dayjs/plugin/relativeTime' +import 'dayjs/locale/zh-cn' +import type { Comment } from '@types/index' +import { getCommentsByTarget, addComment } from '@services/api' +import { useUserStore } from '@store/useUserStore' +import './index.css' + +dayjs.extend(relativeTime) +dayjs.locale('zh-cn') + +const { TextArea } = Input + +interface CommentSectionProps { + targetType: 'heritage' | 'inheritor' | 'course' | 'news' + targetId: string + showRating?: boolean +} + +const CommentSection: React.FC = ({ + targetType, + targetId, + showRating = false, +}) => { + const [comments, setComments] = useState([]) + const [loading, setLoading] = useState(false) + const [submitting, setSubmitting] = useState(false) + const [content, setContent] = useState('') + const [rating, setRating] = useState(5) + + const { user, isAuthenticated } = useUserStore() + + useEffect(() => { + fetchComments() + }, [targetType, targetId]) + + const fetchComments = async () => { + setLoading(true) + try { + const data = await getCommentsByTarget(targetType, targetId) + setComments(data) + } catch (error) { + console.error('Failed to fetch comments:', error) + } finally { + setLoading(false) + } + } + + const handleSubmit = async () => { + if (!isAuthenticated) { + message.warning('请先登录后再发表评论') + return + } + + if (!content.trim()) { + message.warning('请输入评论内容') + return + } + + setSubmitting(true) + try { + const newComment = await addComment({ + userId: user!.id, + userName: user!.nickname, + userAvatar: user!.avatar, + targetType, + targetId, + content, + rating: showRating ? rating : undefined, + likeCount: 0, + replyCount: 0, + }) + + setComments([newComment, ...comments]) + setContent('') + setRating(5) + message.success('评论发表成功') + } catch (error) { + message.error('评论发表失败') + } finally { + setSubmitting(false) + } + } + + return ( +
+
+

全部评论 ({comments.length})

+
+ + {/* 评论输入框 */} + {isAuthenticated && ( +
+ {showRating && ( +
+ 评分: + +
+ )} +