周星排行榜完善

This commit is contained in:
tianfeng 2025-09-18 22:14:55 +08:00
parent 8628638588
commit 16084a3b74
7 changed files with 240 additions and 25 deletions

View File

@ -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<UserRankCO> leaderboard(WeekStarRankingQueryCmd cmd) {
List<WeekStarGiftCount> weekStarGiftCounts = listLeaderboard(cmd);
private PageResult<UserRankCO> leaderboard(WeekStarRankingQueryCmd cmd, Integer current, Integer size) {
PageResult<WeekStarGiftCount> pageResult = listLeaderboard(cmd,current,size);
if (CollectionUtils.isEmpty(weekStarGiftCounts)) {
return Lists.newArrayList();
if (CollectionUtils.isEmpty(pageResult.getRecords())) {
return null;
}
List<WeekStarGiftCount> weekStarGiftCounts = (List<WeekStarGiftCount>) pageResult.getRecords();
Map<Long, UserProfileDTO> userProfileMap = userProfileAppConvertor.toMapUserProfileDTO(
userProfileGateway
.mapByUserIds(getUserIds(weekStarGiftCounts))
);
return weekStarGiftCounts.stream()
List<UserRankCO> 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<UserRankCO> result = new PageResult<>();
result.setTotal(pageResult.getTotal());
result.setRecords(list);
result.setSize(pageResult.getSize());
return result;
}
private List<WeekStarGiftCount> listLeaderboard(WeekStarRankingQueryCmd cmd) {
private PageResult<WeekStarGiftCount> 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<Long> getUserIds(List<WeekStarGiftCount> weekStarGiftCounts) {

View File

@ -39,15 +39,6 @@ public class WeekStarServiceImpl implements WeekStarService {
@Override
public WeekStarGiftUserRankCO getGiftRanking(WeekStarRankingQueryCmd cmd) {
if (Objects.isNull(cmd.getGiftId())) {
List<GiftConfigCO> giftConfigs = listGift(convertWeekStarGiftQueryCmd(cmd));
if (CollectionUtils.isEmpty(giftConfigs)) {
return null;
}
cmd.setGiftId(giftConfigs.get(0).getId());
}
return weekStarGiftRankingQueryExe.execute(cmd);
}

View File

@ -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<UserRankCO> rankUsers;
private PageResult<UserRankCO> rankUsers;
/**
* 礼物id.

View File

@ -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;
}

View File

@ -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;
/**
* 数量.
*/

View File

@ -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<WeekStarGiftCount> listLastWeekTop(String sysOrigin, Long giftId, Integer size);
/**
* 获取本周统计记录top V2版本.
* 按userId分组汇总quantity倒序排列并添加rank字段.
*/
List<WeekStarGiftCount> listThisWeekTopV2(String sysOrigin, Integer size);
/**
* 获取本周统计记录top V2版本 - 分页版本.
* 按userId分组汇总quantity倒序排列并添加rank字段.
*/
PageResult<WeekStarGiftCount> listThisWeekTopV2(String sysOrigin, Pageable pageable);
/**
* 获取上周统计记录top V2版本.
* 按userId分组汇总quantity倒序排列并添加rank字段.
*/
List<WeekStarGiftCount> listLastWeekTopV2(String sysOrigin, Integer size);
/**
* 获取上周统计记录top V2版本 - 分页版本.
* 按userId分组汇总quantity倒序排列并添加rank字段.
*/
PageResult<WeekStarGiftCount> listLastWeekTopV2(String sysOrigin, Pageable pageable);
/**
* 矫正数据.
*/

View File

@ -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<WeekStarGiftCount> 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<WeekStarGiftCount> results = mongoTemplate
.aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class);
List<WeekStarGiftCount> resultList = results.getMappedResults();
// 添加rank字段
AtomicInteger rank = new AtomicInteger(1);
resultList.forEach(item -> item.setRank(rank.getAndIncrement()));
return resultList;
}
@Override
public List<WeekStarGiftCount> 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<WeekStarGiftCount> results = mongoTemplate
.aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class);
List<WeekStarGiftCount> resultList = results.getMappedResults();
// 添加rank字段
AtomicInteger rank = new AtomicInteger(1);
resultList.forEach(item -> item.setRank(rank.getAndIncrement()));
return resultList;
}
@Override
public PageResult<WeekStarGiftCount> 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<WeekStarGiftCount> results = mongoTemplate
.aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class);
List<WeekStarGiftCount> resultList = results.getMappedResults();
// 添加rank字段考虑分页的偏移量
AtomicInteger rank = new AtomicInteger((int) pageable.getOffset() + 1);
resultList.forEach(item -> item.setRank(rank.getAndIncrement()));
PageResult<WeekStarGiftCount> result = new PageResult<>();
result.setTotal(totalCount);
result.setRecords(resultList);
result.setSize(pageable.getPageSize());
return result;
}
@Override
public PageResult<WeekStarGiftCount> 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<WeekStarGiftCount> results = mongoTemplate
.aggregate(aggregation, WeekStarGiftCount.class, WeekStarGiftCount.class);
List<WeekStarGiftCount> resultList = results.getMappedResults();
// 添加rank字段考虑分页的偏移量
AtomicInteger rank = new AtomicInteger((int) pageable.getOffset() + 1);
resultList.forEach(item -> item.setRank(rank.getAndIncrement()));
PageResult<WeekStarGiftCount> 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<CountResult> 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;
}
}
}