3 Commits e7e641dcdc ... 6296dc7d9f

Auteur SHA1 Message Date
  yuxy 6296dc7d9f Merge branch 'yxy' into test_dev il y a 5 heures
  yuxy ef9e1e67b2 匹配功能和页面优化 il y a 5 heures
  yuxy 629cdbb6dd 匹配功能和页面优化 il y a 5 heures

+ 5 - 4
LiangZhiYUMao/pages/match/index.vue

@@ -522,6 +522,7 @@ export default {
 	min-height: 100vh;
 	background: linear-gradient(180deg, #FFF5F7 0%, #FFFFFF 100%);
 	padding: 0;
+	padding-top: calc(env(safe-area-inset-top) + 40rpx);
 }
 
 /* 自定义导航栏 */
@@ -533,9 +534,9 @@ export default {
 	justify-content: space-between;
 	padding: 0 20rpx;
 	box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
-	position: sticky;
-	top: 0;
+	position: relative;
 	z-index: 999;
+	margin-bottom: 10rpx;
 }
 
 .navbar-back {
@@ -578,7 +579,7 @@ export default {
 	background: linear-gradient(135deg, #E3F2FD 0%, #F3E5F5 100%);
 	border-left: 6rpx solid #2196F3;
 	padding: 28rpx 24rpx;
-	margin: 24rpx 20rpx;
+	margin: 10rpx 20rpx 24rpx 20rpx;
 	border-radius: 16rpx;
 	display: flex;
 	align-items: center;
@@ -704,7 +705,7 @@ export default {
 
 .match-button-container {
 	position: fixed;
-	bottom: 80rpx;
+	bottom: calc(env(safe-area-inset-bottom) + 40rpx);
 	left: 30rpx;
 	right: 30rpx;
 	z-index: 100;

+ 84 - 11
service/randomMatch/src/main/java/com/zhentao/service/MatchService.java

@@ -165,8 +165,15 @@ public class MatchService {
                 return new MatchResult(false, null, 0);
             }
             
+            // 获取已匹配过的用户列表(从Redis)
+            Set<String> matchedHistory = getMatchedHistory(userId);
             Set<String> unmatched = redisMatchPool.getUserUnmatchedSet(userId);
+            
+            // 打乱用户列表,增加随机性
+            Collections.shuffle(allUsers);
+            
             Map<String, Double> scores = new HashMap<>();
+            List<Map.Entry<String, Double>> qualifiedMatches = new ArrayList<>();
             
             for (User user : allUsers) {
                 String otherUserId = String.valueOf(user.getUserId());
@@ -174,6 +181,12 @@ public class MatchService {
                 // 排除自己
                 if (userId.equals(otherUserId)) continue;
                 
+                // 排除已经匹配过的用户(本次会话)
+                if (matchedHistory.contains(otherUserId)) {
+                    log.debug("跳过已匹配过的用户: {}", otherUserId);
+                    continue;
+                }
+                
                 // 排除已经不匹配的用户
                 if (unmatched.contains(otherUserId)) continue;
                 
@@ -190,28 +203,56 @@ public class MatchService {
                 double score = MatchingAlgorithmUtils.calculateMatchScore(userData, otherData);
                 scores.put(otherUserId, score);
                 
-                // 如果分数达到阈值,立即返回匹配成功
+                // 收集达到阈值的匹配
                 if (score >= threshold) {
-                    log.info("从数据库匹配成功: userId={}, matchedUserId={}, score={}", userId, otherUserId, score);
-                    return new MatchResult(true, otherUserId, score);
+                    qualifiedMatches.add(new AbstractMap.SimpleEntry<>(otherUserId, score));
                 }
             }
             
-            // 如果没有达到阈值的,返回分数最高的
+            // 如果有达到阈值的匹配,随机选择一个
+            if (!qualifiedMatches.isEmpty()) {
+                // 按分数排序,取前3个(如果有的话)
+                qualifiedMatches.sort((a, b) -> Double.compare(b.getValue(), a.getValue()));
+                List<Map.Entry<String, Double>> topMatches = qualifiedMatches.subList(0, Math.min(3, qualifiedMatches.size()));
+                
+                // 从前3个中随机选择一个
+                Map.Entry<String, Double> selected = topMatches.get(new Random().nextInt(topMatches.size()));
+                
+                // 记录匹配历史
+                addToMatchedHistory(userId, selected.getKey());
+                
+                log.info("从数据库匹配成功: userId={}, matchedUserId={}, score={}, 候选数={}", 
+                    userId, selected.getKey(), selected.getValue(), qualifiedMatches.size());
+                return new MatchResult(true, selected.getKey(), selected.getValue());
+            }
+            
+            // 如果没有达到阈值的,从所有候选中选择分数最高的几个,随机返回一个
             if (!scores.isEmpty()) {
-                Map.Entry<String, Double> best = scores.entrySet().stream()
-                    .max(Map.Entry.comparingByValue())
-                    .get();
+                List<Map.Entry<String, Double>> sortedScores = new ArrayList<>(scores.entrySet());
+                sortedScores.sort((a, b) -> Double.compare(b.getValue(), a.getValue()));
+                
+                // 取前5个最高分的
+                List<Map.Entry<String, Double>> topScores = sortedScores.subList(0, Math.min(5, sortedScores.size()));
                 
                 // 降低阈值要求,只要分数大于30就可以匹配
-                if (best.getValue() >= 30.0) {
+                List<Map.Entry<String, Double>> acceptableMatches = topScores.stream()
+                    .filter(e -> e.getValue() >= 30.0)
+                    .collect(java.util.stream.Collectors.toList());
+                
+                if (!acceptableMatches.isEmpty()) {
+                    // 随机选择一个
+                    Map.Entry<String, Double> selected = acceptableMatches.get(new Random().nextInt(acceptableMatches.size()));
+                    
+                    // 记录匹配历史
+                    addToMatchedHistory(userId, selected.getKey());
+                    
                     log.info("从数据库匹配成功(降低阈值): userId={}, matchedUserId={}, score={}", 
-                        userId, best.getKey(), best.getValue());
-                    return new MatchResult(true, best.getKey(), best.getValue());
+                        userId, selected.getKey(), selected.getValue());
+                    return new MatchResult(true, selected.getKey(), selected.getValue());
                 }
                 
                 // 记录最佳但未匹配的用户
-                redisMatchPool.recordUnmatch(userId, best.getKey());
+                redisMatchPool.recordUnmatch(userId, sortedScores.get(0).getKey());
             }
             
             log.info("数据库中未找到合适的匹配对象: userId={}", userId);
@@ -223,6 +264,38 @@ public class MatchService {
         }
     }
     
+    /**
+     * 获取用户的匹配历史(本次会话)
+     */
+    private Set<String> getMatchedHistory(String userId) {
+        try {
+            String key = "match:history:" + userId;
+            Set<Object> history = redisTemplate.opsForSet().members(key);
+            if (history != null) {
+                return history.stream()
+                    .map(Object::toString)
+                    .collect(java.util.stream.Collectors.toSet());
+            }
+        } catch (Exception e) {
+            log.warn("获取匹配历史失败: userId={}", userId, e);
+        }
+        return new HashSet<>();
+    }
+    
+    /**
+     * 添加到匹配历史
+     */
+    private void addToMatchedHistory(String userId, String matchedUserId) {
+        try {
+            String key = "match:history:" + userId;
+            redisTemplate.opsForSet().add(key, matchedUserId);
+            // 设置过期时间为1小时
+            redisTemplate.expire(key, 1, TimeUnit.HOURS);
+        } catch (Exception e) {
+            log.warn("添加匹配历史失败: userId={}, matchedUserId={}", userId, matchedUserId, e);
+        }
+    }
+    
     /**
      * 从User和UserProfile构建MatchData
      */