排行榜阿语区分区处理

(cherry picked from commit 9792aa2d915d3bb98da12e35532f1290f6f6e588)
This commit is contained in:
tianfeng 2026-04-24 15:35:32 +08:00
parent d09b13c038
commit fcaa54dab5
8 changed files with 162 additions and 74 deletions

View File

@ -16,13 +16,7 @@ import java.util.Objects;
*/
public enum SysOriginPlatformEnum implements ISysOriginPlatform {
@Deprecated
TIM_CHAT("TimChat", 1),
@Deprecated
YAHLLA("Yahlla", 2),
ASWAT("Aswat", 3),
@Deprecated
ASWAT_LITE("AswatLite", 4),
TWO_FUN("2Fun", 5),
YOLO("Yolo", 6),
TARAB("Tarab",7),
@ -33,10 +27,6 @@ public enum SysOriginPlatformEnum implements ISysOriginPlatform {
ATYOU("Atyou",12),
;
/**
* 语言房系统.
*/
private static final List<SysOriginPlatformEnum> VOICE_SYSTEM = List.of(TARAB, YOLO, HALAR, LIKEI, HOOKA, ATYOU);
/**
* 平台名称.

View File

@ -4,6 +4,7 @@ import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.activity.RankingUserVO;
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
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.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
@ -32,15 +33,18 @@ public class KingGamesDailyTopThreeQryExe {
private final RankingActivityGateway rankingActivityGateway;
private final UserProfileGateway userProfileGateway;
private final UserProfileAppConvertor userProfileAppConvertor;
private final UserRegionGateway userRegionGateway;
public List<RankingUserVO> execute(RankingListQueryCmd cmd) {
String regionId = cmd.getReqUserId() != null ? userRegionGateway.getRegionId(cmd.getReqUserId()) : null;
List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
cmd.getReqSysOrigin().getOrigin(),
RankingActivityType.KING_GAMES_DAILY,
RankingCycleType.DAILY,
cmd.getCycleKey(),
null,
3
3,
regionId
);
if (CollectionUtils.isEmpty(records)) {

View File

@ -2,6 +2,7 @@ package com.red.circle.other.app.command.activity.query;
import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
import com.red.circle.other.app.dto.cmd.UserRankQueryCmd;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.other.domain.ranking.RankingActivityType;
@ -22,6 +23,7 @@ import java.util.Optional;
public class UserRankQryExe {
private final RankingActivityGateway rankingActivityGateway;
private final UserRegionGateway userRegionGateway;
public UserRankInfoCO execute(UserRankQueryCmd cmd) {
// 获取枚举
@ -29,6 +31,7 @@ public class UserRankQryExe {
RankingCycleType cycleType = RankingCycleType.getByCode(cmd.getCycleType());
Long queryUserId = cmd.getUserId() != null ? cmd.getUserId() : cmd.getReqUserId();
String regionId = queryUserId != null ? userRegionGateway.getRegionId(queryUserId) : null;
// 查询用户记录
Optional<RankingActivityRecord> userRecord = rankingActivityGateway.getUserRecord(
@ -58,7 +61,8 @@ public class UserRankQryExe {
cycleType,
cmd.getCycleKey(),
null,
record.getQuantity()
record.getQuantity(),
regionId
);
rankInfo.setRank(rank);

View File

@ -7,11 +7,13 @@ import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.app.convertor.material.GiftAppConvertor;
import com.red.circle.other.app.convertor.sys.ActivityAppConvertor;
import com.red.circle.other.app.dto.clientobject.activity.ActivityResourceCO;
import com.red.circle.other.app.dto.clientobject.gift.GiftConfigCO;
import com.red.circle.other.domain.gateway.props.ActivitySourceGroupGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.infra.common.activity.PropsActivitySendCommon;
@ -31,12 +33,14 @@ import com.red.circle.other.infra.database.mongo.service.user.count.WeekFriendsh
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService;
import com.red.circle.other.infra.database.rds.entity.activity.ActivityFriendshipCardHistory;
import com.red.circle.other.infra.database.rds.entity.activity.PropsActivityRuleConfig;
import com.red.circle.other.infra.database.rds.enums.OtherConfigEnum;
import com.red.circle.other.infra.database.rds.service.activity.ActivityFriendshipCardChampionService;
import com.red.circle.other.infra.database.rds.service.activity.ActivityFriendshipCardHistoryService;
import com.red.circle.other.infra.database.rds.service.activity.PropsActivityRuleConfigService;
import com.red.circle.other.infra.database.rds.service.gift.GiftConfigService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGiftService;
import com.red.circle.other.infra.database.rds.service.sys.WeekStarGroupService;
import com.red.circle.other.infra.constant.RegionConstants;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
import com.red.circle.other.infra.utils.DateFormatEnum;
import com.red.circle.other.infra.utils.ZonedDateTimeUtils;
@ -65,10 +69,13 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.ImmutableTriple;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
@ -205,33 +212,46 @@ public class WeeklyRewardsSentManager {
}
Long activityId = activityConfigDTO.getId();
String lastWeekDate = getLastWeekDate();
String sysOrigin = SysOriginPlatformEnum.ATYOU.name();
// 获取枚举
RankingCycleType cycleType = RankingCycleType.WEEKLY;
// 根据活动类型解析周期信息参考 RankCountStrategy.resolveCycleInfo
RankingActivityType rankingActivityType = RankingActivityType.valueOf(activityType);
RankingCycleType cycleType;
String cycleKey;
if (rankingActivityType.isSeasonCycle()) {
DateTimeFormatter fmt = DateTimeFormatter.ofPattern(DateFormatConstant.yyyyMMdd)
.withZone(ZoneId.of("Asia/Riyadh"));
String start = fmt.format(activityConfigDTO.getStartTime().toInstant());
String end = fmt.format(activityConfigDTO.getEndTime().toInstant());
cycleType = RankingCycleType.SEASON;
cycleKey = start + "-" + end;
} else {
cycleType = RankingCycleType.WEEKLY;
cycleKey = getLastWeekDate();
}
// 4. 获取奖励配置并更新
List<ActivityConfigRewardsDTO> kingRewardList = activityConfigDTO.getButOneRewards();
List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
sysOrigin,
RankingActivityType.valueOf(activityType),
cycleType,
lastWeekDate,
null,
isKingGames(activityConfigDTO) || isRamadan(activityConfigDTO) ? 10 : 3
// AR区和非AR区各查一次分别发奖励
String arRegionId = RegionConstants.AR_REGION_IDS.iterator().next();
List<RankingActivityRecord> arRecords = rankingActivityGateway.getRankingList(
sysOrigin, rankingActivityType, cycleType, cycleKey, null,
isKingGames(activityConfigDTO) ? 10 : 3,
arRegionId
);
List<RankingActivityRecord> otherRecords = rankingActivityGateway.getRankingList(
sysOrigin, rankingActivityType, cycleType, cycleKey, null,
isKingGames(activityConfigDTO) ? 10 : 3,
RegionConstants.OTHER_REGION_PLACEHOLDER
);
// 发放活动奖励
if (isKingGames(activityConfigDTO)) {
sendCustomRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, records, kingRewardList);
}
if (isRamadan(activityConfigDTO)) {
sendRamadanRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, records, kingRewardList);
}
else {
sendRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, records, kingRewardList);
sendCustomRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, arRecords, kingRewardList);
sendCustomRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, otherRecords, kingRewardList);
} else {
sendRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, arRecords, kingRewardList);
sendRankingActivityRewards(SysOriginPlatformEnum.ATYOU, activityId, otherRecords, kingRewardList);
}
log.info("上周{}活动奖励发放完成, 活动ID: {}", activityConfigDTO.getRemark(), activityId);

View File

@ -8,6 +8,7 @@ import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivity
import com.red.circle.other.infra.database.mongo.entity.user.count.WeekCpValueCount;
import com.red.circle.other.infra.database.mongo.service.user.count.WeekCpValueCountService;
import org.apache.commons.lang3.tuple.ImmutablePair;
import com.red.circle.other.infra.constant.RegionConstants;
import com.red.circle.other.infra.database.rds.entity.sys.StartPageUser;
import com.red.circle.other.infra.database.rds.service.sys.StartPageUserService;
import com.red.circle.other.infra.gateway.RankingActivityGateway;
@ -39,6 +40,7 @@ public class UpdateStartPageUserTask {
private final WeekCpValueCountService weekCpValueCountService;
private static final String START_PAGE_TYPE = "KING_GAMES";
private static final String START_PAGE_TYPE_AR = "KING_GAMES_AR";
private static final String CP_START_PAGE_TYPE = "CP";
private static final Integer EXPIRE_DAYS = 7;
@ -56,17 +58,24 @@ public class UpdateStartPageUserTask {
String sysOrigin = SysOriginPlatformEnum.ATYOU.name();
String lastWeekDate = getLastWeekDate();
Long topUserId = getLastWeekTopUser(sysOrigin, lastWeekDate);
String arRegionId = RegionConstants.AR_REGION_IDS.iterator().next();
Long arTopUserId = getLastWeekTopUser(sysOrigin, lastWeekDate, arRegionId);
Long otherTopUserId = getLastWeekTopUser(sysOrigin, lastWeekDate, RegionConstants.OTHER_REGION_PLACEHOLDER);
if (topUserId == null) {
if (arTopUserId == null && otherTopUserId == null) {
log.warn("未找到上周排名第一的用户,跳过更新");
return;
}
updateOrCreateStartPageUser(sysOrigin, topUserId);
if (arTopUserId != null) {
updateOrCreateStartPageUser(sysOrigin, arTopUserId, START_PAGE_TYPE_AR);
}
if (otherTopUserId != null) {
updateOrCreateStartPageUser(sysOrigin, otherTopUserId, START_PAGE_TYPE);
}
log.warn("========== 更新启动页用户定时任务完成,耗时:{} ms用户ID{} ==========",
System.currentTimeMillis() - startTime, topUserId);
log.warn("========== 更新启动页用户定时任务完成,耗时:{} ms ==========" ,
System.currentTimeMillis() - startTime);
} catch (Exception e) {
log.error("========== 更新启动页用户定时任务异常 ==========", e);
@ -140,34 +149,34 @@ public class UpdateStartPageUserTask {
/**
* 获取上周排名第一的用户
*/
private Long getLastWeekTopUser(String sysOrigin, String lastWeekDate) {
private Long getLastWeekTopUser(String sysOrigin, String lastWeekDate, String regionId) {
List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
sysOrigin,
RankingActivityType.KING_GAMES,
RankingCycleType.WEEKLY,
lastWeekDate,
null,
1
1,
regionId
);
if (CollectionUtils.isEmpty(records)) {
log.warn("上周排行榜为空,日期:{}", lastWeekDate);
log.warn("上周排行榜为空,日期:{}regionId{}", lastWeekDate, regionId);
return null;
}
RankingActivityRecord topRecord = records.get(0);
log.info("上周排名第一用户ID{},数量:{}", topRecord.getUserId(), topRecord.getQuantity());
log.info("上周排名第一用户ID{},数量:{}regionId{}", topRecord.getUserId(), topRecord.getQuantity(), regionId);
return topRecord.getUserId();
}
/**
* 更新或创建启动页用户记录
*/
private void updateOrCreateStartPageUser(String sysOrigin, Long userId) {
private void updateOrCreateStartPageUser(String sysOrigin, Long userId, String type) {
StartPageUser existingUser = startPageUserService.query()
.eq(StartPageUser::getSysOrigin, sysOrigin)
.eq(StartPageUser::getType, START_PAGE_TYPE)
.eq(StartPageUser::getType, type)
.last("LIMIT 1")
.getOne();
@ -177,17 +186,16 @@ public class UpdateStartPageUserTask {
existingUser.setUserId(userId);
existingUser.setExpireTime(expireTime);
startPageUserService.updateSelectiveById(existingUser);
log.info("更新启动页用户成功ID{}用户ID{},过期时间:{}",
existingUser.getId(), userId, expireTime);
log.info("更新启动页用户成功ID{},类型:{}用户ID{}", existingUser.getId(), type, userId);
} else {
StartPageUser newUser = new StartPageUser();
newUser.setSysOrigin(sysOrigin);
newUser.setType(START_PAGE_TYPE);
newUser.setType(type);
newUser.setUserId(userId);
newUser.setSort(1);
newUser.setExpireTime(expireTime);
startPageUserService.save(newUser);
log.info("创建启动页用户成功,用户ID{},过期时间:{}", userId, expireTime);
log.info("创建启动页用户成功,类型:{}用户ID{}", type, userId);
}
}

View File

@ -23,7 +23,7 @@ import java.util.stream.Collectors;
@Slf4j
@Component
//@Component
@RequiredArgsConstructor
public class RamadanRankingBadgeTask {
@ -53,7 +53,8 @@ public class RamadanRankingBadgeTask {
RankingCycleType.WEEKLY,
ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString(),
null,
10
10,
null
);
// 2. 查询所有持有排名徽章的用户

View File

@ -0,0 +1,43 @@
package com.red.circle.other.infra.constant;
import java.util.Set;
/**
* 区域常量.
*
* @author tf
*/
public final class RegionConstants {
private RegionConstants() {}
public static final String AR = "AR";
/**
* 阿语区 regionId 集合.
*/
public static final Set<String> AR_REGION_IDS = Set.of(
"2049084769873498113"
);
/** 非AR区占位标识用于查询非AR区数据. */
public static final String OTHER_REGION_PLACEHOLDER = "OTHER";
/**
* 阿语区 countryCode 集合.
*/
public static final Set<String> AR_REGIONS = Set.of(
"AE", "AR", "BH", "DJ", "DZ", "EG", "EY", "ER", "IL", "IQ",
"JO", "KM", "KW", "LB", "LY", "MA", "MR", "OM", "PS", "QA",
"SD", "SO", "SS", "KSA", "SY", "TD", "TN", "YE"
);
public static final Set<String> SA_REGIONS = Set.of("BD", "SA", "IN", "PK", "NPR");
public static final Set<String> TR_REGIONS = Set.of("TR");
public static final Set<String> OTHER_REGIONS = Set.of(
"OTHER", "PH", "ID", "GH", "IR", "AF", "NG", "DE", "MYS", "TM", "AZ", "NP"
);
}

View File

@ -3,6 +3,7 @@ package com.red.circle.other.infra.gateway;
import com.red.circle.other.domain.ranking.RankingActivityType;
import com.red.circle.other.domain.ranking.RankingCycleType;
import com.red.circle.other.infra.database.mongo.entity.activity.RankingActivityRecord;
import com.red.circle.other.infra.constant.RegionConstants;
import com.red.circle.other.infra.database.mongo.service.activity.RankingActivityRecordRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -89,25 +90,34 @@ public class RankingActivityGatewayImpl implements RankingActivityGateway {
Integer topN,
String regionId) {
PageRequest pageRequest = PageRequest.of(0, topN);
Criteria criteria = Criteria
.where("sysOrigin").is(sysOrigin)
.and("activityType").is(activityType)
.and("cycleType").is(cycleType)
.and("cycleKey").is(cycleKey)
.and("deleted").is(NOT_DELETED);
if (userSex != null) {
criteria.and("userSex").is(userSex);
}
if (regionId != null) {
if (userSex == null) {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, regionId, NOT_DELETED, pageRequest);
if (RegionConstants.AR_REGION_IDS.contains(regionId)) {
criteria.and("regionId").in(RegionConstants.AR_REGION_IDS);
} else {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndUserSexAndRegionIdAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, userSex, regionId, NOT_DELETED, pageRequest);
criteria.and("regionId").nin(RegionConstants.AR_REGION_IDS);
}
}
if (userSex == null) {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, NOT_DELETED, pageRequest);
} else {
return repository.findBySysOriginAndActivityTypeAndCycleTypeAndCycleKeyAndUserSexAndDeletedOrderByQuantityDescCreateTimeAsc(
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, pageRequest);
}
Query query = new Query(criteria)
.with(org.springframework.data.domain.Sort.by(
org.springframework.data.domain.Sort.Direction.DESC, "quantity"
).and(org.springframework.data.domain.Sort.by(
org.springframework.data.domain.Sort.Direction.ASC, "createTime"
)))
.limit(topN);
return mongoTemplate.find(query, RankingActivityRecord.class);
}
@Override
@ -120,20 +130,28 @@ public class RankingActivityGatewayImpl implements RankingActivityGateway {
Long quantity,
String regionId) {
Long countGreater;
Criteria criteria = Criteria
.where("sysOrigin").is(sysOrigin)
.and("activityType").is(activityType)
.and("cycleType").is(cycleType)
.and("cycleKey").is(cycleKey)
.and("deleted").is(NOT_DELETED)
.and("quantity").gt(quantity);
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);
} else {
countGreater = repository.countByQuantityGreaterThan(
sysOrigin, activityType, cycleType, cycleKey, userSex, NOT_DELETED, quantity);
if (userSex != null) {
criteria.and("userSex").is(userSex);
}
return Math.toIntExact((countGreater == null ? 0 : countGreater) + 1);
if (regionId != null) {
if (RegionConstants.AR_REGION_IDS.contains(regionId)) {
criteria.and("regionId").in(RegionConstants.AR_REGION_IDS);
} else {
criteria.and("regionId").nin(RegionConstants.AR_REGION_IDS);
}
}
long countGreater = mongoTemplate.count(new Query(criteria), RankingActivityRecord.class);
return Math.toIntExact(countGreater + 1);
}
@Override