diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/query/WeekStarGiftRankingQueryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/query/WeekStarGiftRankingQueryExe.java index b8a8f5ef..f9b68c92 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/query/WeekStarGiftRankingQueryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/query/WeekStarGiftRankingQueryExe.java @@ -2,6 +2,7 @@ package com.red.circle.other.app.command.activity.query; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.red.circle.common.business.enums.WeekLeaderboardEnum; +import com.red.circle.framework.dto.PageResult; import com.red.circle.other.app.convertor.user.UserProfileAppConvertor; import com.red.circle.other.app.dto.clientobject.activity.UserRankCO; import com.red.circle.other.app.dto.clientobject.activity.WeekStarGiftUserRankCO; @@ -12,12 +13,12 @@ import com.red.circle.other.infra.database.mongo.service.activity.WeekStarGiftCo import com.red.circle.other.inner.model.dto.user.UserProfileDTO; import com.red.circle.tool.core.collection.CollectionUtils; import com.red.circle.tool.core.num.NumUtils; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Set; + +import java.util.*; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; /** @@ -36,23 +37,25 @@ public class WeekStarGiftRankingQueryExe { public WeekStarGiftUserRankCO execute(WeekStarRankingQueryCmd cmd) { return new WeekStarGiftUserRankCO() .setGiftId(cmd.getGiftId()) - .setRankUsers(leaderboard(cmd)); + .setRankUsers(leaderboard(cmd, cmd.getCurrent(), cmd.getSize())); } - private List leaderboard(WeekStarRankingQueryCmd cmd) { - List weekStarGiftCounts = listLeaderboard(cmd); + private PageResult leaderboard(WeekStarRankingQueryCmd cmd, Integer current, Integer size) { + PageResult pageResult = listLeaderboard(cmd,current,size); - if (CollectionUtils.isEmpty(weekStarGiftCounts)) { - return Lists.newArrayList(); + if (CollectionUtils.isEmpty(pageResult.getRecords())) { + return null; } + List weekStarGiftCounts = (List) pageResult.getRecords(); + Map userProfileMap = userProfileAppConvertor.toMapUserProfileDTO( userProfileGateway .mapByUserIds(getUserIds(weekStarGiftCounts)) ); - return weekStarGiftCounts.stream() + List list = weekStarGiftCounts.stream() .map(item -> { UserProfileDTO userProfile = userProfileMap.get(item.getUserId()); if (Objects.isNull(userProfile)) { @@ -60,7 +63,9 @@ public class WeekStarGiftRankingQueryExe { } return new UserRankCO() .setUserId(userProfile.getId()) + .setAccount(userProfile.getAccount()) .setUserAvatar(userProfile.getUserAvatar()) + .setRank(item.getRank()) .setUserNickname(userProfile.getUserNickname()) .setQuantity(NumUtils.formatLong(item.getQuantity())) .setCountryCode(userProfile.getCountryCode()) @@ -68,20 +73,26 @@ public class WeekStarGiftRankingQueryExe { }) .filter(Objects::nonNull) .toList(); + + PageResult result = new PageResult<>(); + result.setTotal(pageResult.getTotal()); + result.setRecords(list); + result.setSize(pageResult.getSize()); + return result; } - private List listLeaderboard(WeekStarRankingQueryCmd cmd) { + private PageResult listLeaderboard(WeekStarRankingQueryCmd cmd, Integer current, Integer size) { if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.THIS_WEEK)) { return weekStarGiftCountService - .listThisWeekTop(cmd.getReqSysOrigin().getOrigin(), cmd.getGiftId(), 30); - } + .listThisWeekTopV2(cmd.getReqSysOrigin().getOrigin(), PageRequest.of(current - 1, size)); + } if (Objects.equals(cmd.getType(), WeekLeaderboardEnum.LAST_WEEK)) { return weekStarGiftCountService - .listLastWeekTop(cmd.getReqSysOrigin().getOrigin(), cmd.getGiftId(), 30); + .listLastWeekTopV2(cmd.getReqSysOrigin().getOrigin(), PageRequest.of(current - 1, size)); } - return Lists.newArrayList(); + return PageResult.newPageResult(20); } private Set getUserIds(List weekStarGiftCounts) { diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/WeekStarServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/WeekStarServiceImpl.java index c6048bfc..d7ac0ab8 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/WeekStarServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/WeekStarServiceImpl.java @@ -39,15 +39,6 @@ public class WeekStarServiceImpl implements WeekStarService { @Override public WeekStarGiftUserRankCO getGiftRanking(WeekStarRankingQueryCmd cmd) { - - if (Objects.isNull(cmd.getGiftId())) { - List giftConfigs = listGift(convertWeekStarGiftQueryCmd(cmd)); - if (CollectionUtils.isEmpty(giftConfigs)) { - return null; - } - cmd.setGiftId(giftConfigs.get(0).getId()); - } - return weekStarGiftRankingQueryExe.execute(cmd); } diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/WeekStarGiftUserRankCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/WeekStarGiftUserRankCO.java index 9d64df2e..30c4ceaa 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/WeekStarGiftUserRankCO.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/WeekStarGiftUserRankCO.java @@ -4,6 +4,8 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.red.circle.framework.dto.ClientObject; import java.util.List; + +import com.red.circle.framework.dto.PageResult; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; @@ -21,7 +23,7 @@ public class WeekStarGiftUserRankCO extends ClientObject { /** * 排名用户. */ - private List rankUsers; + private PageResult rankUsers; /** * 礼物id. diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/WeekStarRankingQueryCmd.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/WeekStarRankingQueryCmd.java index ba2709db..7d52e3f3 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/WeekStarRankingQueryCmd.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/WeekStarRankingQueryCmd.java @@ -26,4 +26,8 @@ public class WeekStarRankingQueryCmd extends AppExtCommand { @NotNull(message = "type {not.null}") private WeekLeaderboardEnum type; + private Integer current = 1; + + private Integer size = 20; + } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/entity/activity/WeekStarGiftCount.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/entity/activity/WeekStarGiftCount.java index 5f919b8b..b1cf8aca 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/entity/activity/WeekStarGiftCount.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/entity/activity/WeekStarGiftCount.java @@ -9,6 +9,7 @@ import lombok.Data; import lombok.experimental.Accessors; import lombok.experimental.FieldDefaults; import org.springframework.data.annotation.Id; +import org.springframework.data.annotation.Transient; import org.springframework.data.mongodb.core.mapping.Document; /** @@ -53,6 +54,12 @@ public class WeekStarGiftCount implements Serializable { */ String group; + /** + * 排名 + */ + @Transient + Integer rank; + /** * 数量. */ diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/WeekStarGiftCountService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/WeekStarGiftCountService.java index 2bffbc74..7bedfd1c 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/WeekStarGiftCountService.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/WeekStarGiftCountService.java @@ -1,7 +1,10 @@ package com.red.circle.other.infra.database.mongo.service.activity; +import com.red.circle.framework.dto.PageResult; import com.red.circle.other.infra.database.mongo.entity.activity.WeekStarGiftCount; import java.util.List; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; /** * 周星礼物统计. @@ -25,6 +28,30 @@ public interface WeekStarGiftCountService { */ List listLastWeekTop(String sysOrigin, Long giftId, Integer size); + /** + * 获取本周统计记录top V2版本. + * 按userId分组汇总quantity,倒序排列并添加rank字段. + */ + List listThisWeekTopV2(String sysOrigin, Integer size); + + /** + * 获取本周统计记录top V2版本 - 分页版本. + * 按userId分组汇总quantity,倒序排列并添加rank字段. + */ + PageResult listThisWeekTopV2(String sysOrigin, Pageable pageable); + + /** + * 获取上周统计记录top V2版本. + * 按userId分组汇总quantity,倒序排列并添加rank字段. + */ + List listLastWeekTopV2(String sysOrigin, Integer size); + + /** + * 获取上周统计记录top V2版本 - 分页版本. + * 按userId分组汇总quantity,倒序排列并添加rank字段. + */ + PageResult listLastWeekTopV2(String sysOrigin, Pageable pageable); + /** * 矫正数据. */ diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/impl/WeekStarGiftCountServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/impl/WeekStarGiftCountServiceImpl.java index b96130e3..80502199 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/impl/WeekStarGiftCountServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/activity/impl/WeekStarGiftCountServiceImpl.java @@ -1,5 +1,6 @@ package com.red.circle.other.infra.database.mongo.service.activity.impl; +import com.red.circle.framework.dto.PageResult; import com.red.circle.other.infra.database.mongo.entity.activity.WeekStarGiftCount; import com.red.circle.other.infra.database.mongo.service.activity.WeekStarGiftCountService; import com.red.circle.tool.core.date.DateFormatConstant; @@ -8,9 +9,15 @@ import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils; import com.red.circle.tool.core.date.ZonedDateTimeUtils; import java.util.List; import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; +import org.springframework.data.mongodb.core.aggregation.Aggregation; +import org.springframework.data.mongodb.core.aggregation.AggregationResults; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; @@ -78,6 +85,138 @@ public class WeekStarGiftCountServiceImpl implements WeekStarGiftCountService { .limit(size), WeekStarGiftCount.class); } + @Override + public List listThisWeekTopV2(String sysOrigin, Integer size) { + // 使用聚合查询,按userId分组,求和quantity,然后排序并添加rank字段 + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(Criteria.where("sysOrigin").is(sysOrigin) + .and("group").is(getThisWeekDate())), + Aggregation.group("userId") + .first("sysOrigin").as("sysOrigin") + .first("userId").as("userId") + .first("group").as("group") + .first("createTime").as("createTime") + .first("expiredTime").as("expiredTime") + .sum("quantity").as("quantity"), + Aggregation.sort(Sort.by(Sort.Order.desc("quantity"))), + Aggregation.limit(size) + ); + + AggregationResults results = mongoTemplate + .aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class); + + List resultList = results.getMappedResults(); + + // 添加rank字段 + AtomicInteger rank = new AtomicInteger(1); + resultList.forEach(item -> item.setRank(rank.getAndIncrement())); + + return resultList; + } + + @Override + public List listLastWeekTopV2(String sysOrigin, Integer size) { + // 使用聚合查询,按userId分组,求和quantity,然后排序并添加rank字段 + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(Criteria.where("sysOrigin").is(sysOrigin) + .and("group").is(getLastWeekDate())), + Aggregation.group("userId") + .first("sysOrigin").as("sysOrigin") + .first("userId").as("userId") + .first("group").as("group") + .first("createTime").as("createTime") + .first("expiredTime").as("expiredTime") + .sum("quantity").as("quantity"), + Aggregation.sort(Sort.by(Sort.Order.desc("quantity"))), + Aggregation.limit(size) + ); + + AggregationResults results = mongoTemplate + .aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class); + + List resultList = results.getMappedResults(); + + // 添加rank字段 + AtomicInteger rank = new AtomicInteger(1); + resultList.forEach(item -> item.setRank(rank.getAndIncrement())); + + return resultList; + } + + @Override + public PageResult listThisWeekTopV2(String sysOrigin, Pageable pageable) { + // 先获取总数量 + long totalCount = getTotalUserCount(sysOrigin, getThisWeekDate()); + + // 使用聚合查询进行分页 + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(Criteria.where("sysOrigin").is(sysOrigin) + .and("group").is(getThisWeekDate())), + Aggregation.group("userId") + .first("sysOrigin").as("sysOrigin") + .first("userId").as("userId") + .first("group").as("group") + .first("createTime").as("createTime") + .first("expiredTime").as("expiredTime") + .sum("quantity").as("quantity"), + Aggregation.sort(Sort.by(Sort.Order.desc("quantity"))), + Aggregation.skip(pageable.getOffset()), + Aggregation.limit(pageable.getPageSize()) + ); + + AggregationResults results = mongoTemplate + .aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class); + + List resultList = results.getMappedResults(); + + // 添加rank字段(考虑分页的偏移量) + AtomicInteger rank = new AtomicInteger((int) pageable.getOffset() + 1); + resultList.forEach(item -> item.setRank(rank.getAndIncrement())); + + PageResult result = new PageResult<>(); + result.setTotal(totalCount); + result.setRecords(resultList); + result.setSize(pageable.getPageSize()); + return result; + } + + @Override + public PageResult listLastWeekTopV2(String sysOrigin, Pageable pageable) { + // 先获取总数量 + long totalCount = getTotalUserCount(sysOrigin, getLastWeekDate()); + + // 使用聚合查询进行分页 + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(Criteria.where("sysOrigin").is(sysOrigin) + .and("group").is(getLastWeekDate())), + Aggregation.group("userId") + .first("sysOrigin").as("sysOrigin") + .first("userId").as("userId") + .first("group").as("group") + .first("createTime").as("createTime") + .first("expiredTime").as("expiredTime") + .sum("quantity").as("quantity"), + Aggregation.sort(Sort.by(Sort.Order.desc("quantity"))), + Aggregation.skip(pageable.getOffset()), + Aggregation.limit(pageable.getPageSize()) + ); + + AggregationResults results = mongoTemplate + .aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class); + + List resultList = results.getMappedResults(); + + // 添加rank字段(考虑分页的偏移量) + AtomicInteger rank = new AtomicInteger((int) pageable.getOffset() + 1); + resultList.forEach(item -> item.setRank(rank.getAndIncrement())); + + PageResult result = new PageResult<>(); + result.setTotal(totalCount); + result.setRecords(resultList); + result.setSize(pageable.getPageSize()); + return result; + } + @Override public void correctionData(Long userId, Long quantity, Long giftId) { @@ -124,4 +263,38 @@ public class WeekStarGiftCountServiceImpl implements WeekStarGiftCountService { .and("group").is(getThisWeekDate()); } + /** + * 获取指定时间组的用户总数(用于分页). + */ + private long getTotalUserCount(String sysOrigin, String groupDate) { + Aggregation countAggregation = Aggregation.newAggregation( + Aggregation.match(Criteria.where("sysOrigin").is(sysOrigin) + .and("group").is(groupDate)), + Aggregation.group("userId"), + Aggregation.count().as("count") + ); + + AggregationResults countResults = mongoTemplate + .aggregate(countAggregation, WeekStarGiftCount.class, CountResult.class); + + return countResults.getMappedResults().stream() + .mapToLong(CountResult::getCount) + .sum(); + } + + /** + * 用于接收计数结果的内部类. + */ + private static class CountResult { + private long count; + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + } + }