2 次代码提交 d2dfb123d5 ... 901547c59e

作者 SHA1 备注 提交日期
  李思佳 901547c59e Merge remote-tracking branch 'origin/test_dev' into test_dev 4 天之前
  李思佳 56379d8235 feat(user): 添加用户浏览记录功能 4 天之前

+ 80 - 5
LiangZhiYUMao/pages/mine/visited-by-me.vue

@@ -16,8 +16,13 @@
     </view>
     
     <!-- 浏览记录列表 -->
-    <scroll-view class="history-list" scroll-y="true">
-      <view class="history-item" v-for="item in browseHistory" :key="item.id" @click="goUserDetail(item.userId)">
+    <scroll-view 
+      class="history-list" 
+      scroll-y="true" 
+      @scrolltolower="loadMore"
+      lower-threshold="50"
+    >
+      <view class="history-item" v-for="item in browseHistory" :key="item.userId" @click="goUserDetail(item.userId)">
         <image class="user-avatar" :src="item.avatar" mode="aspectFill"></image>
         <view class="user-info">
           <view class="user-basic">
@@ -38,6 +43,14 @@
           <text class="browse-icon">👁️</text>
         </view>
       </view>
+      
+      <!-- 加载更多提示 -->
+      <view class="load-more" v-if="hasMore && !loading">
+        <text class="load-more-text">上拉加载更多</text>
+      </view>
+      <view class="load-more" v-if="!hasMore && browseHistory.length > 0">
+        <text class="load-more-text">没有更多数据了</text>
+      </view>
     </scroll-view>
   </view>
 </template>
