debug

Change-Id: I5c4de18f786f8cc336d8ad66ae9b424d02ed3674
diff --git a/src/main/java/com/example/g8backend/service/IPostService.java b/src/main/java/com/example/g8backend/service/IPostService.java
index ca5376b..855952e 100644
--- a/src/main/java/com/example/g8backend/service/IPostService.java
+++ b/src/main/java/com/example/g8backend/service/IPostService.java
@@ -28,4 +28,6 @@
     void calculateHotScores();
 
     Page<Post> getRecommendedPosts(int page, int size, Long userId);
+
+    Page<Post> getRecommendedByTags(int page, int size, Long userId);
 }
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 ae47d8a..5faa4ac 100644
--- a/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
+++ b/src/main/java/com/example/g8backend/service/impl/PostServiceImpl.java
@@ -1,57 +1,47 @@
 package com.example.g8backend.service.impl;
-
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 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.entity.PostView;
-import com.example.g8backend.mapper.CommentMapper;
-import com.example.g8backend.mapper.PostMapper;
-import com.example.g8backend.mapper.PostViewMapper;
+import com.example.g8backend.entity.*;
+import com.example.g8backend.mapper.*;
 import com.example.g8backend.service.IPostService;
 import com.example.g8backend.service.IPostTagService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
-
 import java.sql.Timestamp;
 import java.time.Instant;
 import java.time.temporal.ChronoUnit;
 import java.util.List;
-
+import java.util.stream.Collectors;
 @Service
 public class PostServiceImpl extends ServiceImpl<PostMapper, Post> implements IPostService {
-
     private final PostMapper postMapper;
-
     private final PostViewMapper postViewMapper;
-
     private final CommentMapper commentMapper;
-
+    private final UserTagPreferenceMapper userTagPreferenceMapper;
+    private final PostTagMapper postTagMapper;
     @Autowired
     private IPostTagService postTagService;
-
-    public PostServiceImpl(PostMapper postMapper, PostViewMapper postViewMapper, CommentMapper commentMapper) {
+    public PostServiceImpl(PostMapper postMapper, PostViewMapper postViewMapper, CommentMapper commentMapper,
+                           UserTagPreferenceMapper userTagPreferenceMapper, PostTagMapper postTagMapper) {
         this.postMapper = postMapper;
         this.postViewMapper = postViewMapper;
         this.commentMapper = commentMapper;
+        this.userTagPreferenceMapper = userTagPreferenceMapper;
+        this.postTagMapper = postTagMapper;
         this.baseMapper = postMapper; // 重要:设置 baseMapper
     }
-
     @Override
     public List<Post> getPostsByUserId(Long userId) {
         return postMapper.getPostsByUserId(userId);
     }
-
     public void createPost(Post post) {
         post.setHotScore(5.0); // 初始热度
         post.setCreatedAt(new Timestamp(System.currentTimeMillis()));
         save(post);
     }
-
     @Override
     public void createPost(Post post, Long[] tagIds) {
         post.setHotScore(5.0); // 初始热度
@@ -61,20 +51,17 @@
             postTagService.save(new PostTag(post.getPostId(), tagId));
         }
     }
-
     @Override
     public Post updatePost(Post post) {
         updateById(post);
         return getById(post.getPostId());
     }
-
     @Override
     public List<Post> getPostsByType(String postType) {
         QueryWrapper<Post> wrapper = new QueryWrapper<>();
         wrapper.eq("post_type", postType);
         return list(wrapper);
     }
-
     @Override
     public void likePost(Long userId, Long postId) {
         // 检查用户是否已经点赞该帖子
@@ -85,14 +72,12 @@
             postMapper.insert(postLike);  // 执行插入点赞记录
         }
     }
-
     // 取消点赞功能
     @Override
     public void unlikePost(Long userId, Long postId) {
         // 删除用户对帖子的点赞记录
         postMapper.deleteLikeByUserIdAndPostId(userId, postId);  // 使用新的方法删除记录
     }
