|
@@ -6,6 +6,7 @@ import com.etotem.cfc.mapper.ReferralLeaderboardMapper;
|
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
import com.etotem.cfc.mapper.UserMapper;
|
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
|
@@ -32,6 +33,12 @@ public class ReferralLeaderboardService {
|
|
|
@Resource
|
|
@Resource
|
|
|
private JdbcTemplate jdbcTemplate;
|
|
private JdbcTemplate jdbcTemplate;
|
|
|
|
|
|
|
|
|
|
+ @Resource
|
|
|
|
|
+ private RedisTemplate<String, Object> redisTemplate;
|
|
|
|
|
+
|
|
|
|
|
+ /** 推荐排行榜 Redis key 前缀 */
|
|
|
|
|
+ private static final String REFERRAL_LEADERBOARD_KEY_PREFIX = "referral:leaderboard:";
|
|
|
|
|
+
|
|
|
/**
|
|
/**
|
|
|
* 获取当前周的周一日期(Asia/Shanghai时区)
|
|
* 获取当前周的周一日期(Asia/Shanghai时区)
|
|
|
*/
|
|
*/
|
|
@@ -56,6 +63,16 @@ public class ReferralLeaderboardService {
|
|
|
} catch (Exception e) {
|
|
} catch (Exception e) {
|
|
|
log.error("排行榜计数递增失败: userId={}, weekStart={}", userId, weekStart, e);
|
|
log.error("排行榜计数递增失败: userId={}, weekStart={}", userId, weekStart, e);
|
|
|
}
|
|
}
|
|
|
|
|
+ // 同步更新 Redis 排行榜(失败不影响主流程)
|
|
|
|
|
+ try {
|
|
|
|
|
+ redisTemplate.opsForZSet().incrementScore(
|
|
|
|
|
+ REFERRAL_LEADERBOARD_KEY_PREFIX + weekStart,
|
|
|
|
|
+ String.valueOf(userId),
|
|
|
|
|
+ 1.0);
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("Redis 排行榜递增失败: userId={}, weekStart={}, error={}",
|
|
|
|
|
+ userId, weekStart, e.getMessage());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -65,6 +82,38 @@ public class ReferralLeaderboardService {
|
|
|
if (weekStart == null || weekStart.isEmpty()) {
|
|
if (weekStart == null || weekStart.isEmpty()) {
|
|
|
weekStart = getCurrentWeekStart();
|
|
weekStart = getCurrentWeekStart();
|
|
|
}
|
|
}
|
|
|
|
|
+ // 优先从 Redis 读取排行榜
|
|
|
|
|
+ try {
|
|
|
|
|
+ java.util.Set<Object> topMembers = redisTemplate.opsForZSet()
|
|
|
|
|
+ .reverseRange(REFERRAL_LEADERBOARD_KEY_PREFIX + weekStart, 0, limit - 1);
|
|
|
|
|
+ if (topMembers != null && !topMembers.isEmpty()) {
|
|
|
|
|
+ List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
+ int rank = 1;
|
|
|
|
|
+ for (Object member : topMembers) {
|
|
|
|
|
+ Long userId = Long.valueOf(member.toString());
|
|
|
|
|
+ Double count = redisTemplate.opsForZSet()
|
|
|
|
|
+ .score(REFERRAL_LEADERBOARD_KEY_PREFIX + weekStart, member);
|
|
|
|
|
+ Map<String, Object> item = new HashMap<>();
|
|
|
|
|
+ item.put("userId", userId);
|
|
|
|
|
+ item.put("referralCount", count != null ? count.intValue() : 0);
|
|
|
|
|
+ item.put("rank", rank);
|
|
|
|
|
+
|
|
|
|
|
+ User user = userMapper.selectById(userId);
|
|
|
|
|
+ if (user != null) {
|
|
|
|
|
+ item.put("nickname", user.getNickname() != null ? user.getNickname() : "微信用户");
|
|
|
|
|
+ item.put("avatarUrl", user.getAvatar() != null ? user.getAvatar() : "");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ item.put("nickname", "未知用户");
|
|
|
|
|
+ item.put("avatarUrl", "");
|
|
|
|
|
+ }
|
|
|
|
|
+ result.add(item);
|
|
|
|
|
+ rank++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("Redis 排行榜读取失败,回退数据库: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
List<ReferralLeaderboard> topList = referralLeaderboardMapper.findTopByWeek(weekStart, limit);
|
|
List<ReferralLeaderboard> topList = referralLeaderboardMapper.findTopByWeek(weekStart, limit);
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
int rank = 1;
|
|
int rank = 1;
|
|
@@ -95,9 +144,23 @@ public class ReferralLeaderboardService {
|
|
|
if (weekStart == null || weekStart.isEmpty()) {
|
|
if (weekStart == null || weekStart.isEmpty()) {
|
|
|
weekStart = getCurrentWeekStart();
|
|
weekStart = getCurrentWeekStart();
|
|
|
}
|
|
}
|
|
|
- ReferralLeaderboard entry = referralLeaderboardMapper.findByUserAndWeek(userId, weekStart);
|
|
|
|
|
Map<String, Object> result = new HashMap<>();
|
|
Map<String, Object> result = new HashMap<>();
|
|
|
result.put("userId", userId);
|
|
result.put("userId", userId);
|
|
|
|
|
+ // 优先从 Redis 读取排名
|
|
|
|
|
+ try {
|
|
|
|
|
+ Double score = redisTemplate.opsForZSet()
|
|
|
|
|
+ .score(REFERRAL_LEADERBOARD_KEY_PREFIX + weekStart, String.valueOf(userId));
|
|
|
|
|
+ if (score != null) {
|
|
|
|
|
+ Long rank = redisTemplate.opsForZSet()
|
|
|
|
|
+ .reverseRank(REFERRAL_LEADERBOARD_KEY_PREFIX + weekStart, String.valueOf(userId));
|
|
|
|
|
+ result.put("referralCount", score.intValue());
|
|
|
|
|
+ result.put("rank", rank != null ? rank + 1 : null);
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
|
+ log.warn("Redis 排名读取失败,回退数据库: {}", e.getMessage());
|
|
|
|
|
+ }
|
|
|
|
|
+ ReferralLeaderboard entry = referralLeaderboardMapper.findByUserAndWeek(userId, weekStart);
|
|
|
if (entry != null) {
|
|
if (entry != null) {
|
|
|
// 计算实际排名:统计比当前用户推荐数多的人数
|
|
// 计算实际排名:统计比当前用户推荐数多的人数
|
|
|
String countSql = "SELECT COUNT(*) + 1 FROM referral_leaderboard " +
|
|
String countSql = "SELECT COUNT(*) + 1 FROM referral_leaderboard " +
|