| // import React, { useEffect, useState } from 'react'; |
| // import { useParams } from 'wouter'; |
| // import { GoodTwo, Star } from '@icon-park/react'; |
| // import { getPostDetail, getPostComments, likePost, unlikePost, addCommentToPost, collectPost } from './api'; // 引入你的 API 函数 |
| // import './PostDetailPage.css'; |
| // import { useUser } from '../../../context/UserContext'; // 注意路径 |
| // import Header from '../../../components/Header'; |
| |
| // const PostDetailPage = () => { |
| // const { postId } = useParams(); // 获取帖子ID |
| // const [postDetail, setPostDetail] = useState(null); |
| // const [comments, setComments] = useState([]); |
| // const [loading, setLoading] = useState(true); |
| // const [errorMsg, setErrorMsg] = useState(''); |
| // const [newComment, setNewComment] = useState(''); // 新评论内容 |
| // const [isAnonymous, setIsAnonymous] = useState(false); // 是否匿名 |
| // const [isLiked, setIsLiked] = useState(false); // 是否已点赞 |
| // const [isCollected, setIsCollected] = useState(false); // 是否已收藏 |
| // const [replyToCommentId, setReplyToCommentId] = useState(null); // 回复的评论ID |
| |
| // // 获取当前用户ID(假设从上下文中获取) |
| // const { user } = useUser(); // 你需要从用户上下文获取用户 ID |
| |
| // useEffect(() => { |
| // const fetchPostDetail = async () => { |
| // setLoading(true); |
| // setErrorMsg(''); |
| // try { |
| // // 获取帖子详情 |
| // const postData = await getPostDetail(postId); |
| // setPostDetail(postData); |
| |
| // // 获取帖子评论 |
| // const commentsData = await getPostComments(postId); |
| // setComments(commentsData); |
| |
| // // 设置是否已经点赞 |
| // if (postData.likedByUser) { |
| // setIsLiked(true); |
| // } else { |
| // setIsLiked(false); |
| // } |
| |
| // // 设置是否已经收藏 |
| // if (postData.collectedByUser) { |
| // setIsCollected(true); |
| // } else { |
| // setIsCollected(false); |
| // } |
| // } catch (err) { |
| // console.error('加载失败:', err); |
| // setErrorMsg('加载失败,请稍后重试'); |
| // } finally { |
| // setLoading(false); |
| // } |
| // }; |
| |
| // fetchPostDetail(); |
| // }, [postId]); |
| |
| // // 点赞功能 |
| // const toggleLike = async () => { |
| // if (!user) { |
| // alert('请先登录'); |
| // return; |
| // } |
| |
| // try { |
| // if (isLiked) { |
| // // 取消点赞 |
| // await unlikePost(postId, user.id); |
| // setIsLiked(false); |
| // setPostDetail((prev) => ({ |
| // ...prev, |
| // postLikeNum: prev.postLikeNum - 1, |
| // })); |
| // } else { |
| // // 点赞 |
| // await likePost(postId, user.id); |
| // setIsLiked(true); |
| // setPostDetail((prev) => ({ |
| // ...prev, |
| // postLikeNum: prev.postLikeNum + 1, |
| // })); |
| // } |
| // } catch (err) { |
| // console.error('点赞失败:', err); |
| // alert('点赞失败,请稍后再试'); |
| // } |
| // }; |
| |
| // // 收藏功能 |
| // const toggleCollect = async () => { |
| // if (!user) { |
| // alert('请先登录'); |
| // return; |
| // } |
| |
| // try { |
| // const action = isCollected ? 'cancel' : 'collect'; |
| // // 调用收藏 API |
| // await collectPost(postId, user.id, action); |
| // setIsCollected(!isCollected); |
| // setPostDetail((prev) => ({ |
| // ...prev, |
| // postCollectNum: isCollected ? prev.postCollectNum - 1 : prev.postCollectNum + 1, |
| // })); |
| // } catch (err) { |
| // console.error('收藏失败:', err); |
| // alert('收藏失败,请稍后再试'); |
| // } |
| // }; |
| |
| // // 添加评论 |
| // const handleAddComment = async () => { |
| // if (!newComment.trim()) { |
| // alert('评论内容不能为空'); |
| // return; |
| // } |
| |
| // try { |
| // // 调用 API 添加评论,若为回复评论则传递父评论ID(com_comment_id) |
| // const commentData = await addCommentToPost(postId, user.id, newComment, isAnonymous, replyToCommentId); |
| // // 更新评论列表 |
| // setComments((prev) => [ |
| // ...prev, |
| // { |
| // commentId: commentData.commentId, |
| // post_id: postId, |
| // userId: user.id, |
| // content: newComment, |
| // isAnonymous, |
| // commentTime: new Date().toISOString(), |
| // comCommentId: replyToCommentId, // 回复评论时传递父评论ID |
| // }, |
| // ]); |
| // // 清空评论框和回复状态 |
| // setNewComment(''); |
| // setReplyToCommentId(null); |
| // } catch (err) { |
| // console.error('评论添加失败:', err); |
| // alert('评论失败,请稍后再试'); |
| // } |
| // }; |
| |
| // // 回复评论 |
| // const handleReply = (commentId) => { |
| // setReplyToCommentId(commentId); // 设置父评论ID为当前评论的ID |
| // }; |
| |
| // return ( |
| // <div className="post-detail-page"> |
| // <Header /> |
| // {loading ? ( |
| // <p>加载中...</p> |
| // ) : errorMsg ? ( |
| // <p className="error-text">{errorMsg}</p> |
| // ) : postDetail ? ( |
| // <div className="post-detail"> |
| // <h1>{postDetail.title}</h1> |
| // <div className="post-meta"> |
| // <span className="post-user">用户ID: {postDetail.user_id}</span> |
| // <span className="post-time"> |
| // 发布时间:{new Date(postDetail.postTime).toLocaleString()} |
| // </span> |
| // </div> |
| // <div className="post-content"> |
| // <p>{postDetail.postContent}</p> |
| // {Array.isArray(postDetail.imgUrl) ? ( |
| // <div className="post-images"> |
| // {postDetail.imgUrl.map((url, idx) => ( |
| // <img key={idx} src={url} alt={`图片${idx}`} /> |
| // ))} |
| // </div> |
| // ) : ( |
| // postDetail.imgUrl && ( |
| // <img className="post-image" src={postDetail.imgUrl} alt="帖子图片" /> |
| // ) |
| // )} |
| |
| // </div> |
| |
| // {/* 点赞和收藏 */} |
| // <div className="post-actions"> |
| // <button |
| // className="icon-btn" |
| // onClick={toggleLike} // 点赞操作 |
| // > |
| // <GoodTwo |
| // theme="outline" |
| // size="20" |
| // fill={isLiked ? '#f00' : '#ccc'} // 如果已点赞,显示红色 |
| // /> |
| // <span>{postDetail.postLikeNum}</span> |
| // </button> |
| // <button |
| // className="icon-btn" |
| // onClick={toggleCollect} // 收藏操作 |
| // > |
| // <Star |
| // theme="outline" |
| // size="20" |
| // fill={isCollected ? '#ffd700' : '#ccc'} // 如果已收藏,显示金色 |
| // /> |
| // <span>{postDetail.postCollectNum}</span> |
| // </button> |
| // </div> |
| |
| // <hr className="divider" /> |
| // {/* 评论部分 */} |
| // <h3>评论区</h3> |
| // <div className="comments-section"> |
| // {comments.length ? ( |
| // comments.map((comment) => ( |
| // <div key={comment.commentId} className="comment"> |
| // <div className="comment-header"> |
| // <span className="comment-user">用户 ID: {comment.userId}</span> |
| // <button className="reply-btn" onClick={() => handleReply(comment.commentId)}>回复</button> |
| // </div> |
| // <p className="comment-content">{comment.content}</p> |
| // <div className="comment-time"> |
| // {new Date(comment.commentTime).toLocaleString()} |
| // </div> |
| |
| // {/* 回复框,只有在当前评论是正在回复的评论时显示 */} |
| // {replyToCommentId === comment.commentId && ( |
| // <div className="reply-form"> |
| // <textarea |
| // placeholder="输入你的回复..." |
| // value={newComment} |
| // onChange={(e) => setNewComment(e.target.value)} |
| // /> |
| // <div className="comment-options"> |
| // <label> |
| // <input |
| // type="checkbox" |
| // checked={isAnonymous} |
| // onChange={() => setIsAnonymous(!isAnonymous)} |
| // /> |
| // 匿名评论 |
| // </label> |
| // <button onClick={handleAddComment}>发布回复</button> |
| // </div> |
| // </div> |
| // )} |
| // </div> |
| // )) |
| // ) : ( |
| // <p>暂无评论</p> |
| // )} |
| |
| // {/* 添加评论表单 */} |
| // <div className="add-comment-form"> |
| // <textarea |
| // placeholder="输入你的评论..." |
| // value={newComment} |
| // onChange={(e) => setNewComment(e.target.value)} |
| // /> |
| // <div className="comment-options"> |
| // <label> |
| // <input |
| // type="checkbox" |
| // checked={isAnonymous} |
| // onChange={() => setIsAnonymous(!isAnonymous)} |
| // /> |
| // 匿名评论 |
| // </label> |
| // <button onClick={handleAddComment}>发布评论</button> |
| // </div> |
| // </div> |
| // </div> |
| // </div> |
| // ) : ( |
| // <p>帖子不存在</p> |
| // )} |
| // </div> |
| // ); |
| // }; |
| |
| // export default PostDetailPage; |
| |
| import React, { useEffect, useState } from 'react'; |
| import { useParams } from 'wouter'; |
| import { GoodTwo, Star } from '@icon-park/react'; |
| import { getPostDetail, getPostComments, likePost, unlikePost, addCommentToPost, collectPost, uncollectPost } from './api'; // 引入你的 API 函数 |
| import './PostDetailPage.css'; |
| import { useUser } from '../../../context/UserContext'; // 注意路径 |
| import Header from '../../../components/Header'; |
| |
| const PostDetailPage = () => { |
| const { postId } = useParams(); // 获取帖子ID |
| const [postDetail, setPostDetail] = useState(null); |
| const [comments, setComments] = useState([]); |
| const [loading, setLoading] = useState(true); |
| const [errorMsg, setErrorMsg] = useState(''); |
| const [newComment, setNewComment] = useState(''); // 新评论内容 |
| // const [isAnonymous, setIsAnonymous] = useState(false); // 是否匿名 |
| const [isLiked, setIsLiked] = useState(false); // 是否已点赞 |
| const [isCollected, setIsCollected] = useState(false); // 是否已收藏 |
| const [replyToCommentId, setReplyToCommentId] = useState(null); // 回复的评论ID |
| |
| // 获取当前用户ID(假设从上下文中获取) |
| const { user } = useUser(); // 你需要从用户上下文获取用户 ID |
| |
| useEffect(() => { |
| const fetchPostDetail = async () => { |
| setLoading(true); |
| setErrorMsg(''); |
| try { |
| // 获取帖子详情 |
| const postData = await getPostDetail(postId); |
| setPostDetail(postData); |
| |
| // 获取帖子评论 |
| const commentsData = await getPostComments(postId); |
| setComments(commentsData); |
| |
| // 设置是否已经点赞 |
| if (postData.likedByUser) { |
| setIsLiked(true); |
| } else { |
| setIsLiked(false); |
| } |
| |
| // 设置是否已经收藏 |
| if (postData.collectedByUser) { |
| setIsCollected(true); |
| } else { |
| setIsCollected(false); |
| } |
| } catch (err) { |
| console.error('加载失败:', err); |
| setErrorMsg('加载失败,请稍后重试'); |
| } finally { |
| setLoading(false); |
| } |
| }; |
| |
| fetchPostDetail(); |
| }, [postId]); |
| |
| // 点赞功能 |
| const toggleLike = async () => { |
| if (!user) { |
| alert('请先登录'); |
| return; |
| } |
| |
| try { |
| if (isLiked) { |
| // 取消点赞 |
| await unlikePost(postId, user.id); |
| setIsLiked(false); |
| setPostDetail((prev) => ({ |
| ...prev, |
| postLikeNum: prev.postLikeNum - 1, |
| })); |
| } else { |
| // 点赞 |
| await likePost(postId, user.id); |
| setIsLiked(true); |
| setPostDetail((prev) => ({ |
| ...prev, |
| postLikeNum: prev.postLikeNum + 1, |
| })); |
| } |
| } catch (err) { |
| console.error('点赞失败:', err); |
| alert('点赞失败,请稍后再试'); |
| } |
| }; |
| |
| // 收藏功能 |
| const toggleCollect = async () => { |
| if (!user) { |
| alert('请先登录'); |
| return; |
| } |
| |
| try { |
| if (isCollected) { |
| // 取消收藏 - 使用原有的collectPost函数,传递action: "cancel" |
| await collectPost(postId, user.id, "cancel"); |
| setIsCollected(false); |
| setPostDetail((prev) => ({ |
| ...prev, |
| postCollectNum: prev.postCollectNum - 1, |
| })); |
| } else { |
| // 收藏 |
| await collectPost(postId, user.id, "collect"); |
| setIsCollected(true); |
| setPostDetail((prev) => ({ |
| ...prev, |
| postCollectNum: prev.postCollectNum + 1, |
| })); |
| } |
| } catch (err) { |
| console.error('收藏操作失败:', err); |
| alert('收藏操作失败,请稍后再试'); |
| } |
| }; |
| |
| // 添加评论 |
| const handleAddComment = async () => { |
| if (!newComment.trim()) { |
| alert('评论内容不能为空'); |
| return; |
| } |
| |
| try { |
| // 调用 API 添加评论,若为回复评论则传递父评论ID(com_comment_id) |
| const commentData = await addCommentToPost(postId, user.id, newComment, replyToCommentId); |
| // 更新评论列表 |
| setComments((prev) => [ |
| ...prev, |
| { |
| commentId: commentData.commentId, |
| post_id: postId, |
| userId: user.id, |
| content: newComment, |
| // isAnonymous, |
| commentTime: new Date().toISOString(), |
| comCommentId: replyToCommentId, // 回复评论时传递父评论ID |
| }, |
| ]); |
| // 清空评论框和回复状态 |
| setNewComment(''); |
| setReplyToCommentId(null); |
| } catch (err) { |
| console.error('评论添加失败:', err); |
| alert('评论失败,请稍后再试'); |
| } |
| }; |
| |
| // 回复评论 |
| const handleReply = (commentId) => { |
| setReplyToCommentId(commentId); // 设置父评论ID为当前评论的ID |
| }; |
| |
| return ( |
| <div className="post-detail-page"> |
| <Header /> |
| {loading ? ( |
| <p>加载中...</p> |
| ) : errorMsg ? ( |
| <p className="error-text">{errorMsg}</p> |
| ) : postDetail ? ( |
| <div className="post-detail"> |
| <h1>{postDetail.title}</h1> |
| <div className="post-meta"> |
| <span className="post-user">用户ID: {postDetail.user_id}</span> |
| <span className="post-time"> |
| 发布时间:{new Date(postDetail.postTime).toLocaleString()} |
| </span> |
| </div> |
| <div className="post-content"> |
| <p>{postDetail.postContent}</p> |
| {Array.isArray(postDetail.imgUrl) ? ( |
| <div className="post-images"> |
| {postDetail.imgUrl.map((url, idx) => ( |
| <img key={idx} src={url} alt={`图片${idx}`} /> |
| ))} |
| </div> |
| ) : ( |
| postDetail.imgUrl && ( |
| <img className="post-image" src={postDetail.imgUrl} alt="帖子图片" /> |
| ) |
| )} |
| |
| </div> |
| |
| {/* 点赞和收藏 */} |
| <div className="post-actions"> |
| <button |
| className="icon-btn" |
| onClick={toggleLike} // 点赞操作 |
| > |
| <GoodTwo |
| theme="outline" |
| size="20" |
| fill={isLiked ? '#f00' : '#ccc'} // 如果已点赞,显示红色 |
| /> |
| <span>{postDetail.postLikeNum}</span> |
| </button> |
| <button |
| className="icon-btn" |
| onClick={toggleCollect} // 收藏操作 |
| > |
| <Star |
| theme="outline" |
| size="20" |
| fill={isCollected ? '#ffd700' : '#ccc'} // 如果已收藏,显示金色 |
| /> |
| <span>{postDetail.postCollectNum}</span> |
| </button> |
| </div> |
| |
| <hr className="divider" /> |
| {/* 评论部分 */} |
| <h3>评论区</h3> |
| <div className="comments-section"> |
| {comments.length ? ( |
| comments.map((comment) => ( |
| <div key={comment.commentId} className="comment"> |
| <div className="comment-header"> |
| <span className="comment-user">用户 ID: {comment.userId}</span> |
| <button className="reply-btn" onClick={() => handleReply(comment.commentId)}>回复</button> |
| </div> |
| <p className="comment-content">{comment.content}</p> |
| <div className="comment-time"> |
| {new Date(comment.commentTime).toLocaleString()} |
| </div> |
| |
| {/* 回复框,只有在当前评论是正在回复的评论时显示 */} |
| {replyToCommentId === comment.commentId && ( |
| <div className="reply-form"> |
| <textarea |
| placeholder="输入你的回复..." |
| value={newComment} |
| onChange={(e) => setNewComment(e.target.value)} |
| /> |
| <div className="comment-options"> |
| {/* <label> */} |
| {/* <input */} |
| {/* type="checkbox" */} |
| {/* checked={isAnonymous} */} |
| {/* onChange={() => setIsAnonymous(!isAnonymous)} */} |
| {/* /> */} |
| {/* 匿名评论 */} |
| {/* </label> */} |
| <button onClick={handleAddComment}>发布回复</button> |
| </div> |
| </div> |
| )} |
| </div> |
| )) |
| ) : ( |
| <p>暂无评论</p> |
| )} |
| |
| {/* 添加评论表单 */} |
| <div className="add-comment-form"> |
| <textarea |
| placeholder="输入你的评论..." |
| value={newComment} |
| onChange={(e) => setNewComment(e.target.value)} |
| /> |
| <div className="comment-options"> |
| {/* <label> |
| <input |
| type="checkbox" |
| checked={isAnonymous} |
| onChange={() => setIsAnonymous(!isAnonymous)} |
| /> |
| 匿名评论 |
| </label> */} |
| <button onClick={handleAddComment}>发布评论</button> |
| </div> |
| </div> |
| </div> |
| </div> |
| ) : ( |
| <p>帖子不存在</p> |
| )} |
| </div> |
| ); |
| }; |
| |
| export default PostDetailPage; |