blob: 159bdfaf3c2f26b8035a0a24c43c79a666c454de [file] [log] [blame]
import React, { useContext, 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 { UserContext, 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
const [replyToUsername, setReplyToUsername] = useState(null);
// 获取当前用户ID(假设从上下文中获取)
const { user } = useContext(UserContext);
// 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.userId);
setIsLiked(false);
setPostDetail((prev) => ({
...prev,
postLikeNum: prev.postLikeNum - 1,
}));
} else {
// 点赞
await likePost(postId, user.userId);
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.userId, "cancel");
setIsCollected(false);
setPostDetail((prev) => ({
...prev,
postCollectNum: prev.postCollectNum - 1,
}));
} else {
// 收藏
await collectPost(postId, user.userId, "collect");
setIsCollected(true);
setPostDetail((prev) => ({
...prev,
postCollectNum: prev.postCollectNum + 1,
}));
}
} catch (err) {
console.error('收藏操作失败:', err);
alert('收藏操作失败,请稍后再试');
}
};
// 添加评论
const handleAddComment = async () => {
// 直接使用组件顶层获取的 user
if (!user || !user.userId) {
alert('请先登录后再评论');
return;
}
if (!newComment.trim()) {
alert('评论内容不能为空');
return;
}
try {
// 构建评论数据
const commentPayload = {
content: newComment,
userId: user.userId, // 使用已获取的用户ID
isAnonymous: false,
com_comment_id: replyToCommentId || null,
};
// 发送评论请求
const commentData = await addCommentToPost(postId, commentPayload);
// 更新评论列表
const newCommentItem = {
commentId: commentData?.commentId || Date.now(),
post_id: postId,
userId: user.userId,
content: newComment,
commentTime: new Date().toISOString(),
comCommentId: replyToCommentId,
};
setComments((prevComments) => [newCommentItem, ...prevComments]);
// 重置表单
setNewComment('');
setReplyToCommentId(null);
// alert('评论成功!');
} catch (error) {
console.error('评论失败:', error);
const errorMessage =
error.response?.data?.message ||
error.message ||
'评论失败,请稍后再试';
alert(errorMessage);
}
};
// 回复评论
const handleReply = (commentId) => {
setReplyToCommentId(commentId);
const comment = comments.find(c => c.commentId === commentId);
if (comment) {
// 这里用用户名或者用户ID
setReplyToUsername(comment.username || comment.userId);
} else {
setReplyToUsername(null);
}
};
const findUsernameByCommentId = (id) => {
const comment = comments.find(c => c.commentId === id);
return comment ? (comment.username || comment.userId) : '未知用户';
};
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.comCommentId ? (
<>
<span className="reply-to">回复 {findUsernameByCommentId(comment.comCommentId)}:</span>
{comment.content}
</>
) : (
comment.content
)}
</p>
<div className="comment-time">
{new Date(comment.commentTime).toLocaleString()}
</div>
{/* 回复框 */}
{replyToCommentId === comment.commentId && (
<div className="reply-form">
<div className="replying-to">
回复 <strong>{replyToUsername}</strong>:
</div>
<textarea
placeholder="输入你的回复..."
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
/>
<div className="comment-options">
<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;