排行榜隐身我的排名 新增加密用户ID逻辑

This commit is contained in:
tianfeng 2026-03-19 12:19:55 +08:00
parent 9c257eba1b
commit 37d6fc7273
6 changed files with 55 additions and 2 deletions

View File

@ -10,6 +10,7 @@ import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheSe
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenCount;
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenType;
import com.red.circle.other.infra.database.mongo.service.activity.RankCountService;
import com.red.circle.other.infra.utils.UserIdEncryptUtils;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
@ -104,6 +105,7 @@ public class GiftsReceivedLeaderboardQryExe {
.setQuantityFormat(NumUtils.formatLong(count.getQuantity()));
if (invisibleUserIds.contains(count.getBusinessId())) {
co.setId(null);
co.setEncryptedId(UserIdEncryptUtils.encrypt(userProfile.getId()));
co.setNickname("****");
co.setAvatar(enumConfigCacheService.getValue(EnumConfigKey.USER_YINSHEN_COVER, userProfile.getSysOriginChild()));
} else {

View File

@ -10,6 +10,7 @@ import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheSe
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenCount;
import com.red.circle.other.infra.database.mongo.entity.activity.RankQueenType;
import com.red.circle.other.infra.database.mongo.service.activity.RankCountService;
import com.red.circle.other.infra.utils.UserIdEncryptUtils;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
@ -116,6 +117,7 @@ public class GiftsSendLeaderboardQryExe {
.setQuantityFormat(NumUtils.formatLong(count.getQuantity()));
if (invisibleUserIds.contains(count.getBusinessId())) {
co.setId(null);
co.setEncryptedId(UserIdEncryptUtils.encrypt(userProfile.getId()));
co.setNickname("****");
co.setAvatar(enumConfigCacheService.getValue(EnumConfigKey.USER_YINSHEN_COVER, userProfile.getSysOriginChild()));
} else {

View File

@ -16,6 +16,7 @@ import com.red.circle.other.infra.database.cache.key.RankKey;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.cache.service.user.RankCacheService;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.infra.utils.UserIdEncryptUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@ -236,7 +237,11 @@ public class ActivityLeaderboardServiceImpl implements ActivityLeaderboardServic
// 查找用户排名
for (int i = 0; i < rankList.size(); i++) {
ActivityLeaderboardCO.LeaderboardUserCO userCO = rankList.get(i);
if (Objects.equals(userCO.getId(), userId)) {
boolean matched = Objects.equals(userCO.getId(), userId)
|| (userCO.getId() == null
&& userCO.getEncryptedId() != null
&& Objects.equals(UserIdEncryptUtils.decrypt(userCO.getEncryptedId()), userId));
if (matched) {
userCO.setRank(i + 1);
return userCO;
}

View File

@ -67,6 +67,11 @@ public class ActivityLeaderboardCO extends ClientObject {
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 加密后的用户ID隐身用户使用用于myRank匹配.
*/
private String encryptedId;
/**
* 头像.
*/

View File

@ -23,7 +23,7 @@ import java.util.concurrent.TimeUnit;
public class RankCacheServiceImpl implements RankCacheService {
private final RedisService redisService;
private static final long CACHE_TIME = 5;
private static final long CACHE_TIME = 2;
@Override
public void remove(String sysOrigin, String type) {

View File

@ -0,0 +1,39 @@
package com.red.circle.other.infra.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* 用户ID加密工具用于排行榜隐身场景.
*
* @author tf
*/
public class UserIdEncryptUtils {
private static final String ALGORITHM = "AES/ECB/PKCS5Padding";
private static final byte[] KEY = "likei_rank_2026!".getBytes(StandardCharsets.UTF_8); // 16字节
public static String encrypt(Long userId) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(KEY, "AES"));
byte[] encrypted = cipher.doFinal(userId.toString().getBytes(StandardCharsets.UTF_8));
return Base64.getUrlEncoder().withoutPadding().encodeToString(encrypted);
} catch (Exception e) {
throw new RuntimeException("userId encrypt error", e);
}
}
public static Long decrypt(String token) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(KEY, "AES"));
byte[] decoded = Base64.getUrlDecoder().decode(token);
return Long.parseLong(new String(cipher.doFinal(decoded), StandardCharsets.UTF_8));
} catch (Exception e) {
throw new RuntimeException("userId decrypt error", e);
}
}
}