diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java index 694e0496..dedf553d 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/family/FamilyRestController.java @@ -127,13 +127,21 @@ public class FamilyRestController extends BaseController { } /** - * 家族排行榜. + * 家族成员Top10周排行榜 */ - @GetMapping("/leaderboard") - public FamilyLeaderboardCO getLeaderboard(AppExtCommand cmd) { + @GetMapping("/member-top10") + public FamilyLeaderboardCO getMemberTop10(FamilyBaseInfoQueryCmd cmd) { return familyService.getLeaderboard(cmd); } + /** + * 家族成员Top100总排行榜 + */ + @GetMapping("/member-top100") + public FamilyLeaderboardCO getMemberTop100(FamilyBaseInfoQueryCmd cmd) { + return familyService.getMemberTop100(cmd); + } + /** * 家族等级配置 */ diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyLeaderboardExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyLeaderboardExe.java index 1daa517c..f36fe618 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyLeaderboardExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyLeaderboardExe.java @@ -5,6 +5,7 @@ import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.live.inner.endpoint.LiveMicClient; import com.red.circle.other.app.dto.clientobject.family.FamilyLeaderboardCO; import com.red.circle.other.app.dto.clientobject.family.FamilyMemberWeekRankCO; +import com.red.circle.other.app.dto.cmd.family.FamilyBaseInfoQueryCmd; import com.red.circle.other.domain.gateway.user.UserProfileGateway; import com.red.circle.other.domain.model.user.UserProfile; import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember; @@ -39,18 +40,19 @@ public class FamilyLeaderboardExe { private final FamilyMemberInfoService familyMemberInfoService; private final FamilyMemberWeekExpService familyMemberWeekExpService; - public FamilyLeaderboardCO execute(AppExtCommand cmd) { - FamilyMemberInfo member = familyMemberInfoService.getFamilyMemberByUserId(cmd.getReqUserId()); + public FamilyLeaderboardCO execute(FamilyBaseInfoQueryCmd cmd) { + Map map = familyMemberInfoService.mapUserIdBaseInfo(cmd.getFamilyId(), Set.of(cmd.getReqUserId())); + FamilyMemberInfo member = map.get(cmd.getReqUserId()); if (Objects.isNull(member)) { return new FamilyLeaderboardCO(); } - List top200Exp = getTop200WeekExp(member.getFamilyId()); - if (CollectionUtils.isEmpty(top200Exp)) { + List top100Exp = getTop100WeekExp(member.getFamilyId()); + if (CollectionUtils.isEmpty(top100Exp)) { return new FamilyLeaderboardCO(); } - Set userIds = top200Exp.stream() + Set userIds = top100Exp.stream() .map(FamilyMemberWeekExp::getFamilyMemberId) .collect(Collectors.toSet()); @@ -60,19 +62,19 @@ public class FamilyLeaderboardExe { List hostRank = new ArrayList<>(); List supporterRank = new ArrayList<>(); - for (FamilyMemberWeekExp exp : top200Exp) { + for (FamilyMemberWeekExp exp : top100Exp) { Long userId = exp.getFamilyMemberId(); boolean isHost = hostUserIds.contains(userId); FamilyMemberWeekRankCO rankCO = buildRankCO(exp, userProfileMap.get(userId), isHost); - if (isHost && hostRank.size() < 100) { + if (isHost && hostRank.size() < 10) { hostRank.add(rankCO); - } else if (!isHost && supporterRank.size() < 100) { + } else if (!isHost && supporterRank.size() < 10) { supporterRank.add(rankCO); } - if (hostRank.size() >= 100 && supporterRank.size() >= 100) { + if (hostRank.size() >= 10 && supporterRank.size() >= 10) { break; } } @@ -82,11 +84,11 @@ public class FamilyLeaderboardExe { .setSupporterWeekRank(supporterRank); } - private List getTop200WeekExp(Long familyId) { + private List getTop100WeekExp(Long familyId) { return familyMemberWeekExpService.query() .eq(FamilyMemberWeekExp::getFamilyId, familyId) .orderByDesc(FamilyMemberWeekExp::getExp) - .last("LIMIT 200") + .last("LIMIT 100") .list(); } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyMemberTop100Exe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyMemberTop100Exe.java new file mode 100644 index 00000000..8e8fa0bc --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/family/FamilyMemberTop100Exe.java @@ -0,0 +1,110 @@ +package com.red.circle.other.app.command.family; + +import com.red.circle.other.app.dto.clientobject.family.FamilyLeaderboardCO; +import com.red.circle.other.app.dto.clientobject.family.FamilyMemberWeekRankCO; +import com.red.circle.other.app.dto.cmd.family.FamilyBaseInfoQueryCmd; +import com.red.circle.other.domain.gateway.user.UserProfileGateway; +import com.red.circle.other.domain.model.user.UserProfile; +import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember; +import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService; +import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo; +import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberTotalExp; +import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService; +import com.red.circle.other.infra.database.rds.service.family.FamilyMemberTotalExpService; +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.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 家族成员Top100总排行榜 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class FamilyMemberTop100Exe { + + private final TeamMemberService teamMemberService; + private final UserProfileGateway userProfileGateway; + private final FamilyMemberInfoService familyMemberInfoService; + private final FamilyMemberTotalExpService familyMemberTotalExpService; + + public FamilyLeaderboardCO execute(FamilyBaseInfoQueryCmd cmd) { + Map map = familyMemberInfoService.mapUserIdBaseInfo(cmd.getFamilyId(), Set.of(cmd.getReqUserId())); + FamilyMemberInfo member = map.get(cmd.getReqUserId()); + if (Objects.isNull(member)) { + return new FamilyLeaderboardCO(); + } + + List top200Exp = getTop200TotalExp(member.getFamilyId()); + if (CollectionUtils.isEmpty(top200Exp)) { + return new FamilyLeaderboardCO(); + } + + Set userIds = top200Exp.stream() + .map(FamilyMemberTotalExp::getFamilyMemberId) + .collect(Collectors.toSet()); + + Set hostUserIds = getHostUserIds(userIds); + Map userProfileMap = userProfileGateway.mapByUserIds(userIds); + + List hostRank = new ArrayList<>(); + List supporterRank = new ArrayList<>(); + + for (FamilyMemberTotalExp exp : top200Exp) { + Long userId = exp.getFamilyMemberId(); + boolean isHost = hostUserIds.contains(userId); + + FamilyMemberWeekRankCO rankCO = buildRankCO(exp, userProfileMap.get(userId), isHost); + + if (isHost && hostRank.size() < 100) { + hostRank.add(rankCO); + } else if (!isHost && supporterRank.size() < 100) { + supporterRank.add(rankCO); + } + + if (hostRank.size() >= 100 && supporterRank.size() >= 100) { + break; + } + } + + return new FamilyLeaderboardCO() + .setHostWeekRank(hostRank) + .setSupporterWeekRank(supporterRank); + } + + private List getTop200TotalExp(Long familyId) { + return familyMemberTotalExpService.query() + .eq(FamilyMemberTotalExp::getFamilyId, familyId) + .orderByDesc(FamilyMemberTotalExp::getExp) + .last("LIMIT 200") + .list(); + } + + private Set getHostUserIds(Set userIds) { + if (CollectionUtils.isEmpty(userIds)) { + return Set.of(); + } + + List hostIds = teamMemberService.listMemberIds(userIds); + return CollectionUtils.isEmpty(hostIds) ? Set.of() : Set.copyOf(hostIds); + } + + private FamilyMemberWeekRankCO buildRankCO(FamilyMemberTotalExp exp, + UserProfile profile, boolean isHost) { + return new FamilyMemberWeekRankCO() + .setUserId(exp.getFamilyMemberId()) + .setNickname(Objects.nonNull(profile) ? profile.getUserNickname() : "") + .setAvatar(Objects.nonNull(profile) ? profile.getUserAvatar() : "") + .setExp(NumUtils.formatLong(exp.getExp())) + .setIsHost(isHost); + } +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java index bc795b56..453831dd 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/family/FamilyServiceImpl.java @@ -32,6 +32,7 @@ import com.red.circle.other.app.command.family.FamilyListExe; import com.red.circle.other.app.command.family.FamilyBoxContributeExe; import com.red.circle.other.app.command.family.FamilyBoxClaimExe; import com.red.circle.other.app.command.family.FamilyHomeListExe; +import com.red.circle.other.app.command.family.FamilyMemberTop100Exe; import com.red.circle.other.app.dto.clientobject.family.*; import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO; import com.red.circle.other.app.dto.cmd.family.*; @@ -86,8 +87,9 @@ public class FamilyServiceImpl implements FamilyService { private final FamilyListExe familyListExe; private final FamilyBoxContributeExe familyBoxContributeExe; private final FamilyBoxClaimExe familyBoxClaimExe; - private final DistributedLockUtil distributedLockUtil; private final FamilyHomeListExe familyHomeListExe; + private final FamilyMemberTop100Exe familyMemberTop100Exe; + private final DistributedLockUtil distributedLockUtil; @Override public Long create(FamilyCreateCmd cmd) { @@ -128,10 +130,15 @@ public class FamilyServiceImpl implements FamilyService { } @Override - public FamilyLeaderboardCO getLeaderboard(AppExtCommand cmd) { + public FamilyLeaderboardCO getLeaderboard(FamilyBaseInfoQueryCmd cmd) { return familyLeaderboardExe.execute(cmd); } + @Override + public FamilyLeaderboardCO getMemberTop100(FamilyBaseInfoQueryCmd cmd) { + return familyMemberTop100Exe.execute(cmd); + } + @Override public List listLevelConfig(AppExtCommand cmd) { return familyLevelListExe.execute(cmd); diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java index 0adb62f1..723a92c2 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/family/FamilyService.java @@ -52,9 +52,14 @@ public interface FamilyService { void grantUserRole(FamilyGrantUserRoleCmd cmd); /** - * 家族排行榜 周榜、月榜、自己家族信息. + * 家族成员Top10周排行榜. */ - FamilyLeaderboardCO getLeaderboard(AppExtCommand cmd); + FamilyLeaderboardCO getLeaderboard(FamilyBaseInfoQueryCmd cmd); + + /** + * 家族成员Top100总排行榜. + */ + FamilyLeaderboardCO getMemberTop100(FamilyBaseInfoQueryCmd cmd); /** * 全部等级配置集合.