修改论坛、促销、登录,增加测试

Change-Id: I71883fc1da46a94db47f90a4cd61474c274a5b2c
diff --git a/src/pages/Forum/posts-detail/PostDetailPage.css b/src/pages/Forum/posts-detail/PostDetailPage.css
index 780492b..570b65f 100644
--- a/src/pages/Forum/posts-detail/PostDetailPage.css
+++ b/src/pages/Forum/posts-detail/PostDetailPage.css
@@ -1,5 +1,5 @@
    .post-detail-page {
-    background: linear-gradient(180deg, #5F4437, #823c3c);
+    background: #333;
     font-family: 'Helvetica Neue', sans-serif;
     color: #333;
   }
diff --git a/src/pages/Forum/posts-detail/PostDetailPage.jsx b/src/pages/Forum/posts-detail/PostDetailPage.jsx
index 01e1648..c58ed33 100644
--- a/src/pages/Forum/posts-detail/PostDetailPage.jsx
+++ b/src/pages/Forum/posts-detail/PostDetailPage.jsx
@@ -1,7 +1,288 @@
+// 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 } from './api'; // 引入你的 API 函数
+import { getPostDetail, getPostComments, likePost, unlikePost, addCommentToPost, collectPost, uncollectPost } from './api'; // 引入你的 API 函数
 import './PostDetailPage.css';
 import { useUser } from '../../../context/UserContext'; // 注意路径
 import Header from '../../../components/Header';
@@ -13,7 +294,7 @@
   const [loading, setLoading] = useState(true);
   const [errorMsg, setErrorMsg] = useState('');
   const [newComment, setNewComment] = useState(''); // 新评论内容
-  const [isAnonymous, setIsAnonymous] = useState(false); // 是否匿名
+  // const [isAnonymous, setIsAnonymous] = useState(false); // 是否匿名
   const [isLiked, setIsLiked] = useState(false); // 是否已点赞
   const [isCollected, setIsCollected] = useState(false); // 是否已收藏
   const [replyToCommentId, setReplyToCommentId] = useState(null); // 回复的评论ID
@@ -89,27 +370,36 @@
     }
   };
 
-  // 收藏功能
-  const toggleCollect = async () => {
+// 收藏功能
+const toggleCollect = async () => {
     if (!user) {
-      alert('请先登录');
-      return;
+        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,
-      }));
+        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('收藏失败,请稍后再试');
+        console.error('收藏操作失败:', err);
+        alert('收藏操作失败,请稍后再试');
     }