@@ -58,13 +71,57 @@ export default {
   onLoad() {
     this.loadBrowseHistory()
   },
+  
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.loadBrowseHistory(true)
+  },
   methods: {
     // 加载浏览记录
-    async loadBrowseHistory() {
+    async loadBrowseHistory(isRefresh = false) {
       try {
         this.loading = true
-        // 不调用真实API,显示空数据
-        this.browseHistory = []
+        
+        // 从本地存储获取当前用户ID
+        const userInfo = uni.getStorageSync('userInfo')
+        if (!userInfo || !userInfo.userId) {
+          uni.showToast({
+            title: '请先登录',
+            icon: 'none'
+          })
+          return
+        }
+        
+        // 如果是刷新,则重置页码
+        if (isRefresh) {
+          this.pageNum = 1
+          this.hasMore = true
+        }
+        
+        // 如果没有更多数据,则直接返回
+        if (!this.hasMore) {
+          return
+        }
+        
+        // 调用API获取浏览记录
+        const response = await api.user.getBrowseHistory(userInfo.userId, this.pageNum, this.pageSize)
+        
+        // 处理返回数据
+        if (isRefresh) {
+          // 刷新:替换原有数据
+          this.browseHistory = response.records || []
+        } else {
+          // 加载更多:追加数据
+          this.browseHistory = this.browseHistory.concat(response.records || [])
+        }
+        
+        // 判断是否还有更多数据
+        this.hasMore = this.browseHistory.length < response.total
+        
+        // 如果还有更多数据,则页码加1
+        if (this.hasMore) {
+          this.pageNum++
+        }
       } catch (error) {
         console.error('加载浏览记录失败:', error)
         uni.showToast({
@@ -73,6 +130,10 @@ export default {
         })
       } finally {
         this.loading = false
+        // 停止下拉刷新
+        if (isRefresh) {
+          uni.stopPullDownRefresh()
+        }
       }
     },
     
@@ -118,6 +179,13 @@ export default {
       uni.navigateTo({
         url: '/pages/recommend/index'
       })
+    },
+    
+    // 上拉加载更多
+    loadMore() {
+      if (!this.loading && this.hasMore) {
+        this.loadBrowseHistory()
+      }
     }
   }
 }
@@ -189,6 +257,13 @@ export default {
   height: calc(100vh - 88rpx);
 }
 
+.load-more {
+  text-align: center;
+  padding: 30rpx 0;
+  color: #999;
+  font-size: 24rpx;
+}
+
 .history-item {
   display: flex;
   align-items: center;

+ 19 - 2
LiangZhiYUMao/utils/api.js

@@ -117,8 +117,8 @@ export default {
     getInfo: () => request({ url: '/user/info' }),
 
     // 获取指定用户的详细信息(包含简介和照片)
-    getDetailInfo: (userId) => request({
-      url: `/user/info?userId=${userId}`
+    getDetailInfo: (userId, currentUserId) => request({
+      url: `/user/info?userId=${userId}${currentUserId ? `&currentUserId=${currentUserId}` : ''}`
     }),
 
     // 查询用户是否为红娘
@@ -140,6 +140,23 @@ export default {
     updateField: (userId, fieldName, fieldValue) => request({
       url: `/user/basic/field?userId=${userId}&fieldName=${fieldName}&fieldValue=${encodeURIComponent(fieldValue)}`,
       method: 'PUT'
+    }),
+    
+    // 获取用户的浏览记录列表
+    getBrowseHistory: (userId, pageNum = 1, pageSize = 20) => request({
+      url: `/user/browse-history?userId=${userId}&pageNum=${pageNum}&pageSize=${pageSize}`
+    }),
+    
+    // 清空用户的所有浏览记录
+    clearBrowseHistory: (userId) => request({
+      url: `/user/browse-history?userId=${userId}`,
+      method: 'DELETE'
+    }),
+    
+    // 删除用户对某个特定用户的浏览记录
+    deleteBrowseHistory: (userId, visitedUserId) => request({
+      url: `/user/browse-history/one?userId=${userId}&visitedUserId=${visitedUserId}`,
+      method: 'DELETE'
     })
   },
 

+ 124 - 1
service/Essential/src/main/java/com/zhentao/controller/UserController.java

@@ -1,7 +1,9 @@
 package com.zhentao.controller;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.zhentao.common.Result;
 import com.zhentao.entity.User;
+import com.zhentao.service.UserBrowseUserService;
 import com.zhentao.service.UserService;
 import com.zhentao.vo.UserInfoVO;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,15 +19,21 @@ public class UserController {
     @Autowired
     private UserService userService;
     
+    @Autowired
+    private UserBrowseUserService userBrowseUserService;
+    
     /**
      * 获取用户信息
      * @param userId 用户ID(必传)
+     * @param currentUserId 当前登录用户ID(可选,用于添加浏览记录)
      * @return 用户信息
      */
     @GetMapping("/info")
-    public Result<UserInfoVO> getUserInfo(@RequestParam Long userId) {
+    public Result<UserInfoVO> getUserInfo(@RequestParam Long userId, 
+                                         @RequestParam(required = false) Long currentUserId) {
         System.out.println("=== UserController.getUserInfo 接收请求 ===");
         System.out.println("接收到的用户ID: " + userId + " (类型: " + userId.getClass().getSimpleName() + ")");
+        System.out.println("当前登录用户ID: " + currentUserId);
         
         try {
             // 验证用户ID
@@ -39,6 +47,25 @@ public class UserController {
             
             if (vo != null) {
                 System.out.println("✅ 查询成功,用户: " + vo.getNickname() + " (ID: " + vo.getUserId() + ")");
+                
+                // 如果当前有登录用户,且不是查看自己的信息,则添加浏览记录
+                if (currentUserId != null && currentUserId > 0 && !currentUserId.equals(userId)) {
+                    System.out.println("📝 添加浏览记录: " + currentUserId + " -> " + userId);
+                    
+                    // 异步添加浏览记录,不影响主流程
+                    new Thread(() -> {
+                        try {
+                            // 转换为Integer类型
+                            Integer visitorId = currentUserId.intValue();
+                            Integer visitedUserId = userId.intValue();
+                            userBrowseUserService.addBrowseHistory(visitorId, visitedUserId);
+                            System.out.println("✅ 浏览记录添加成功: " + visitorId + " -> " + visitedUserId);
+                        } catch (Exception e) {
+                            System.err.println("❌ 浏览记录添加失败: " + e.getMessage());
+                            e.printStackTrace();
+                        }
+                    }).start();
+                }
             } else {
                 System.out.println("❌ 查询结果为null");
             }
@@ -55,6 +82,102 @@ public class UserController {
         }
     }
     
+    /**
+     * 获取用户的浏览记录列表
+     * @param userId 用户ID(必传)
+     * @param pageNum 页码(可选,默认1)
+     * @param pageSize 每页条数(可选,默认20)
+     * @return 浏览记录分页列表
+     */
+    @GetMapping("/browse-history")
+    public Result<Page<UserInfoVO>> getBrowseHistory(@RequestParam Long userId, 
+                                                   @RequestParam(required = false, defaultValue = "1") Integer pageNum, 
+                                                   @RequestParam(required = false, defaultValue = "20") Integer pageSize) {
+        System.out.println("=== UserController.getBrowseHistory 接收请求 ===");
+        System.out.println("用户ID: " + userId + ", 页码: " + pageNum + ", 每页条数: " + pageSize);
+        
+        try {
+            // 验证用户ID
+            if (userId == null || userId <= 0) {
+                System.out.println("❌ 用户ID无效: " + userId);
+                return Result.error("用户ID无效");
+            }
+            
+            // 转换为Integer类型
+            Integer visitorId = userId.intValue();
+            Page<UserInfoVO> page = userBrowseUserService.getBrowseHistory(visitorId, pageNum, pageSize);
+            System.out.println("✅ 浏览记录查询成功,共" + page.getTotal() + "条记录");
+            
+            return Result.success(page);
+        } catch (Exception e) {
+            System.err.println("❌ 浏览记录查询失败: " + e.getMessage());
+            e.printStackTrace();
+            return Result.error("获取浏览记录失败: " + e.getMessage());
+        }
+    }
+    
+    /**
+     * 清空用户的所有浏览记录
+     * @param userId 用户ID(必传)
+     * @return 操作结果
+     */
+    @DeleteMapping("/browse-history")
+    public Result<String> clearBrowseHistory(@RequestParam Long userId) {
+        System.out.println("=== UserController.clearBrowseHistory 接收请求 ===");
+        System.out.println("用户ID: " + userId);
+        
+        try {
+            // 验证用户ID
+            if (userId == null || userId <= 0) {
+                System.out.println("❌ 用户ID无效: " + userId);
+                return Result.error("用户ID无效");
+            }
+            
+            // 转换为Integer类型
+            Integer visitorId = userId.intValue();
+            userBrowseUserService.clearBrowseHistory(visitorId);
+            System.out.println("✅ 浏览记录清空成功");
+            
+            return Result.success("浏览记录清空成功");
+        } catch (Exception e) {
+            System.err.println("❌ 浏览记录清空失败: " + e.getMessage());
+            e.printStackTrace();
+            return Result.error("清空浏览记录失败: " + e.getMessage());
+        }
+    }
+    
+    /**
+     * 删除用户对某个特定用户的浏览记录
+     * @param userId 用户ID(必传)
+     * @param visitedUserId 被浏览者ID(必传)
+     * @return 操作结果
+     */
+    @DeleteMapping("/browse-history/one")
+    public Result<String> deleteBrowseHistory(@RequestParam Long userId, @RequestParam Long visitedUserId) {
+        System.out.println("=== UserController.deleteBrowseHistory 接收请求 ===");
+        System.out.println("用户ID: " + userId + ", 被浏览者ID: " + visitedUserId);
+        
+        try {
+            // 验证用户ID
+            if (userId == null || userId <= 0 || visitedUserId == null || visitedUserId <= 0) {
+                System.out.println("❌ 用户ID或被浏览者ID无效");
+                return Result.error("用户ID或被浏览者ID无效");
+            }
+            
+            // 转换为Integer类型
+            Integer visitorId = userId.intValue();
+            Integer lookUserId = visitedUserId.intValue();
+            userBrowseUserService.deleteBrowseHistory(visitorId, lookUserId);
+            System.out.println("✅ 浏览记录删除成功");
+            
+            return Result.success("浏览记录删除成功");
+        } catch (Exception e) {
+            System.err.println("❌ 浏览记录删除失败: " + e.getMessage());
+            e.printStackTrace();
+            return Result.error("删除浏览记录失败: " + e.getMessage());
+        }
+    }
+    
     /**
      * 查询用户是否为红娘
      * @param userId 用户ID

+ 50 - 0
service/Essential/src/main/java/com/zhentao/entity/UserBrowseUser.java

@@ -0,0 +1,50 @@
+package com.zhentao.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户浏览用户记录实体类
+ */
+@Data
+@TableName("user_look")
+public class UserBrowseUser implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 用户ID(浏览者)
+     */
+    @TableField("user_id")
+    private Integer userId;
+
+    /**
+     * 用户浏览的用户ID(被浏览者)
+     */
+    @TableField("look_user_id")
+    private Integer lookUserId;
+
+    /**
+     * 创建时间
+     */
+    @TableField(value = "create_time", fill = FieldFill.INSERT)
+    private Date createTime;
+
+    /**
+     * 更新时间
+     */
+    @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
+    private Date updateTime;
+}

+ 35 - 0
service/Essential/src/main/java/com/zhentao/mapper/UserBrowseUserMapper.java

@@ -0,0 +1,35 @@
+package com.zhentao.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.zhentao.entity.UserBrowseUser;
+import com.zhentao.vo.UserInfoVO;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * 用户浏览用户记录Mapper
+ */
+public interface UserBrowseUserMapper extends BaseMapper<UserBrowseUser> {
+    
+    /**
+     * 按浏览时间倒序获取用户的浏览记录,包含被浏览用户的基本信息
+     */
+    Page<UserInfoVO> getBrowseHistory(@Param("page") Page<UserInfoVO> page, @Param("visitorId") Long visitorId);
+    
+    /**
+     * 删除用户的所有浏览记录
+     */
+    int deleteByVisitorId(@Param("visitorId") Long visitorId);
+    
+    /**
+     * 删除用户对某个特定用户的浏览记录
+     */
+    int deleteByVisitorAndVisited(@Param("visitorId") Long visitorId, @Param("visitedUserId") Long visitedUserId);
+    
+    /**
+     * 获取用户最近一次浏览某个特定用户的记录
+     */
+    UserBrowseUser getLatestByVisitorAndVisited(@Param("visitorId") Long visitorId, @Param("visitedUserId") Long visitedUserId);
+}

+ 45 - 0
service/Essential/src/main/java/com/zhentao/service/UserBrowseUserService.java

@@ -0,0 +1,45 @@
+package com.zhentao.service;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.zhentao.entity.UserBrowseUser;
+import com.zhentao.vo.UserInfoVO;
+
+/**
+ * 用户浏览用户记录Service
+ */
+public interface UserBrowseUserService extends IService<UserBrowseUser> {
+    
+    /**
+     * 添加浏览记录
+     * 
+     * @param userId 浏览者ID
+     * @param lookUserId 被浏览者ID
+     */
+    void addBrowseHistory(Integer userId, Integer lookUserId);
+    
+    /**
+     * 获取用户的浏览记录列表
+     * 
+     * @param userId 浏览者ID
+     * @param pageNum 页码
+     * @param pageSize 每页条数
+     * @return 浏览记录分页列表
+     */
+    Page<UserInfoVO> getBrowseHistory(Integer userId, Integer pageNum, Integer pageSize);
+    
+    /**
+     * 清空用户的所有浏览记录
+     * 
+     * @param userId 浏览者ID
+     */
+    void clearBrowseHistory(Integer userId);
+    
+    /**
+     * 删除用户对某个特定用户的浏览记录
+     * 
+     * @param userId 浏览者ID
+     * @param lookUserId 被浏览者ID
+     */
+    void deleteBrowseHistory(Integer userId, Integer lookUserId);
+}

+ 76 - 0
service/Essential/src/main/java/com/zhentao/service/impl/UserBrowseUserServiceImpl.java

@@ -0,0 +1,76 @@
+package com.zhentao.service.impl;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.zhentao.entity.UserBrowseUser;
+import com.zhentao.mapper.UserBrowseUserMapper;
+import com.zhentao.service.UserBrowseUserService;
+import com.zhentao.vo.UserInfoVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.Date;
+
+/**
+ * 用户浏览用户记录Service实现类
+ */
+@Slf4j
+@Service
+public class UserBrowseUserServiceImpl extends ServiceImpl<UserBrowseUserMapper, UserBrowseUser> implements UserBrowseUserService {
+    
+    @Autowired
+    private UserBrowseUserMapper userBrowseUserMapper;
+    
+    /**
+     * 添加浏览记录
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void addBrowseHistory(Integer userId, Integer lookUserId) {
+        // 检查是否已存在浏览记录
+        UserBrowseUser existingRecord = userBrowseUserMapper.getLatestByVisitorAndVisited(userId.longValue(), lookUserId.longValue());
+        
+        if (existingRecord != null) {
+            // 已存在则删除旧记录
+            userBrowseUserMapper.deleteById(existingRecord.getId());
+        }
+        
+        // 创建新的浏览记录
+        UserBrowseUser record = new UserBrowseUser();
+        record.setUserId(userId);
+        record.setLookUserId(lookUserId);
+        
+        // 保存记录(创建时间和更新时间由MyBatis Plus自动填充)
+        this.save(record);
+    }
+    
+    /**
+     * 获取用户的浏览记录列表
+     */
+    @Override
+    public Page<UserInfoVO> getBrowseHistory(Integer userId, Integer pageNum, Integer pageSize) {
+        // 分页查询浏览记录,按浏览时间倒序
+        Page<UserInfoVO> page = new Page<>(pageNum, pageSize);
+        return userBrowseUserMapper.getBrowseHistory(page, userId.longValue());
+    }
+    
+    /**
+     * 清空用户的所有浏览记录
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void clearBrowseHistory(Integer userId) {
+        userBrowseUserMapper.deleteByVisitorId(userId.longValue());
+    }
+    
+    /**
+     * 删除用户对某个特定用户的浏览记录
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteBrowseHistory(Integer userId, Integer lookUserId) {
+        userBrowseUserMapper.deleteByVisitorAndVisited(userId.longValue(), lookUserId.longValue());
+    }
+}

+ 79 - 0
service/Essential/src/main/resources/com/zhentao/mapper/UserBrowseUserMapper.xml

@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.zhentao.mapper.UserBrowseUserMapper">
+    
+    <!-- 按浏览时间倒序获取用户的浏览记录,包含被浏览用户的基本信息 -->
+    <select id="getBrowseHistory" resultType="com.zhentao.vo.UserInfoVO">
+        SELECT 
+            u.id as userId,
+            u.nickname,
+            u.avatar,
+            u.gender,
+            u.age,
+            u.height,
+            u.weight,
+            u.education,
+            u.salary,
+            u.education_text as educationText,
+            u.salary_text as salaryText,
+            u.birth_date as birthDate,
+            u.constellation,
+            u.zodiac,
+            u.mbti,
+            u.province,
+            u.city,
+            u.area,
+            u.position,
+            u.company,
+            u.marital_status as maritalStatus,
+            u.have_children as haveChildren,
+            u.religion,
+            u.smoke,
+            u.drink,
+            u.work_industry as workIndustry,
+            u.work_status as workStatus,
+            u.housing_condition as housingCondition,
+            u.car_condition as carCondition,
+            u.self_introduction as selfIntroduction,
+            u.life_style as lifeStyle,
+            u.family_background as familyBackground,
+            u.ideal_partner as idealPartner,
+            u.is_vip as isVip,
+            u.vip_expire_time as vipExpireTime,
+            u.status,
+            u.create_time as createTime,
+            u.update_time as updateTime,
+            ul.create_time as viewTime
+        FROM 
+            user_look ul
+        LEFT JOIN 
+            users u ON ul.look_user_id = u.id
+        WHERE 
+            ul.user_id = #{visitorId}
+        ORDER BY 
+            ul.create_time DESC
+    </select>
+    
+    <!-- 删除用户的所有浏览记录 -->
+    <delete id="deleteByVisitorId">
+        DELETE FROM user_look WHERE user_id = #{visitorId}
+    </delete>
+    
+    <!-- 删除用户对某个特定用户的浏览记录 -->
+    <delete id="deleteByVisitorAndVisited">
+        DELETE FROM user_look WHERE user_id = #{visitorId} AND look_user_id = #{visitedUserId}
+    </delete>
+    
+    <!-- 获取用户最近一次浏览某个特定用户的记录 -->
+    <select id="getLatestByVisitorAndVisited" resultType="com.zhentao.entity.UserBrowseUser">
+        SELECT 
+            *
+        FROM 
+            user_look
+        WHERE 
+            user_id = #{visitorId} AND look_user_id = #{visitedUserId}
+        ORDER BY 
+            create_time DESC
+        LIMIT 1
+    </select>
+</mapper>