新增历史top1接口

This commit is contained in:
tianfeng 2025-09-12 18:37:35 +08:00
parent 1b18c15a0c
commit 5bb530f009
10 changed files with 286 additions and 11 deletions

View File

@ -4,9 +4,12 @@ import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.dto.ResultResponse;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import com.red.circle.other.inner.model.dto.sys.SysActivityCountDTO;
import com.red.circle.other.inner.model.dto.sys.WeekKingQueenCountVO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.List;
/**
* 国王和王后排行
*/
@ -22,4 +25,7 @@ public interface WeekKingQueenClientApi {
@RequestParam("current") Long current,
@RequestParam("size") Long size);
@GetMapping("/history")
ResultResponse<List<WeekKingQueenCountVO>> listLastThreeMonthsTop1(String sysOrigin);
}

View File

@ -0,0 +1,72 @@
package com.red.circle.other.inner.model.dto.sys;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* 每周king&queen统计.
*/
@Data
public class WeekKingQueenCountVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 记录id.
*/
@JsonSerialize(using = ToStringSerializer.class)
String id;
/**
* 归属平台.
*/
String sysOrigin;
/**
* 用户id.
*/
@JsonSerialize(using = ToStringSerializer.class)
Long userId;
/**
* 用户性别:0 1 .
*/
private Integer userSex;
/**
* 排名
*/
Integer rank;
/**
* 类型.
*/
KingQueenType type;
/**
* 分组.
*/
String group;
/**
* 数量.
*/
@JsonSerialize(using = ToStringSerializer.class)
Long quantity;
/**
* 创建时间.
*/
Timestamp createTime;
/**
* 过期时间.
*/
Timestamp expiredTime;
}

View File

@ -31,14 +31,7 @@ import com.red.circle.other.inner.enums.activity.KingQueenType;
import com.red.circle.other.inner.model.cmd.activity.SendActivityRewardCmd;
import com.red.circle.other.inner.model.dto.material.GiftConfigDTO;
import com.red.circle.other.inner.model.dto.material.PropsActivityRewardConfigInfoDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityAwardRankUserDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityConfigDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityConfigRewardsDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityConfigRewardsInfoDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityTemplateDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityTemplateValueDTO;
import com.red.circle.other.inner.model.dto.sys.SysActivityCountDTO;
import com.red.circle.other.inner.model.dto.sys.SysActivityCountType;
import com.red.circle.other.inner.model.dto.sys.*;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;

View File

@ -10,6 +10,8 @@ import com.red.circle.console.app.dto.cmd.app.sys.ActivityTemplateConsoleQryCmd;
import com.red.circle.other.inner.model.dto.sys.ActivityConfigDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityTemplateDTO;
import com.red.circle.other.inner.model.dto.sys.ActivityTemplateValueDTO;
import com.red.circle.other.inner.model.dto.sys.WeekKingQueenCountVO;
import java.util.List;
/**

View File

@ -5,11 +5,21 @@ import com.red.circle.framework.dto.PageResult;
import com.red.circle.framework.web.controller.BaseController;
import com.red.circle.other.app.dto.clientobject.activity.UserCharmWealthContributeCO;
import com.red.circle.other.app.dto.clientobject.activity.UserRankCO;
import com.red.circle.other.app.dto.clientobject.activity.WeekKingQueenHistoryVO;
import com.red.circle.other.app.dto.clientobject.sys.ActivityConfigVO;
import com.red.circle.other.app.dto.cmd.activity.WeekKingQueenRankingQueryCmd;
import com.red.circle.other.app.service.activity.WeekKingQueenService;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
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.activity.WeekKingQueenCount;
import com.red.circle.other.infra.database.mongo.service.activity.WeekKingQueenCountService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
@ -30,6 +40,8 @@ import org.springframework.web.bind.annotation.RestController;
public class WeekKingQueenController extends BaseController {
private final WeekKingQueenService weekKingQueenService;
private final WeekKingQueenCountService weekKingQueenCountService;
private final UserProfileGateway userProfileGateway;
/**
* 排行榜.
@ -44,6 +56,30 @@ public class WeekKingQueenController extends BaseController {
return weekKingQueenService.listRanking(cmd);
}
/**
* 历史top1
*/
@GetMapping("/history")
public List<WeekKingQueenHistoryVO> history(AppExtCommand cmd) {
List<WeekKingQueenCount> top1List = weekKingQueenCountService.listLastThreeMonthsTop1(cmd.getReqSysOrigin().getOrigin());
Set<Long> userIds = top1List.stream().map(WeekKingQueenCount::getUserId).collect(Collectors.toSet());
Map<Long, UserProfile> profileMap = userProfileGateway.mapByUserIds(userIds);
return top1List.stream().map(e -> {
WeekKingQueenHistoryVO weekKingQueenHistoryVO = new WeekKingQueenHistoryVO();
BeanUtils.copyProperties(e, weekKingQueenHistoryVO);
UserProfile userProfile = profileMap.get(e.getUserId());
if (userProfile != null) {
weekKingQueenHistoryVO.setAccount(userProfile.getAccount());
weekKingQueenHistoryVO.setUserAvatar(userProfile.getUserAvatar());
weekKingQueenHistoryVO.setUserNickname(userProfile.getUserNickname());
}
return weekKingQueenHistoryVO;
}).collect(Collectors.toList());
}
/**
* 获取有效活动
*/

