complete_postlike

Change-Id: If5a628b11d1bf19d531703ec1a8b62f1690ed7fb
diff --git a/src/main/java/com/example/g8backend/entity/PostLike.java b/src/main/java/com/example/g8backend/entity/PostLike.java
new file mode 100644
index 0000000..c3df741
--- /dev/null
+++ b/src/main/java/com/example/g8backend/entity/PostLike.java
@@ -0,0 +1,41 @@
+package com.example.g8backend.entity;
+
+import java.sql.Timestamp;
+
+public class PostLike {
+
+    private Long userId;
+    private Long postId;
+    private Timestamp createdAt;
+
+    public PostLike(Long userId, Long postId) {
+        this.userId = userId;
+        this.postId = postId;
+        this.createdAt = new Timestamp(System.currentTimeMillis());
+    }
+
+    // Getters and Setters
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public Long getPostId() {
+        return postId;
+    }
+
+    public void setPostId(Long postId) {
+        this.postId = postId;
+    }
+
+    public Timestamp getCreatedAt() {
+        return createdAt;
+    }
+
+    public void setCreatedAt(Timestamp createdAt) {
+        this.createdAt = createdAt;
+    }
+}
diff --git a/src/main/java/com/example/g8backend/mapper/PostMapper.java b/src/main/java/com/example/g8backend/mapper/PostMapper.java
index 0cba5c1..51c3164 100644
--- a/src/main/java/com/example/g8backend/mapper/PostMapper.java
+++ b/src/main/java/com/example/g8backend/mapper/PostMapper.java
@@ -1,17 +1,24 @@
 package com.example.g8backend.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.example.g8backend.entity.Post;
+import com.example.g8backend.entity.PostLike;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Delete;
+import org.apache.ibatis.annotations.Insert;
 
 import java.util.List;
 
 @Mapper
 public interface PostMapper extends BaseMapper<Post> {
+
+    // 获取用户的帖子
     List<Post> getPostsByUserId(@Param("userId") Long userId);
 
+    // 搜索帖子
     @Select("<script>" +
             "SELECT p.* " +
             "FROM posts p " +
@@ -30,6 +37,22 @@
             "</if>" +
             "</script>")
     List<Post> searchPosts(@Param("keyword") String keyword,
-                           @Param("tagIds") List<Long> tagIds,  // 改成接受一个tagIds列表
+                           @Param("tagIds") List<Long> tagIds,
                            @Param("author") String author);
+
+    // 检查用户是否已经点赞该帖子
+    @Select("SELECT EXISTS (SELECT 1 FROM post_likes WHERE user_id = #{userId} AND post_id = #{postId})")
+    boolean existsByUserIdAndPostId(@Param("userId") Long userId, @Param("postId") Long postId);
+
+    // 插入一条点赞记录
+    @Insert("INSERT INTO post_likes (user_id, post_id) VALUES (#{userId}, #{postId})")
+    void insert(PostLike postLike);
+
+    // 删除用户对帖子的点赞记录
+    @Delete("DELETE FROM post_likes WHERE user_id = #{userId} AND post_id = #{postId}")
+    void deleteLikeByUserIdAndPostId(@Param("userId") Long userId, @Param("postId") Long postId);
+
+    // 获取某个帖子点赞数
+    @Select("SELECT COUNT(*) FROM post_likes WHERE post_id = #{postId}")
+    Long selectCount(@Param("postId") Long postId);
 }
diff --git a/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
index 37db6af..647095d 100644
--- a/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
+++ b/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
@@ -3,6 +3,7 @@
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.example.g8backend.entity.Post;
+import com.example.g8backend.entity.PostLike;
 import com.example.g8backend.entity.PostTag;
 import com.example.g8backend.mapper.PostMapper;
 import com.example.g8backend.service.IPostService;
@@ -59,21 +60,29 @@
     }
 
     @Override
-    public Long getPostLikeCount(Long postId) {
-        // TODO: 需要实现post_likes表的查询
-        return 0L;
-    }
-
-    @Override
     public void likePost(Long userId, Long postId) {
-        // TODO: 需要实现post_likes表的插入
+        // 检查用户是否已经点赞该帖子
+        boolean exists = postMapper.existsByUserIdAndPostId(userId, postId);
+        if (!exists) {
+            // 如果没有点赞,则执行插入操作
+            PostLike postLike = new PostLike(userId, postId);
+            postMapper.insert(postLike);  // 执行插入点赞记录
+        }
     }
 
