新增排行榜历史top1接口
This commit is contained in:
parent
0cd3a9eb83
commit
b3ae76ea45
@ -1,12 +1,15 @@
|
||||
package com.red.circle.other.adapter.app.activity;
|
||||
|
||||
import com.red.circle.framework.web.controller.BaseController;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.HistoricalTop1ListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.RankingListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
|
||||
import com.red.circle.other.app.dto.cmd.UserRankQueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.HistoricalTop1QueryCmd;
|
||||
import com.red.circle.other.app.service.activity.RankingActivityService;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
|
||||
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
@ -46,6 +49,20 @@ public class RankingActivityRestController extends BaseController {
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public RankingListCO getRankingList(@RequestBody @Validated RankingListQueryCmd cmd) {
|
||||
cmd.setCycleKey(ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString());
|
||||
return rankingActivityService.getRankingList(cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询历史Top1列表(周榜)
|
||||
*
|
||||
* 用途:查询指定活动的历史周榜Top1用户,最多返回近10周
|
||||
*
|
||||
* @param cmd 查询命令
|
||||
* @return 历史Top1列表
|
||||
*/
|
||||
@PostMapping("/historical-top1")
|
||||
public HistoricalTop1ListCO getHistoricalTop1List(@RequestBody @Validated HistoricalTop1QueryCmd cmd) {
|
||||
return rankingActivityService.getHistoricalTop1List(cmd);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,135 @@
|
||||
package com.red.circle.other.app.command.activity.query;
|
||||
|
||||
import com.red.circle.other.app.dto.clientobject.activity.HistoricalTop1ListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.HistoricalWeekTop1CO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.RankingActivityRecordCO;
|
||||
import com.red.circle.other.app.dto.cmd.activity.HistoricalTop1QueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
|
||||
import com.red.circle.other.app.service.activity.RankingActivityService;
|
||||
import com.red.circle.other.domain.ranking.RankingActivityType;
|
||||
import com.red.circle.other.domain.ranking.RankingCycleType;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.time.temporal.WeekFields;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 历史Top1查询执行器
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class HistoricalTop1QryExe {
|
||||
|
||||
private final RankingListQryExe rankingListQryExe;
|
||||
|
||||
/**
|
||||
* 执行查询
|
||||
*/
|
||||
public HistoricalTop1ListCO execute(HistoricalTop1QueryCmd cmd) {
|
||||
// 获取活动类型
|
||||
RankingActivityType activityType = RankingActivityType.getByCode(cmd.getActivityType());
|
||||
if (Objects.isNull(activityType)) {
|
||||
throw new IllegalArgumentException("无效的活动类型");
|
||||
}
|
||||
|
||||
// 构建结果
|
||||
HistoricalTop1ListCO result = new HistoricalTop1ListCO();
|
||||
result.setActivityType(activityType.getCode());
|
||||
result.setActivityTypeName(activityType.getName());
|
||||
|
||||
// 查询最近10周的Top1
|
||||
List<HistoricalWeekTop1CO> historicalList = new ArrayList<>();
|
||||
for (int i = 0; i < 5; i++) {
|
||||
// 获取往前推i周的周一cycleKey
|
||||
String cycleKey = getWeekMondayCycleKey(i);
|
||||
|
||||
// 查询该周的Top1
|
||||
RankingListQueryCmd queryCmd = new RankingListQueryCmd();
|
||||
queryCmd.setActivityType(cmd.getActivityType());
|
||||
queryCmd.setCycleType(RankingCycleType.WEEKLY.getCode());
|
||||
queryCmd.setCycleKey(cycleKey);
|
||||
queryCmd.setUserSex(cmd.getUserSex());
|
||||
queryCmd.setTopN(1); // 只查询Top1
|
||||
queryCmd.setReqSysOrigin(cmd.getReqSysOrigin());
|
||||
queryCmd.setIncludeCurrentUser(false); // 不需要查询当前用户排名
|
||||
|
||||
try {
|
||||
var rankingList = rankingListQryExe.execute(queryCmd);
|
||||
|
||||
// 如果有数据,添加到结果中
|
||||
if (Objects.nonNull(rankingList) &&
|
||||
Objects.nonNull(rankingList.getRankingList()) &&
|
||||
!rankingList.getRankingList().isEmpty()) {
|
||||
|
||||
HistoricalWeekTop1CO weekTop1 = new HistoricalWeekTop1CO();
|
||||
weekTop1.setCycleKey(cycleKey);
|
||||
weekTop1.setCycleDisplay(generateCycleDisplay(cycleKey));
|
||||
weekTop1.setTopUser(rankingList.getRankingList().get(0));
|
||||
historicalList.add(weekTop1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.warn("查询历史Top1失败, cycleKey={}", cycleKey, e);
|
||||
}
|
||||
}
|
||||
|
||||
result.setHistoricalList(historicalList);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取往前推N周的周一cycleKey
|
||||
*
|
||||
* @param weeksAgo 往前推的周数(0表示本周)
|
||||
* @return cycleKey(格式:yyyyMMdd)
|
||||
*/
|
||||
private String getWeekMondayCycleKey(int weeksAgo) {
|
||||
// 使用亚洲/利雅得时区
|
||||
ZoneId riyadhZone = ZoneId.of("Asia/Riyadh");
|
||||
ZonedDateTime now = ZonedDateTime.now(riyadhZone);
|
||||
|
||||
// 获取本周周一
|
||||
LocalDate monday = now.toLocalDate().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
|
||||
|
||||
// 往前推N周
|
||||
if (weeksAgo > 0) {
|
||||
monday = monday.minusWeeks(weeksAgo);
|
||||
}
|
||||
|
||||
// 格式化为yyyyMMdd
|
||||
return monday.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成周期显示文本
|
||||
*
|
||||
* @param cycleKey 周期标识(yyyyMMdd格式)
|
||||
* @return 周期显示文本(示例:2025年第1周)
|
||||
*/
|
||||
private String generateCycleDisplay(String cycleKey) {
|
||||
try {
|
||||
LocalDate date = LocalDate.parse(cycleKey, DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
int year = date.getYear();
|
||||
|
||||
// 获取周数(ISO 8601标准)
|
||||
WeekFields weekFields = WeekFields.of(Locale.getDefault());
|
||||
int weekOfYear = date.get(weekFields.weekOfWeekBasedYear());
|
||||
|
||||
return String.format("%d年第%d周", year, weekOfYear);
|
||||
} catch (Exception e) {
|
||||
log.warn("生成周期显示文本失败, cycleKey={}", cycleKey, e);
|
||||
return cycleKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -50,9 +50,9 @@ public class RankingListQryExe {
|
||||
// 查询排行榜列表
|
||||
List<RankingActivityRecord> records = rankingActivityGateway.getRankingList(
|
||||
cmd.getReqSysOrigin().getOrigin(),
|
||||
activityType,
|
||||
activityType,
|
||||
cycleType,
|
||||
ZonedDateTimeAsiaRiyadhUtils.nowWeekMondayToInt().toString(),
|
||||
cmd.getCycleKey(),
|
||||
null,
|
||||
cmd.getTopN()
|
||||
);
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package com.red.circle.other.app.service.activity;
|
||||
|
||||
import com.red.circle.other.app.command.activity.query.HistoricalTop1QryExe;
|
||||
import com.red.circle.other.app.command.activity.query.RankingDataAccumulateCmdExe;
|
||||
import com.red.circle.other.app.command.activity.query.RankingListQryExe;
|
||||
import com.red.circle.other.app.command.activity.query.UserRankQryExe;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.HistoricalTop1ListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.RankingListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
|
||||
import com.red.circle.other.app.dto.cmd.UserRankQueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.HistoricalTop1QueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -24,6 +27,7 @@ public class RankingActivityServiceImpl implements RankingActivityService {
|
||||
private final RankingDataAccumulateCmdExe rankingDataAccumulateCmdExe;
|
||||
private final RankingListQryExe rankingListQryExe;
|
||||
private final UserRankQryExe userRankQryExe;
|
||||
private final HistoricalTop1QryExe historicalTop1QryExe;
|
||||
|
||||
@Override
|
||||
public Boolean accumulateRankingData(RankingDataUpdateCmd cmd) {
|
||||
@ -39,4 +43,9 @@ public class RankingActivityServiceImpl implements RankingActivityService {
|
||||
public UserRankInfoCO getUserRank(UserRankQueryCmd cmd) {
|
||||
return userRankQryExe.execute(cmd);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HistoricalTop1ListCO getHistoricalTop1List(HistoricalTop1QueryCmd cmd) {
|
||||
return historicalTop1QryExe.execute(cmd);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,30 @@
|
||||
package com.red.circle.other.app.dto.clientobject.activity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 历史Top1列表 CO
|
||||
*/
|
||||
@Data
|
||||
public class HistoricalTop1ListCO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 活动类型编码
|
||||
*/
|
||||
private Integer activityType;
|
||||
|
||||
/**
|
||||
* 活动类型名称
|
||||
*/
|
||||
private String activityTypeName;
|
||||
|
||||
/**
|
||||
* 历史周榜Top1列表(最近10周)
|
||||
*/
|
||||
private List<HistoricalWeekTop1CO> historicalList;
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.red.circle.other.app.dto.clientobject.activity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 历史周榜Top1记录 CO
|
||||
*/
|
||||
@Data
|
||||
public class HistoricalWeekTop1CO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 周期标识(格式:yyyyMMdd,周一日期)
|
||||
*/
|
||||
private String cycleKey;
|
||||
|
||||
/**
|
||||
* 周期显示文本(示例:2025年第1周)
|
||||
*/
|
||||
private String cycleDisplay;
|
||||
|
||||
/**
|
||||
* Top1用户信息
|
||||
*/
|
||||
private RankingActivityRecordCO topUser;
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
package com.red.circle.other.app.dto.cmd.activity;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 历史Top1查询命令
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class HistoricalTop1QueryCmd extends AppExtCommand {
|
||||
|
||||
/**
|
||||
* 活动类型
|
||||
*
|
||||
* RankingActivityType
|
||||
*/
|
||||
@NotNull(message = "活动类型不能为空")
|
||||
private Integer activityType;
|
||||
|
||||
/**
|
||||
* 用户性别筛选
|
||||
*
|
||||
* 0-女, 1-男, null-全部
|
||||
*/
|
||||
private Integer userSex;
|
||||
}
|
||||
@ -1,8 +1,10 @@
|
||||
package com.red.circle.other.app.service.activity;
|
||||
|
||||
import com.red.circle.other.app.dto.clientobject.activity.HistoricalTop1ListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.RankingListCO;
|
||||
import com.red.circle.other.app.dto.clientobject.activity.UserRankInfoCO;
|
||||
import com.red.circle.other.app.dto.cmd.UserRankQueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.HistoricalTop1QueryCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingDataUpdateCmd;
|
||||
import com.red.circle.other.app.dto.cmd.activity.RankingListQueryCmd;
|
||||
|
||||
@ -34,4 +36,12 @@ public interface RankingActivityService {
|
||||
* @return 用户排名信息
|
||||
*/
|
||||
UserRankInfoCO getUserRank(UserRankQueryCmd cmd);
|
||||
|
||||
/**
|
||||
* 查询历史Top1列表(周榜)
|
||||
*
|
||||
* @param cmd 查询命令
|
||||
* @return 历史Top1列表(最近10周)
|
||||
*/
|
||||
HistoricalTop1ListCO getHistoricalTop1List(HistoricalTop1QueryCmd cmd);
|
||||
}
|
||||
@ -85,7 +85,7 @@ public class PropCouponGatewayImpl implements PropCouponGateway {
|
||||
if (status != null) {
|
||||
wrapper.eq(PropCouponDO::getStatus, status.getCode());
|
||||
}
|
||||
wrapper.lt(PropCouponDO::getExpireTime, LocalDateTime.now());
|
||||
wrapper.gt(PropCouponDO::getExpireTime, LocalDateTime.now());
|
||||
wrapper.orderByDesc(PropCouponDO::getCreateTime);
|
||||
|
||||
Page<PropCouponDO> page = new Page<>(pageNo, pageSize);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user