抽奖 新增排行榜

This commit is contained in:
tianfeng 2025-10-21 17:22:42 +08:00
parent 59841d6fc2
commit 93367e2874
6 changed files with 274 additions and 0 deletions

View File

@ -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<LotteryRankCO> getRankList(LotteryRankQryCmd cmd) {
return lotteryActivityRestService.getRankList(cmd);
}
}

View File

@ -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<LotteryRankCO> execute(LotteryRankQryCmd cmd) {
Long currentUserId = cmd.getReqUserId();
// 1. 确定周标识
String weekKey = StringUtils.isNotBlank(cmd.getWeekKey())
? cmd.getWeekKey()
: getCurrentWeekKey();
// 2. 查询排行榜数据
List<LotteryUserProgress> progressList = queryRankData(cmd.getActivityId(), weekKey, cmd.getRankType(), cmd.getLimit());
if (progressList.isEmpty()) {
return new ArrayList<>();
}
// 3. 获取用户信息
List<Long> userIds = progressList.stream()
.map(LotteryUserProgress::getUserId)
.collect(Collectors.toList());
Map<Long, UserProfileDTO> userMap = getUserProfiles(userIds);
// 4. 组装排行榜数据
List<LotteryRankCO> 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<LotteryUserProgress> 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<Long, UserProfileDTO> getUserProfiles(List<Long> userIds) {
try {
List<UserProfileDTO> 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);
}
}

View File

@ -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<LotteryActivityCO> listValidActivities(AppExtCommand cmd) {
@ -75,4 +79,9 @@ public class LotteryActivityRestServiceImpl implements LotteryActivityRestServic
return lotteryTicketCountQryExe.execute(cmd);
}
@Override
public List<LotteryRankCO> getRankList(LotteryRankQryCmd cmd) {
return lotteryRankQryExe.execute(cmd);
}
}

View File

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

View File

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

View File

@ -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<LotteryRankCO> getRankList(LotteryRankQryCmd cmd);
}