+    // 取消点赞功能
     @Override
     public void unlikePost(Long userId, Long postId) {
-        // TODO: 需要实现post_likes表的删除
+        // 删除用户对帖子的点赞记录
+        postMapper.deleteLikeByUserIdAndPostId(userId, postId);  // 使用新的方法删除记录
     }
 
+    // 获取帖子点赞数
+    @Override
+    public Long getPostLikeCount(Long postId) {
+        // 使用 postMapper 直接查询点赞数(调用数据库中的 SQL 查询)
+        return postMapper.selectCount(postId);
+    }
     @Override
     public List<Post> searchPosts(String keyword, List<Long> tagIds, String author) {
         return postMapper.searchPosts(keyword, tagIds, author); // 调用mapper的搜索方法
diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql
index 3c9ff93..355602c 100644
--- a/src/main/resources/schema.sql
+++ b/src/main/resources/schema.sql
@@ -97,3 +97,12 @@
     FOREIGN KEY (user_id) REFERENCES users(user_id), -- 关联用户
     FOREIGN KEY (parent_comment_id) REFERENCES comments(comment_id) -- 关联父评论
 );
+
+CREATE TABLE post_likes (
+    user_id BIGINT NOT NULL,
+    post_id BIGINT NOT NULL,
+    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    PRIMARY KEY (user_id, post_id),
+    CONSTRAINT fk_post FOREIGN KEY (post_id) REFERENCES posts(post_id),
+    CONSTRAINT fk_user FOREIGN KEY (user_id) REFERENCES users(user_id)
+);
diff --git a/src/test/java/com/example/g8backend/service/PostLikeServiceTest.java b/src/test/java/com/example/g8backend/service/PostLikeServiceTest.java
new file mode 100644
index 0000000..987f672
--- /dev/null
+++ b/src/test/java/com/example/g8backend/service/PostLikeServiceTest.java
@@ -0,0 +1,84 @@
+package com.example.g8backend.service;
+
+import com.example.g8backend.entity.Post;
+import com.example.g8backend.entity.PostLike;
+import com.example.g8backend.mapper.PostMapper;
+import com.example.g8backend.service.impl.PostServiceImpl;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Mockito.*;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class PostLikeServiceTest {
+
+    @InjectMocks
+    private PostServiceImpl postService;
+
+    @Mock
+    private PostMapper postMapper;
+
+    private Post post;
+
+    @BeforeEach
+    void setUp() {
+        MockitoAnnotations.openMocks(this);  // 初始化mock对象
+        post = new Post();
+        post.setPostId(1L);
+        post.setPostTitle("Test Post");
+        post.setPostContent("This is a test post.");
+        post.setUserId(1L);
+    }
+
+    // 测试点赞功能
+    @Test
+    void likePost_ShouldAddLike_WhenNotAlreadyLiked() {
+        Long userId = 1L;
+        Long postId = 1L;
+
+        // 设置返回值,模拟查询用户是否已点赞
+        when(postMapper.existsByUserIdAndPostId(userId, postId)).thenReturn(false);
+
+        // 调用点赞方法
+        postService.likePost(userId, postId);
+
+        // 验证postMapper的insert方法被调用一次,表示插入点赞记录
+        verify(postMapper, times(1)).insert(any(PostLike.class));
+    }
+
+    // 测试取消点赞功能
+    @Test
+    void unlikePost_ShouldRemoveLike_WhenAlreadyLiked() {
+        Long userId = 1L;
+        Long postId = 1L;
+
+        // 设置返回值,模拟查询用户是否已点赞
+        when(postMapper.existsByUserIdAndPostId(userId, postId)).thenReturn(true);
+
+        // 调用取消点赞方法
+        postService.unlikePost(userId, postId);
+
+        // 验证postMapper的deleteLikeByUserIdAndPostId方法被调用一次,表示删除点赞记录
+        verify(postMapper, times(1)).deleteLikeByUserIdAndPostId(userId, postId);
+    }
+
+    // 测试获取帖子点赞数功能
+    @Test
+    void getPostLikeCount_ShouldReturnCorrectCount() {
+        Long postId = 1L;
+        Long expectedCount = 10L;
+
+        // 模拟查询返回点赞数
+        when(postMapper.selectCount(postId)).thenReturn(expectedCount);
+
+        // 调用获取点赞数方法
+        Long actualCount = postService.getPostLikeCount(postId);
+
+        // 验证返回的点赞数是否正确
+        assertEquals(expectedCount, actualCount);
+    }
+}