合并
Change-Id: I19ca58c58a513cba20c162c9ed7cbab90e060bf6
diff --git a/src/components/HelpDetail.jsx b/src/components/HelpDetail.jsx
index da50850..7e7b7c8 100644
--- a/src/components/HelpDetail.jsx
+++ b/src/components/HelpDetail.jsx
@@ -3,12 +3,14 @@
import {
getPostDetail,
addPostComment,
- likePost
+ likePost,
+ deletePost
} from '../api/helpPost';
import {
likePostComment,
getCommentReplies,
- addCommentReply
+ addCommentReply,
+ deleteComment
} from '../api/helpComment';
import './HelpDetail.css';
@@ -22,12 +24,13 @@
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [newComment, setNewComment] = useState('');
- const [newReply, setNewReply] = useState({});
- const [images, setImages] = useState([]);
+ const [replyContent, setReplyContent] = useState('');
+ const [replyImage, setReplyImage] = useState([]);
+ const [commentImage, setCommentImage] = useState([]);
const [expandedReplies, setExpandedReplies] = useState({}); // 记录哪些评论的回复是展开的
const [loadingReplies, setLoadingReplies] = useState({});
const [setReplyingTo] = useState(null);
- const [replyContent, setReplyContent] = useState('');
+
const [activeReplyId, setActiveReplyId] = useState(null);
const [replyModal, setReplyModal] = useState({
@@ -58,7 +61,7 @@
setReplyContent('');
};
- const Comment = ({ comment, onLike, onReply, isReply = false }) => {
+ const Comment = ({ comment, onLike, onReply, onDelete, isReply = false }) => {
return (
<div className={`comment-container ${isReply ? "is-reply" : ""}`}>
<div className="comment-item">
@@ -76,6 +79,17 @@
</span>
</div>
<p className="comment-text">{comment.content}</p>
+ {/* 添加评论图片展示 */}
+ {comment.imageUrl && (
+ <div className="comment-image-container">
+ <img
+ src={`http://localhost:8088${comment.imageUrl}`}
+ alt="评论图片"
+ className="comment-image"
+ onClick={() => window.open(comment.imageUrl, '_blank')}
+ />
+ </div>
+ )}
<div className="comment-actions">
<button onClick={() => onLike(comment.id)}>
👍 ({comment.likeCount || 0})
@@ -83,6 +97,14 @@
<button onClick={() => onReply(comment.id, comment.authorId)}>
回复
</button>
+ {comment.authorId === localStorage.getItem('username') && (
+ <button
+ className="delete-comment-btn"
+ onClick={() => onDelete(comment.id)}
+ >
+ 删除
+ </button>
+ )}
</div>
</div>
</div>
@@ -99,6 +121,7 @@
onLike={handleLikeComment}
onReply={openReplyModal}
isReply={depth > 0}
+ onDelete={handleDeleteComment}
/>
{/* 递归渲染所有回复 */}
@@ -140,6 +163,19 @@
setError('点赞失败: ' + (err.response?.data?.message || err.message));
}
};
+
+ // 添加删除处理函数
+ const handleDeletePost = async (postId) => {
+ if (window.confirm('确定要删除这个帖子吗?所有评论也将被删除!')) {
+ try {
+ const username = localStorage.getItem('username');
+ await deletePost(postId, username);
+ navigate('/dashboard/help'); // 删除成功后返回求助区
+ } catch (err) {
+ setError('删除失败: ' + (err.response?.data?.message || err.message));
+ }
+ }
+ };
const handleCommentSubmit = async (e) => {
e.preventDefault();
@@ -196,6 +232,18 @@
}
};
+ const handleDeleteComment = async (commentId) => {
+ if (window.confirm('确定要删除这条评论吗?')) {
+ try {
+ const username = localStorage.getItem('username');
+ await deleteComment(commentId, username);
+ await fetchPostDetail(); // 刷新评论列表
+ } catch (err) {
+ setError('删除失败: ' + (err.response?.data?.message || err.message));
+ }
+ }
+ };
+
// 修改startReply函数
const startReply = (commentId) => {
@@ -217,15 +265,16 @@
try {
const username = localStorage.getItem('username');
const response = await addCommentReply(replyModal.replyingTo, {
+ authorId: username,
content: replyContent,
- authorId: username
+ image: replyImage
});
console.log('回复响应:', response.data); // 调试
if (response.data && response.data.code === 200) {
await fetchPostDetail();
-
+ setReplyContent('');
closeReplyModal();
}
} catch (err) {
@@ -251,15 +300,15 @@
}));
};
- const handleImageUpload = (e) => {
- const files = Array.from(e.target.files);
- const newImages = files.map(file => URL.createObjectURL(file));
- setImages(prev => [...prev, ...newImages]);
- };
+ // const handleImageUpload = (e) => {
+ // const files = Array.from(e.target.files);
+ // const newImages = files.map(file => URL.createObjectURL(file));
+ // setImages(prev => [...prev, ...newImages]);
+ // };
- const handleRemoveImage = (index) => {
- setImages(prev => prev.filter((_, i) => i !== index));
- };
+ // const handleRemoveImage = (index) => {
+ // setImages(prev => prev.filter((_, i) => i !== index));
+ // };
@@ -284,9 +333,19 @@
<div className="post-author">{post.authorId}</div>
<div className="post-date">
{new Date(post.createTime).toLocaleString()}
- </div>
+ </div>
</div>
- {post.isSolved && <span className="solved-badge">已解决</span>}
+ {post.isSolved && <span ClassName="solved-badge">已解决</span>}
+ <div classname="delete-post">
+ {post.authorId === localStorage.getItem('username') && (
+ <button
+ className="delete-button"
+ onClick={() => handleDeletePost(post.id)}
+ >
+ 删除帖子
+ </button>
+ )}
+ </div>
</div>
<h1 className="post-title">{post.title}</h1>
@@ -295,6 +354,21 @@
{post.content.split('\n').map((para, i) => (
<p key={i}>{para}</p>
))}
+ {/* 添加帖子图片展示 */}
+ {post.imageUrl && (
+ <div className="post-image-container">
+ <img
+ src={`http://localhost:8088${post.imageUrl}`}
+ alt="帖子图片"
+ className="post-image"
+ // onError={(e) => {
+ // e.target.onerror = null;
+ // e.target.src = 'https://via.placeholder.com/400x300?text=图片加载失败';
+ // console.error('图片加载失败:', post.imageUrl);
+ // }}
+ />
+ </div>
+ )}
</div>
<div className="post-actions">
@@ -325,8 +399,21 @@
required
/>
<button type="submit">发表评论</button>
+
+ {/* 图片上传部分 */}
+ <div className="form-group">
+ <div className="upload-image-btn">
+ <input
+ type="file"
+ accept="image/*"
+ onChange={(e) => setCommentImage(e.target.files[0])}
+ data-testid="comment-image-input"
+ />
+ </div>
+ </div>
</form>
+
<div className="comment-list">
{comments.map(comment => renderComment(comment))}
</div>
@@ -347,6 +434,18 @@
autoFocus
required
/>
+
+ {/* 图片上传部分 */}
+ <div className="form-group">
+ <div className="upload-image-btn">
+ <input
+ type="file"
+ accept="image/*"
+ onChange={(e) => setReplyImage(e.target.files[0])}
+ />
+ </div>
+ </div>
+
<div className="modal-actions">
<button type="button" onClick={closeReplyModal} className="cancel-btn">
取消