View File

@ -0,0 +1,88 @@
package com.red.circle.other.app.dto.clientobject.activity;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* 每周king&queen统计.
*/
@Data
public class WeekKingQueenHistoryVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 记录id.
*/
@JsonSerialize(using = ToStringSerializer.class)
String id;
/**
* 归属平台.
*/
String sysOrigin;
/**
* 账号.
*/
private String account;
/**
* 头像.
*/
private String userAvatar;
/**
* 用户昵称.
*/
private String userNickname;
/**
* 用户id.
*/
@JsonSerialize(using = ToStringSerializer.class)
Long userId;
/**
* 用户性别:0 1 .
*/
private Integer userSex;
/**
* 排名
*/
Integer rank;
/**
* 类型.
*/
KingQueenType type;
/**
* 分组.
*/
String group;
/**
* 数量.
*/
@JsonSerialize(using = ToStringSerializer.class)
Long quantity;
/**
* 创建时间.
*/
Timestamp createTime;
/**
* 过期时间.
*/
Timestamp expiredTime;
}

View File

@ -47,7 +47,7 @@ public class WeekKingQueenCount implements Serializable {
/**
* 用户性别:0 1 .
*/
private Integer userSex;
Integer userSex;
/**
* 排名

View File

@ -46,6 +46,11 @@ public interface WeekKingQueenCountService {
Page<WeekKingQueenCount> pageWeekQuery(String sysOrigin, KingQueenType type, String group,
Long current, Long size);
/**
* 历史top1
*/
List<WeekKingQueenCount> listLastThreeMonthsTop1(String sysOrigin);
/**
* 分页查询每周top (支持性别过滤)
*/

View File

@ -12,12 +12,19 @@ import com.red.circle.tool.core.date.DateFormatConstant;
import com.red.circle.tool.core.date.TimestampUtils;
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.time.DayOfWeek;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.domain.*;
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;
@ -167,6 +174,60 @@ public class WeekKingQueenCountServiceImpl implements WeekKingQueenCountService
return new PageImpl<>(results, pageRequest, total);
}
public List<WeekKingQueenCount> listLastThreeMonthsTop1(String sysOrigin) {
// 获取近三个月的分组列表比如 20250601 ~ 20250901
List<String> lastThreeMonthGroups = getLastThreeMonthGroups(); // 自己实现返回 List<String>格式如 "20250818"
List<WeekKingQueenCount> top1List = new ArrayList<>();
for (KingQueenType type : Arrays.asList(KingQueenType.WEALTH, KingQueenType.CHARM)) {
// 聚合查询每周 Top1
Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match(
Criteria.where("sysOrigin").is(sysOrigin)
.and("type").is(type)
.and("group").in(lastThreeMonthGroups)
),
Aggregation.sort(Sort.by(Sort.Order.desc("quantity"))), // 按数量降序
Aggregation.group("group") // 按周分组
.first(Aggregation.ROOT).as("top1"), // 每组取第一个文档
Aggregation.replaceRoot("top1") // 展平
);
AggregationResults<WeekKingQueenCount> results = mongoTemplate.aggregate(
aggregation, "week_king_queen_count", WeekKingQueenCount.class
);
top1List.addAll(results.getMappedResults());
}
// 给结果赋值 rank=1
top1List.forEach(w -> w.setRank(1));
// 日期倒排
top1List.sort(Comparator.comparing(WeekKingQueenCount::getGroup).reversed());
return top1List;
}
public List<String> getLastThreeMonthGroups() {
List<String> groups = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
LocalDate today = LocalDate.now();
LocalDate threeMonthsAgo = today.minusMonths(3);
// 调整到三个月前的周一
LocalDate current = threeMonthsAgo.with(DayOfWeek.MONDAY);
// 循环每周的周一
while (!current.isAfter(today)) {
groups.add(current.format(formatter));
current = current.plusWeeks(1);
}
return groups;
}
/**
* 根据周类型获取对应的日期组

View File

@ -8,10 +8,12 @@ import com.red.circle.other.inner.endpoint.user.user.api.WeekKingQueenClientApi;
import com.red.circle.other.inner.enums.activity.KingQueenType;
import com.red.circle.other.inner.model.dto.sys.SysActivityCountDTO;
import com.red.circle.other.inner.model.dto.sys.SysActivityCountType;
import com.red.circle.other.inner.model.dto.sys.WeekKingQueenCountVO;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
@ -66,6 +68,16 @@ public class WeekKingQueenClientEndpoint implements WeekKingQueenClientApi {
throw new RuntimeException("查询排行榜失败", e);
}
}
public ResultResponse<List<WeekKingQueenCountVO>> listLastThreeMonthsTop1(String sysOrigin) {
List<WeekKingQueenCountVO> list = new ArrayList<>();
weekKingQueenCountService.listLastThreeMonthsTop1(sysOrigin).forEach(e -> {
WeekKingQueenCountVO weekKingQueenCountVO = new WeekKingQueenCountVO();
BeanUtils.copyProperties(e, weekKingQueenCountVO);
list.add(weekKingQueenCountVO);
});
return ResultResponse.success(list);
}
/**
* 转换WeekKingQueenCount为SysActivityCountDTO