bug_fix+historyview
Change-Id: I6f446c1b660a4322865cfcf5502c88cb772ca0a1
diff --git a/src/main/java/com/example/g8backend/controller/PostController.java b/src/main/java/com/example/g8backend/controller/PostController.java
index a47734a..51aa519 100644
--- a/src/main/java/com/example/g8backend/controller/PostController.java
+++ b/src/main/java/com/example/g8backend/controller/PostController.java
@@ -1,6 +1,9 @@
package com.example.g8backend.controller;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.g8backend.dto.PostCreateDTO;
+import com.example.g8backend.entity.PostView;
+import com.example.g8backend.mapper.PostViewMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
@@ -16,6 +19,8 @@
public class PostController {
@Autowired
private IPostService postService;
+ @Autowired // ✅ 新增注入
+ private PostViewMapper postViewMapper;
@PostMapping("")
public ResponseEntity<?> createPost(@RequestBody PostCreateDTO postCreateDTO) {
@@ -34,7 +39,15 @@
}
@GetMapping("/{postId}")
- public Post getPost(@PathVariable("postId") Long postId) {
+ public Post getPost(@PathVariable Long postId) {
+ // 获取当前用户ID
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ long userId = (long) authentication.getPrincipal();
+
+ // 记录浏览行为
+ postService.recordViewHistory(userId, postId);
+
+ // 返回帖子详情
return postService.getById(postId);
}
@@ -119,4 +132,20 @@
return postService.searchPosts(keyword, tags, author);
}
+
+ @GetMapping("/history")
+ public ResponseEntity<List<PostView>> getViewHistory() {
+ // 获取当前用户ID
+ Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ long userId = (long) authentication.getPrincipal();
+
+ // 查询历史记录(按时间倒序)
+ List<PostView> history = postViewMapper.selectList(
+ new QueryWrapper<PostView>()
+ .eq("user_id", userId)
+ .orderByDesc("view_time")
+ );
+
+ return ResponseEntity.ok(history);
+ }
}
diff --git a/src/main/java/com/example/g8backend/entity/Post.java b/src/main/java/com/example/g8backend/entity/Post.java
index ac7ff20..1a3cd25 100644
--- a/src/main/java/com/example/g8backend/entity/Post.java
+++ b/src/main/java/com/example/g8backend/entity/Post.java
@@ -1,6 +1,7 @@
package com.example.g8backend.entity;
import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
@@ -19,6 +20,10 @@
private Timestamp createdAt;
private String postType;
+ @TableField("view_count")
+ private Integer viewCount = 0;
+
+
@Override
public String toString() {
return "Post{" +
@@ -28,6 +33,7 @@
", postContent='" + postContent + '\'' +
", createdAt=" + createdAt +
", postType='" + postType + '\'' +
+ ", viewCount=" + viewCount + // ✅ 更新 toString 方法
'}';
}
}
diff --git a/src/main/java/com/example/g8backend/entity/PostView.java b/src/main/java/com/example/g8backend/entity/PostView.java
new file mode 100644
index 0000000..72de7ca
--- /dev/null
+++ b/src/main/java/com/example/g8backend/entity/PostView.java
@@ -0,0 +1,20 @@
+package com.example.g8backend.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.IdType;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.time.LocalDateTime;
+
+@Data
+@Accessors(chain = true)
+@TableName("post_views") // 指定数据库表名
+public class PostView {
+ @TableId(value = "view_id", type = IdType.AUTO) // 主键映射为 view_id,自增
+ private Long viewId;
+ private Long userId; // 对应 user_id 字段(自动驼峰转下划线)
+ private Long postId; // 对应 post_id 字段(自动驼峰转下划线)
+ private LocalDateTime viewTime; // 对应 view_time 字段
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/g8backend/mapper/PostMapper.java b/src/main/java/com/example/g8backend/mapper/PostMapper.java
index 8f7e029..d49125e 100644
--- a/src/main/java/com/example/g8backend/mapper/PostMapper.java
+++ b/src/main/java/com/example/g8backend/mapper/PostMapper.java
@@ -4,11 +4,7 @@
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 org.apache.ibatis.annotations.*;
import java.util.List;
@@ -55,4 +51,7 @@
// 获取某个帖子点赞数
@Select("SELECT COUNT(*) FROM post_likes WHERE post_id = #{postId}")
Long selectCount(@Param("postId") Long postId);
+
+ @Update("UPDATE posts SET view_count = view_count + 1 WHERE post_id = #{postId}")
+ void incrementViewCount(Long postId);
}
diff --git a/src/main/java/com/example/g8backend/mapper/PostViewMapper.java b/src/main/java/com/example/g8backend/mapper/PostViewMapper.java
new file mode 100644
index 0000000..7423418
--- /dev/null
+++ b/src/main/java/com/example/g8backend/mapper/PostViewMapper.java
@@ -0,0 +1,21 @@
+package com.example.g8backend.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.example.g8backend.entity.PostView;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+@Mapper
+public interface PostViewMapper extends BaseMapper<PostView> {
+
+
+ @Select("SELECT post_id FROM post_views WHERE user_id = #{userId}")
+ List<Long> findViewedPostIds(@Param("userId") Long userId);
+
+
+ @Select("SELECT * FROM post_views WHERE user_id = #{userId} ORDER BY view_time DESC LIMIT #{limit}")
+ List<PostView> selectRecentViews(@Param("userId") Long userId, @Param("limit") int limit);
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/g8backend/service/IPostService.java b/src/main/java/com/example/g8backend/service/IPostService.java
index 82c792e..a349b59 100644
--- a/src/main/java/com/example/g8backend/service/IPostService.java
+++ b/src/main/java/com/example/g8backend/service/IPostService.java
@@ -2,6 +2,7 @@
import com.example.g8backend.entity.Post;
import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@@ -16,4 +17,7 @@
void unlikePost(Long userId, Long postId);
List<Post> searchPosts(String keyword, List<Long> tagIds, String author); // 更新为支持多个标签
+
+ @Transactional
+ void recordViewHistory(Long userId, 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 647095d..f2bef5f 100644
--- a/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
+++ b/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
@@ -5,11 +5,15 @@
import com.example.g8backend.entity.Post;
import com.example.g8backend.entity.PostLike;
import com.example.g8backend.entity.PostTag;
+import com.example.g8backend.entity.PostView;
import com.example.g8backend.mapper.PostMapper;
+import com.example.g8backend.mapper.PostViewMapper;
import com.example.g8backend.service.IPostService;
import com.example.g8backend.service.IPostTagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
import java.sql.Timestamp;
import java.util.List;
@@ -18,11 +22,14 @@
private final PostMapper postMapper;
+ private final PostViewMapper postViewMapper;
+
@Autowired
private IPostTagService postTagService;
- public PostServiceImpl(PostMapper postMapper) {
+ public PostServiceImpl(PostMapper postMapper, PostViewMapper postViewMapper) {
this.postMapper = postMapper;
+ this.postViewMapper = postViewMapper;
this.baseMapper = postMapper; // 重要:设置 baseMapper
}
@@ -87,4 +94,20 @@
public List<Post> searchPosts(String keyword, List<Long> tagIds, String author) {
return postMapper.searchPosts(keyword, tagIds, author); // 调用mapper的搜索方法
}
+
+
+ @Override
+ @Transactional
+ public void recordViewHistory(Long userId, Long postId) {
+ // 1. 插入浏览记录
+ PostView view = new PostView()
+ .setUserId(userId)
+ .setPostId(postId)
+ .setViewTime(new Timestamp(System.currentTimeMillis()).toLocalDateTime());
+ postViewMapper.insert(view);
+
+ // 2. 原子更新浏览数
+ postMapper.incrementViewCount(postId); // 直接调用原子操作
+ }
+
}
\ No newline at end of file