blob: fceaef845fabd38e15aecbbc1d7e28d152cf3923 [file] [log] [blame]
import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { API_BASE_URL } from "./config";
export default function PostDetailPage() {
const { postId } = useParams();
const [post, setPost] = useState(null);
const [replies, setReplies] = useState([]);
const [newReply, setNewReply] = useState('');
// function to load post details and its replies
const fetchDetail = () => {
fetch(`${API_BASE_URL}/api/forum-detail?postid=${postId}`)
.then(res => res.json())
.then(data => {
console.log("Fetched post detail:", data);
const p = data.post || data;
const formattedPost = {
post_id: p.postid,
title: p.posttitle,
content: p.postcontent,
author_id: p.postuserid,
author_name: p.author?.username || '',
created_at: new Date(p.posttime).toLocaleString(),
reply_count: p.replytime,
view_count: p.readtime,
};
const formattedReplies = (data.replies || []).map(r => ({
reply_id: r.replyid,
post_id: r.postid || postId,
content: r.content,
author_id: r.authorid,
author_name: r.author?.username || '',
created_at: new Date(r.createdAt).toLocaleString(),
}));
setPost(formattedPost);
setReplies(formattedReplies);
})
.catch(err => console.error(err));
};
useEffect(() => {
fetchDetail();
}, [postId]);
// post a new reply to backend
const handleReply = () => {
const match = document.cookie.match('(^|;)\\s*userId=([^;]+)');
const userId = match ? match[2] : null;
if (!userId) {
alert('请先登录后再回复');
return;
}
fetch(`${API_BASE_URL}/api/forum-reply`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ postid: postId, replycontent: newReply, replyuserid: userId }),
})
.then(res => res.json())
.then(() => {
setNewReply('');
fetchDetail();
})
.catch(err => console.error(err));
};
if (!post) return <div>加载中...</div>;
return (
<div style={{ maxWidth: 700, margin: "40px auto" }}>
{/* 原帖 */}
<div style={{
background: "#fff",
borderRadius: 12,
boxShadow: "0 2px 8px #e0e7ff",
padding: 24,
marginBottom: 32,
}}>
<div style={{ fontSize: 15, color: "#1976d2", marginBottom: 6 }}>
{post.author_name} · {post.created_at}
</div>
<div style={{ fontWeight: 600, fontSize: 20, marginBottom: 8, color: "#222" }}>
{post.title}
</div>
<div style={{ fontSize: 16, color: "#444", marginBottom: 18 }}>
{post.content}
</div>
<div style={{ display: "flex", justifyContent: "flex-start", gap: 32, fontSize: 14, color: "#888" }}>
<span>回复数: {post.reply_count}</span>
<span>观看数: {post.view_count}</span>
</div>
</div>
{/* 评论区 */}
<div>
{replies.map(reply => (
<div key={reply.reply_id} style={{
display: "flex",
alignItems: "center",
background: "#f8faff",
borderRadius: 8,
padding: "12px 18px",
marginBottom: 16,
fontSize: 15,
}}>
<span style={{ color: "#1976d2", fontWeight: 500, minWidth: 80 }}>{reply.author_name}</span>
<span style={{ flex: 1, marginLeft: 18 }}>{reply.content}</span>
<span style={{ color: "#888", fontSize: 13, marginLeft: 18 }}>{reply.created_at}</span>
</div>
))}
</div>
{/* 回复框 */}
<div style={{
marginTop: 32,
background: "#fff",
borderRadius: 8,
boxShadow: "0 2px 8px #e0e7ff",
padding: 18,
display: "flex",
gap: 12,
alignItems: "center"
}}>
<input
type="text"
placeholder="写下你的回复..."
value={newReply}
onChange={e => setNewReply(e.target.value)}
style={{
flex: 1,
border: "1px solid #bfcfff",
borderRadius: 6,
padding: "8px 12px",
fontSize: 15,
}}
/>
<button onClick={handleReply} style={{
background: "#1976d2",
color: "#fff",
border: "none",
borderRadius: 6,
padding: "8px 24px",
fontSize: 15,
cursor: "pointer"
}}>回复</button>
</div>
</div>
);
}