-  };
+};
 
   // 添加评论
   const handleAddComment = async () => {
@@ -120,7 +410,7 @@
 
     try {
       // 调用 API 添加评论,若为回复评论则传递父评论ID(com_comment_id)
-      const commentData = await addCommentToPost(postId, user.id, newComment, isAnonymous, replyToCommentId);
+      const commentData = await addCommentToPost(postId, user.id, newComment, replyToCommentId);
       // 更新评论列表
       setComments((prev) => [
         ...prev,
@@ -129,7 +419,7 @@
           post_id: postId,
           userId: user.id,
           content: newComment,
-          isAnonymous,
+          // isAnonymous,
           commentTime: new Date().toISOString(),
           comCommentId: replyToCommentId, // 回复评论时传递父评论ID
         },
@@ -231,14 +521,14 @@
                         onChange={(e) => setNewComment(e.target.value)}
                       />
                       <div className="comment-options">
-                        <label>
-                          <input
-                            type="checkbox"
-                            checked={isAnonymous}
-                            onChange={() => setIsAnonymous(!isAnonymous)}
-                          />
-                          匿名评论
-                        </label>
+                        {/* <label> */}
+                          {/* <input */}
+                            {/* type="checkbox" */}
+                            {/* checked={isAnonymous} */}
+                            {/* onChange={() => setIsAnonymous(!isAnonymous)} */}
+                          {/* /> */}
+                          {/* 匿名评论 */}
+                        {/* </label> */}
                         <button onClick={handleAddComment}>发布回复</button>
                       </div>
                     </div>
@@ -257,14 +547,14 @@
                 onChange={(e) => setNewComment(e.target.value)}
               />
               <div className="comment-options">
-                <label>
+                {/* <label>
                   <input
                     type="checkbox"
                     checked={isAnonymous}
                     onChange={() => setIsAnonymous(!isAnonymous)}
                   />
                   匿名评论
-                </label>
+                </label> */}
                 <button onClick={handleAddComment}>发布评论</button>
               </div>
             </div>
@@ -277,4 +567,4 @@
   );
 };
 
-export default PostDetailPage;
+export default PostDetailPage;
\ No newline at end of file
diff --git a/src/pages/Forum/posts-detail/api.js b/src/pages/Forum/posts-detail/api.js
index d05f148..27c3a18 100644
--- a/src/pages/Forum/posts-detail/api.js
+++ b/src/pages/Forum/posts-detail/api.js
@@ -2,22 +2,23 @@
 
 const API_BASE = process.env.REACT_APP_API_BASE;
 
+
 // 获取帖子详情
-export const getPostDetail = async (postId) => {
-    const response = await axios.get(`${API_BASE}/echo/forum/posts/${postId}/getPost`);
+export const getPostDetail = async (post_id) => {
+    const response = await axios.get(`${API_BASE}/echo/forum/posts/${post_id}/getPost`);
     return response.data;
 };
 
 // 获取帖子评论
-export const getPostComments = async (postId) => {
-    const response = await axios.get(`${API_BASE}/echo/forum/posts/${postId}/getAllComments`);
+export const getPostComments = async (post_id) => {
+    const response = await axios.get(`${API_BASE}/echo/forum/posts/${post_id}/getAllComments`);
     return response.data;
 };
 
 // 点赞帖子
-export const likePost = async (postId, userId) => {
+export const likePost = async (post_id, userId) => {
     try {
-        const response = await axios.post(`${API_BASE}/echo/forum/posts/${postId}/like`, {
+        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/like`, {
             user_id: userId,  // 用户 ID
         });
         return response.data;
@@ -27,15 +28,15 @@
 };
 
 // 取消点赞帖子
-export const unlikePost = async (postId) => {
-    const response = await axios.delete(`${API_BASE}/echo/forum/posts/${postId}/unlike`);
+export const unlikePost = async (post_id) => {
+    const response = await axios.delete(`${API_BASE}/echo/forum/posts/${post_id}/unlike`);
     return response.data;
 };
 
 // 添加评论
-export const addCommentToPost = async (postId, userId, content, isAnonymous, comCommentId = null) => {
+export const addCommentToPost = async (post_id, userId, content, isAnonymous, comCommentId = null) => {
     try {
-        const response = await axios.post(`${API_BASE}/echo/forum/posts/${postId}/comments`, {
+        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/comments`, {
             content,
             user_id: userId,
             is_anonymous: isAnonymous,
@@ -60,9 +61,9 @@
 };
 
 // 收藏帖子
-export const collectPost = async (postId, userId, action) => {
+export const collectPost = async (post_id, userId, action) => {
     try {
-        const response = await axios.post(`${API_BASE}/echo/forum/posts/${postId}/collect`, {
+        const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/collect`, {
             user_id: userId,
             action: action,  // "collect" 或 "cancel"
         });
@@ -72,6 +73,14 @@
     }
 };
 
+// // 取消收藏帖子
+// export const uncollectPost = async (post_id, userId) => {
+//     const response = await axios.post(`${API_BASE}/echo/forum/posts/${post_id}/uncollect`, {
+//         user_id: userId,  // 用户 ID
+//     });
+//     return response.data;
+// };
+
 // 获取用户信息
 export const getUserInfo = async (userId) => {
     const response = await axios.get(`${API_BASE}/user/${userId}/info`);