-
     // 获取帖子点赞数
     @Override
     public Long getPostLikeCount(Long postId) {
@@ -103,8 +88,6 @@
     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) {
@@ -114,11 +97,11 @@
                 .setPostId(postId)
                 .setViewTime(new Timestamp(System.currentTimeMillis()).toLocalDateTime());
         postViewMapper.insert(view);
-
         // 2. 原子更新浏览数
         postMapper.incrementViewCount(postId); // 直接调用原子操作
+        // 3. 新增:更新用户标签偏好
+        updateUserTagPreference(userId, postId);
     }
-
     @Override
     @Scheduled(cron = "0 */10 * * * *") // 每10分钟执行一次
     @Transactional
@@ -126,7 +109,6 @@
         // 1. 获取所有帖子
         List<Post> posts = postMapper.selectList(new QueryWrapper<>());
         Instant now = Instant.now();
-
         // 2. 计算每个帖子的热度
         posts.forEach(post -> {
             // 计算时间衰减因子(以小时为单位)
@@ -134,40 +116,65 @@
                     post.getCreatedAt().toInstant(),
                     now
             );
-
             // 获取互动数据(点赞数、评论数)
             Long likeCount = postMapper.selectLikeCount(post.getPostId());
             Long commentCount = commentMapper.selectCountByPostId(post.getPostId());
-
             // 热度计算公式
             double hotScore = (
                     Math.log(post.getViewCount() + 1) * 0.2 +
                             likeCount * 0.5 +
                             commentCount * 0.3
             ) / Math.pow(hoursSinceCreation + 2, 1.5);
-
             post.setHotScore(hotScore);
             post.setLastCalculated(new Timestamp(System.currentTimeMillis()));
         });
-
         // 3. 批量更新热度(自定义SQL实现)
         postMapper.batchUpdateHotScore(posts);
     }
-
     @Override
     public Page<Post> getRecommendedPosts(int page, int size, Long userId) {
         // 1. 获取用户已浏览的帖子ID列表
         List<Long> viewedPostIds = postViewMapper.findViewedPostIds(userId);
-
         // 2. 构建查询条件:排除已浏览帖子,按热度降序
         QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
         if (!viewedPostIds.isEmpty()) {
             queryWrapper.notIn("post_id", viewedPostIds);
         }
         queryWrapper.orderByDesc("hot_score");
-
         // 3. 分页查询
         return postMapper.selectPage(new Page<>(page, size), queryWrapper);
     }
-
+    private void updateUserTagPreference(Long userId, Long postId) {
+        // 获取帖子关联的标签ID列表
+        List<Long> tagIds = postTagMapper.findTagIdsByPostId(postId);
+        // 对每个标签增加权重(示例:每次浏览 +0.1)
+        tagIds.forEach(tagId -> {
+            userTagPreferenceMapper.insertOrUpdateWeight(
+                    userId,
+                    tagId,
+                    0.1 // 权重增量
+            );
+        });
+    }
+    @Override
+    public Page<Post> getRecommendedByTags(int page, int size, Long userId) {
+        // 获取用户偏好标签
+        List<UserTagPreference> preferences = userTagPreferenceMapper.selectByUserId(userId);
+        if (preferences.isEmpty()) {
+            return new Page<>(page, size);
+        }
+        // 获取标签关联的帖子ID
+        List<Long> tagIds = preferences.stream()
+                .map(UserTagPreference::getTagId)
+                .collect(Collectors.toList());
+        List<Long> postIds = postTagMapper.findPostIdsByTagIds(tagIds);
+        if (postIds.isEmpty()) {
+            return new Page<>(page, size);
+        }
+        // 构建查询条件
+        QueryWrapper<Post> queryWrapper = new QueryWrapper<>();
+        queryWrapper.in("post_id", postIds) // 确保正确添加 IN 条件
+                .orderByDesc("hot_score"); // 确保排序条件正确
+        return postMapper.selectPage(new Page<>(page, size), queryWrapper);
+    }
 }
\ No newline at end of file