活动排行榜新增regionId

(cherry picked from commit 9ef4d79a32724dfd082393d47dae7c2859684a69)
This commit is contained in:
tianfeng 2026-04-24 14:50:55 +08:00
parent c3665613c4
commit d09b13c038
5 changed files with 114 additions and 87 deletions

View File

@ -9,6 +9,7 @@ import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
import com.red.circle.other.domain.enums.VipAbilityType;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.infra.utils.UserIdEncryptUtils;
@ -51,6 +52,7 @@ public class RankingListQryExe {
private final UserProfileAppConvertor userProfileAppConvertor;
private final SysActivityConfigClient sysActivityConfigClient;
private final EnumConfigCacheService enumConfigCacheService;
private final UserRegionGateway userRegionGateway;
public RankingListCO execute(RankingListQueryCmd cmd) {
// 获取枚举
@ -64,13 +66,15 @@ public class RankingListQryExe {
}
// 查询排行榜列表
String regionId = cmd.getReqUserId() != null ? userRegionGateway.getRegionId(cmd.getReqUserId()) : null;
List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
cmd.getReqSysOrigin().getOrigin(),
activityType,
cycleType,
cmd.getCycleKey(),
null,
cmd.getTopN()
cmd.getTopN(),
regionId
);
Set<Long> userIds = getUserIds(records);
@ -106,7 +110,7 @@ public class RankingListQryExe {
// 查询当前用户排名如果需要
UserRankInfoCO currentUserRank = null;
if (cmd.getIncludeCurrentUser() && cmd.getReqUserId() != null) {
currentUserRank = queryCurrentUserRank(cmd, rankingList);
currentUserRank = queryCurrentUserRank(cmd, rankingList, cycleType, regionId);
UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());
if (userProfile != null) {
currentUserRank.setAccount(userProfile.getActualAccount());
@ -142,17 +146,22 @@ public class RankingListQryExe {
return result;
}
private Set<Long> getUserIds(List<RankingActivityRecord> records) {
return records.stream().map(RankingActivityRecord::getUserId).collect(Collectors.toSet());
}
/**
* 从排行榜列表中查询当前用户排名
* 查询当前用户排名
*/
private UserRankInfoCO queryCurrentUserRank(
RankingListQueryCmd cmd,
List<RankingActivityRecordCO> rankingList) {
List<RankingActivityRecordCO> rankingList,
RankingCycleType cycleType,
String regionId) {
UserRankInfoCO rankInfo = new UserRankInfoCO();
rankInfo.setUserId(cmd.getReqUserId());
// 从排行榜列表中查找当前用户
Optional<RankingActivityRecordCO> userInList = rankingList.stream()
.filter(record -> cmd.getReqUserId().equals(record.getUserId())
|| (record.getUserId() == null
@ -161,18 +170,14 @@ public class RankingListQryExe {
.findFirst();
if (userInList.isPresent()) {
// 用户在榜单中
RankingActivityRecordCO userRecord = userInList.get();
rankInfo.setRank(userRecord.getRank());
rankInfo.setQuantity(userRecord.getQuantity());
rankInfo.setIsRanked(true);
} else {
// 用户不在榜单中显示为0
rankInfo.setRank(0);
rankInfo.setQuantity("0");
rankInfo.setIsRanked(false);
return rankInfo;
}
// 用户不在榜单中单独查询其记录和排名
Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
cmd.getReqSysOrigin().getOrigin(),
cmd.getReqUserId(),
@ -180,64 +185,30 @@ public class RankingListQryExe {
cmd.getCycleKey()
);
userRecord.ifPresent(rankingActivityRecord -> rankInfo.setQuantity(NumUtils.formatLong(rankingActivityRecord.getQuantity())));
if (userRecord.isEmpty()) {
rankInfo.setRank(0);
rankInfo.setQuantity("0");
rankInfo.setIsRanked(false);
return rankInfo;
}
RankingActivityRecord record = userRecord.get();
Integer rank = rankingActivityGateway.calculateUserRank(
cmd.getReqSysOrigin().getOrigin(),
RankingActivityType.getByCode(cmd.getActivityType()),
cycleType,
cmd.getCycleKey(),
null,
record.getQuantity(),
regionId
);
rankInfo.setRank(rank);
rankInfo.setQuantity(NumUtils.formatLong(record.getQuantity()));
rankInfo.setIsRanked(rank <= cmd.getTopN());
return rankInfo;
}
private Set<Long> getUserIds(List<RankingActivityRecord> weekStarGiftCounts) {
return weekStarGiftCounts.stream().map(RankingActivityRecord::getUserId)
.collect(Collectors.toSet());
}
/**
* 查询当前用户排名
*/
private UserRankInfoCO queryCurrentUserRank(
RankingListQueryCmd cmd,
RankingActivityType activityType,
RankingCycleType cycleType) {
Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
cmd.getReqSysOrigin().getOrigin(),
cmd.getReqUserId(),
activityType,
cmd.getCycleKey()
);
if (userRecord.isEmpty()) {
// 用户未参与
UserRankInfoCO rankInfo = new UserRankInfoCO();
rankInfo.setUserId(cmd.getReqUserId());
rankInfo.setRank(0);
rankInfo.setQuantity("0");
rankInfo.setIsRanked(false);
return rankInfo;
}
RankingActivityRecord record = userRecord.get();
// 计算排名
Integer rank = rankingActivityGateway.calculateUserRank(
cmd.getReqSysOrigin().getOrigin(),
activityType,
cycleType,
cmd.getCycleKey(),
null,
record.getQuantity()
);
UserRankInfoCO rankInfo = new UserRankInfoCO();
rankInfo.setUserId(record.getUserId());
rankInfo.setRank(rank);
rankInfo.setQuantity(NumUtils.formatLong(record.getQuantity()));
rankInfo.setIsRanked(rank <= cmd.getTopN());
return rankInfo;
}
/**
* 格式化周期显示文本
*/

View File

@ -125,6 +125,11 @@ public class RankingActivityRecord implements Serializable {
@Transient
Integer rank;
/**
* 区域ID
*/
String regionId;
/**
* 扩展数据JSON 格式
*

View File

@ -109,6 +109,47 @@ public interface RankingActivityRecordRepository extends MongoRepository<Ranking
Long quantity
);
/**
* 查询指定活动和周期的排行榜列表按区域不限性别
*/
List<RankingActivityRecord> findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
String sysOrigin,
RankingActivityType activityType,
RankingCycleType cycleType,
String cycleKey,
String regionId,
Integer deleted,
Pageable pageable
);
/**
* 查询指定活动和周期的排行榜列表按区域 + 性别
*/
List<RankingActivityRecord> findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndUserSexAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
String sysOrigin,
RankingActivityType activityType,
RankingCycleType cycleType,
String cycleKey,
Integer userSex,
String regionId,
Integer deleted,
Pageable pageable
);
/**
* 统计指定活动和周期中数量大于指定值的记录数按区域
*/
@Query(value = "{'sysOrigin': ?0, 'activityType': ?1, 'cycleType': ?2, 'cycleKey': ?3, 'deleted': ?4, 'regionId': ?5, 'quantity': {'$gt': ?6}}", count = true)
Long countByQuantityGreaterThanWithRegion(
String sysOrigin,
RankingActivityType activityType,
RankingCycleType cycleType,
String cycleKey,
Integer deleted,
String regionId,
Long quantity
);
/**
* 删除过期数据
*/

View File

@ -46,6 +46,7 @@ public interface RankingActivityGateway {
* @param cycleKey 周期标识
* @param userSex 用户性别null 表示不限
* @param topN 查询数量
* @param regionId 区域IDnull 表示不限
* @return 排行榜列表
*/
List<RankingActivityRecord> getRankingList(
@ -54,7 +55,8 @@ public interface RankingActivityGateway {
RankingCycleType cycleType,
String cycleKey,
Integer userSex,
Integer topN
Integer topN,
String regionId
);
/**
@ -66,6 +68,7 @@ public interface RankingActivityGateway {
* @param cycleKey 周期标识
* @param userSex 用户性别null 表示不限
* @param quantity 用户数值
* @param regionId 区域IDnull 表示不限
* @return 排名1表示第一名
*/
Integer calculateUserRank(
@ -74,7 +77,8 @@ public interface RankingActivityGateway {
RankingCycleType cycleType,
String cycleKey,
Integer userSex,
Long quantity
Long quantity,
String regionId
);
/**

View File

@ -86,20 +86,27 @@ public class RankingActivityGatewayImpl implements RankingActivityGateway {
RankingCycleType cycleType,
String cycleKey,
Integer userSex,
Integer topN) {
Integer topN,
String regionId) {
PageRequest pageRequest = PageRequest.of(0, topN);
if (regionId != null) {
if (userSex == null) {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, regionId, NOT_DELETED, pageRequest);
} else {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndUserSexAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, userSex, regionId, NOT_DELETED, pageRequest);
}
}
if (userSex == null) {
// 不限性别
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, pageRequest
);
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, pageRequest);
} else {
// 按性别筛选
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndUserSexAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, pageRequest
);
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, pageRequest);
}
}
@ -110,23 +117,22 @@ public class RankingActivityGatewayImpl implements RankingActivityGateway {
RankingCycleType cycleType,
String cycleKey,
Integer userSex,
Long quantity) {
Long quantity,
String regionId) {
Long countGreater;
if (userSex == null) {
// 不限性别
if (regionId != null) {
countGreater = repository.countByQuantityGreaterThanWithRegion(
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, regionId, quantity);
} else if (userSex == null) {
countGreater = repository.countByQuantityGreaterThanWithoutSex(
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, quantity
);
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, quantity);
} else {
// 按性别筛选
countGreater = repository.countByQuantityGreaterThan(
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, quantity
);
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, quantity);
}
// 排名 = 比我多的人数 + 1
return Math.toIntExact((countGreater == null ? 0 : countGreater) + 1);
}