diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/LotteryActivityRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/LotteryActivityRestController.java index 236bbb6c..221f5a61 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/LotteryActivityRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/activity/LotteryActivityRestController.java @@ -7,10 +7,12 @@ import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO; +import com.red.circle.other.app.dto.clientobject.activity.LotteryRankCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO; import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd; +import com.red.circle.other.app.dto.cmd.activity.LotteryRankQryCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd; import com.red.circle.other.app.service.activity.LotteryActivityRestService; @@ -150,4 +152,17 @@ public class LotteryActivityRestController extends BaseController { return lotteryActivityRestService.getMyTicketCount(cmd); } + /** + * 查询排行榜. + * + * @eo.name 查询排行榜. + * @eo.url /rank-list + * @eo.method get + * @eo.request-type formdata + */ + @GetMapping("/rank-list") + public List getRankList(LotteryRankQryCmd cmd) { + return lotteryActivityRestService.getRankList(cmd); + } + } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryRankQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryRankQryExe.java new file mode 100644 index 00000000..0eba36ad --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/activity/LotteryRankQryExe.java @@ -0,0 +1,134 @@ +package com.red.circle.other.app.command.activity; + +import com.red.circle.other.app.dto.clientobject.activity.LotteryRankCO; +import com.red.circle.other.app.dto.cmd.activity.LotteryRankQryCmd; +import com.red.circle.other.infra.database.rds.entity.activity.LotteryUserProgress; +import com.red.circle.other.infra.database.rds.service.activity.LotteryUserProgressService; +import com.red.circle.other.inner.endpoint.user.user.UserProfileClient; +import com.red.circle.other.inner.model.dto.user.UserProfileDTO; +import com.red.circle.tool.core.text.StringUtils; +import java.time.LocalDate; +import java.time.temporal.WeekFields; +import java.util.*; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +/** + * 查询抽奖排行榜. + * + * @author system + * @since 2025-10-21 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class LotteryRankQryExe { + + private final LotteryUserProgressService lotteryUserProgressService; + private final UserProfileClient userProfileClient; + + public List execute(LotteryRankQryCmd cmd) { + Long currentUserId = cmd.getReqUserId(); + + // 1. 确定周标识 + String weekKey = StringUtils.isNotBlank(cmd.getWeekKey()) + ? cmd.getWeekKey() + : getCurrentWeekKey(); + + // 2. 查询排行榜数据 + List progressList = queryRankData(cmd.getActivityId(), weekKey, cmd.getRankType(), cmd.getLimit()); + + if (progressList.isEmpty()) { + return new ArrayList<>(); + } + + // 3. 获取用户信息 + List userIds = progressList.stream() + .map(LotteryUserProgress::getUserId) + .collect(Collectors.toList()); + + Map userMap = getUserProfiles(userIds); + + // 4. 组装排行榜数据 + List rankList = new ArrayList<>(); + int rank = 1; + + for (LotteryUserProgress progress : progressList) { + UserProfileDTO user = userMap.get(progress.getUserId()); + if (user == null) { + continue; + } + + LotteryRankCO rankCO = new LotteryRankCO(); + rankCO.setRank(rank++); + rankCO.setUserId(progress.getUserId()); + rankCO.setAccount(user.getAccount()); + rankCO.setNickname(user.getUserNickname()); + rankCO.setAvatar(user.getUserAvatar()); + rankCO.setTotalAmount(progress.getTotalAmount()); + rankCO.setTotalDrawCount(progress.getTotalDrawCount()); + rankCO.setBigPrizeCount(progress.getBigPrizeCount()); + rankCO.setWeekKey(weekKey); + rankCO.setIsMe(currentUserId != null && currentUserId.equals(progress.getUserId())); + + rankList.add(rankCO); + } + + return rankList; + } + + /** + * 查询排行榜数据. + */ + private List queryRankData(Long activityId, String weekKey, String rankType, Integer limit) { + var query = lotteryUserProgressService.query() + .eq(LotteryUserProgress::getWeekKey, weekKey); + + // 如果指定了活动ID + if (activityId != null) { + query.eq(LotteryUserProgress::getActivityId, activityId); + } + + // 根据排行榜类型排序 + if ("DRAW_COUNT".equals(rankType)) { + query.orderByDesc(LotteryUserProgress::getTotalDrawCount); + } else { + // 默认按金额排序 + query.orderByDesc(LotteryUserProgress::getTotalAmount); + } + + // 限制数量 + query.last("LIMIT " + limit); + + return query.list(); + } + + /** + * 获取用户信息. + */ + private Map getUserProfiles(List userIds) { + try { + List users = userProfileClient.listByUserId(new HashSet<>(userIds)).getBody(); + if (users != null) { + return users.stream() + .collect(Collectors.toMap(UserProfileDTO::getId, user -> user, (a, b) -> a)); + } + } catch (Exception e) { + log.error("Failed to get user profiles", e); + } + return Map.of(); + } + + /** + * 获取当前周标识. + */ + private String getCurrentWeekKey() { + LocalDate now = LocalDate.now(); + int year = now.getYear(); + int weekOfYear = now.get(WeekFields.of(Locale.getDefault()).weekOfYear()); + return String.format("%dW%02d", year, weekOfYear); + } + +} diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestServiceImpl.java index 003238b9..b4f029a0 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestServiceImpl.java @@ -6,6 +6,7 @@ import com.red.circle.other.app.command.activity.LotteryActivityDetailQryExe; import com.red.circle.other.app.command.activity.LotteryActivityListQryExe; import com.red.circle.other.app.command.activity.LotteryDrawExe; import com.red.circle.other.app.command.activity.LotteryMultiDrawExe; +import com.red.circle.other.app.command.activity.LotteryRankQryExe; import com.red.circle.other.app.command.activity.LotteryRecordQryExe; import com.red.circle.other.app.command.activity.LotteryTicketCountQryExe; import com.red.circle.other.app.command.activity.LotteryTicketQryExe; @@ -13,10 +14,12 @@ import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO; +import com.red.circle.other.app.dto.clientobject.activity.LotteryRankCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO; import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd; +import com.red.circle.other.app.dto.cmd.activity.LotteryRankQryCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd; import java.util.List; import lombok.RequiredArgsConstructor; @@ -39,6 +42,7 @@ public class LotteryActivityRestServiceImpl implements LotteryActivityRestServic private final LotteryRecordQryExe lotteryRecordQryExe; private final LotteryTicketQryExe lotteryTicketQryExe; private final LotteryTicketCountQryExe lotteryTicketCountQryExe; + private final LotteryRankQryExe lotteryRankQryExe; @Override public List listValidActivities(AppExtCommand cmd) { @@ -75,4 +79,9 @@ public class LotteryActivityRestServiceImpl implements LotteryActivityRestServic return lotteryTicketCountQryExe.execute(cmd); } + @Override + public List getRankList(LotteryRankQryCmd cmd) { + return lotteryRankQryExe.execute(cmd); + } + } diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryRankCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryRankCO.java new file mode 100644 index 00000000..6b7f0b77 --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/activity/LotteryRankCO.java @@ -0,0 +1,70 @@ +package com.red.circle.other.app.dto.clientobject.activity; + +import com.red.circle.framework.dto.ClientObject; +import java.math.BigDecimal; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 抽奖排行榜CO. + * + * @author system + * @since 2025-10-21 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class LotteryRankCO extends ClientObject { + + /** + * 排名. + */ + private Integer rank; + + /** + * 用户ID. + */ + private Long userId; + + /** + * 用户账号. + */ + private String account; + + /** + * 用户昵称. + */ + private String nickname; + + /** + * 用户头像. + */ + private String avatar; + + /** + * 累计获得金额. + */ + private BigDecimal totalAmount; + + /** + * 抽奖次数. + */ + private Integer totalDrawCount; + + /** + * 大奖次数. + */ + private Integer bigPrizeCount; + + /** + * 周标识. + */ + private String weekKey; + + /** + * 是否是当前用户. + */ + private Boolean isMe; + +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/LotteryRankQryCmd.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/LotteryRankQryCmd.java new file mode 100644 index 00000000..9a227047 --- /dev/null +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/cmd/activity/LotteryRankQryCmd.java @@ -0,0 +1,39 @@ +package com.red.circle.other.app.dto.cmd.activity; + +import com.red.circle.common.business.dto.cmd.AppExtCommand; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.experimental.Accessors; + +/** + * 抽奖排行榜查询CMD. + * + * @author system + * @since 2025-10-21 + */ +@Data +@Accessors(chain = true) +@EqualsAndHashCode(callSuper = true) +public class LotteryRankQryCmd extends AppExtCommand { + + /** + * 活动ID(可选,不传则查询所有活动). + */ + private Long activityId; + + /** + * 周标识(可选,不传则查询当前周). + */ + private String weekKey; + + /** + * 排行榜类型:AMOUNT-按金额排序,DRAW_COUNT-按抽奖次数排序. + */ + private String rankType = "AMOUNT"; + + /** + * 查询数量(默认100). + */ + private Integer limit = 100; + +} diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestService.java index 6d2d352f..1b6bb4ae 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/activity/LotteryActivityRestService.java @@ -6,10 +6,12 @@ import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryActivityDetailCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryDrawResultCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryMultiDrawResultCO; +import com.red.circle.other.app.dto.clientobject.activity.LotteryRankCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryRecordCO; import com.red.circle.other.app.dto.clientobject.activity.LotteryTicketCO; import com.red.circle.other.app.dto.cmd.activity.LotteryDrawCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryMultiDrawCmd; +import com.red.circle.other.app.dto.cmd.activity.LotteryRankQryCmd; import com.red.circle.other.app.dto.cmd.activity.LotteryRecordQryCmd; import java.util.List; @@ -56,4 +58,9 @@ public interface LotteryActivityRestService { */ Integer getMyTicketCount(AppExtCommand cmd); + /** + * 查询排行榜. + */ + List getRankList(LotteryRankQryCmd cmd); + }