房间日奖励-首页-增加奖励状态

This commit is contained in:
2025-09-17 16:04:40 +08:00
parent e6c3d4dd1a
commit cf4da23bca
8 changed files with 118 additions and 36 deletions

View File

@@ -1473,6 +1473,8 @@ public enum RedisKey {
v5pay_lock, //v5pay支付锁
game_usd_recv_lock, //游戏薪资锁
room_day_send_rank_reward_home_flag
;
public String getKey() {

View File

@@ -12,7 +12,7 @@ public class RoomDaySendRankRoomRecord {
/**
* 统计日期
*/
private Date statDate;
private String statDate;
/**
* 房间ID

View File

@@ -12,7 +12,7 @@ public class RoomDaySendRankUserRecord {
/**
* 统计日期
*/
private Date statDate;
private String statDate;
/**
* 房间ID

View File

@@ -12,7 +12,10 @@ import java.util.List;
@Data
@ApiModel("房间日流水奖励首页信息")
public class RoomDaySendRankRewardHomeVo {
@ApiModelProperty("是否今天内第一次访问")
private Boolean isFirstTimeVisit;
@ApiModelProperty("房间信息")
private ActivityUserVo roomInfo;
@@ -60,10 +63,19 @@ public class RoomDaySendRankRewardHomeVo {
private Integer ranking;
@ApiModelProperty("得分")
private BigDecimal score;
@ApiModelProperty("第10名得分")
private BigDecimal theTenScore;
@ApiModelProperty("房主奖励")
private Long ownerReward;
@ApiModelProperty("房主奖励状态")
private Byte ownerRewardStatus;
@ApiModelProperty("贡献奖励")
private Long myReward;
@ApiModelProperty("贡献奖励状态")
private Byte myRewardStatus;
}

View File

@@ -1,18 +1,18 @@
package com.accompany.business.service.room;
import com.accompany.business.common.vo.ActivityUserVo;
import com.accompany.business.model.room.RoomDaySendRankReward;
import com.accompany.business.model.room.RoomDaySendRankRoomRecord;
import com.accompany.business.model.room.RoomDaySendRankUserRecord;
import com.accompany.business.service.SendSysMsgService;
import com.accompany.business.service.purse.UserPurseService;
import com.accompany.business.service.rank.room.RoomDayRankService;
import com.accompany.business.service.rank.room.SendRoomDayRankService;
import com.accompany.business.service.user.UsersService;
import com.accompany.business.vo.room.RoomDaySendRankRewardHomeVo;
import com.accompany.business.vo.room.RoomDaySendRankRewardRecordVo;
import com.accompany.common.constant.Constant;
import com.accompany.common.enums.RedisZSetEnum;
import com.accompany.common.model.PageReq;
import com.accompany.common.redis.RedisKey;
import com.accompany.common.status.BusiStatus;
import com.accompany.common.utils.DateTimeUtil;
import com.accompany.core.base.SpringContextHolder;
@@ -26,6 +26,8 @@ import com.accompany.core.util.I18NMessageSourceUtil;
import com.accompany.core.util.PartitionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.redisson.api.RSet;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
@@ -33,6 +35,7 @@ import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.Duration;
import java.time.ZonedDateTime;
import java.util.*;
@@ -44,7 +47,7 @@ public class RoomDaySendRankRewardManager {
@Autowired
private RoomService roomService;
@Autowired
private RoomDayRankService roomDayRankService;
private SendRoomDayRankService sendRoomDayRankService;
@Autowired
private RoomDaySendRankRewardService rewardService;
@Autowired
@@ -55,6 +58,8 @@ public class RoomDaySendRankRewardManager {
private UserPurseService userPurseService;
@Autowired
private SendSysMsgService sendSysMsgService;
@Autowired
private RedissonClient redissonClient;
/**
* 获取房间日流水奖励首页信息
@@ -84,6 +89,15 @@ public class RoomDaySendRankRewardManager {
throw new ServiceException(BusiStatus.PARTITION_ERROR);
}
ZonedDateTime zdt = DateTimeUtil.getDateTimeByZoneId(partitionEnum.getZoneId());
String zdtDate = zdt.format(DateTimeUtil.dateFormatter);
RSet<Long> flagSet = redissonClient.getSet(RedisKey.room_day_send_rank_reward_home_flag.getKey(u.getPartitionId().toString(), zdtDate));
boolean isFirstTimeVisit = flagSet.tryAdd(uid);
vo.setIsFirstTimeVisit(isFirstTimeVisit);
if (isFirstTimeVisit){
flagSet.expire(Duration.ofDays(3));
}
Users owner = usersService.getNotNullUsersByUid(room.getUid());
ActivityUserVo roomInfo = new ActivityUserVo(room.getUid(), owner.getErbanNo(), room.getTitle(), room.getAvatar());
@@ -93,7 +107,7 @@ public class RoomDaySendRankRewardManager {
Date todayTime = new Date();
Date statTime = Boolean.TRUE.equals(isToday)? todayTime: DateTimeUtil.addDays(todayTime, -1);
Set<Map<String, Object>> rankList = roomDayRankService.getRank(statTime, roomUid, 1L, -1L, room.getPartitionId());
Set<Map<String, Object>> rankList = sendRoomDayRankService.getRank(statTime, roomUid, 0L, -1L, room.getPartitionId());
BigDecimal roomSerialValue = rankList.stream().map(entry-> new BigDecimal(entry.get(RedisZSetEnum.score.name()).toString())).reduce(BigDecimal.ZERO, BigDecimal::add);
RoomDaySendRankRewardHomeVo.RewardInfoVo rewardInfoVo = rewardService.buildBySerialValue(roomSerialValue);
@@ -105,7 +119,7 @@ public class RoomDaySendRankRewardManager {
vo.setTop10RankList(top10RankVoList);
// 4. 获取我的排名信息使用ActivityRankItemVo
RoomDaySendRankRewardHomeVo.RankItemVo myRank = buildMyRank(u, roomUid, top10RankList, rewardInfoVo);
RoomDaySendRankRewardHomeVo.RankItemVo myRank = buildMyRank(u, roomUid, rankList, rewardInfoVo, isToday);
vo.setMyRank(myRank);
return vo;
@@ -154,41 +168,73 @@ public class RoomDaySendRankRewardManager {
return voList;
}
private RoomDaySendRankRewardHomeVo.RankItemVo buildMyRank(Users u, Long roomUid, List<Map<String, Object>> top10RankList,
RoomDaySendRankRewardHomeVo.RewardInfoVo rewardInfoVo) {
private RoomDaySendRankRewardHomeVo.RankItemVo buildMyRank(Users u, Long roomUid, Set<Map<String, Object>> rankList,
RoomDaySendRankRewardHomeVo.RewardInfoVo rewardInfoVo, Boolean isToday) {
RoomDaySendRankRewardHomeVo.RankItemVo vo = new RoomDaySendRankRewardHomeVo.RankItemVo();
vo.setUid(u.getUid());
vo.setErbanNo(u.getErbanNo());
vo.setNick(u.getNick());
vo.setAvatar(u.getAvatar());
vo.setRanking(0);
vo.setScore(BigDecimal.ZERO);
//vo.setOwnerReward(0L);
vo.setMyReward(0L);
//vo.setMyReward(0L);
BigDecimal theTenScore = BigDecimal.ZERO;
BigDecimal top10SerialValue = BigDecimal.ZERO;
int rank = 1;
for (Map<String, Object> entry: top10RankList){
for (Map<String, Object> entry: rankList){
Long uid = Long.parseLong(entry.get(RedisZSetEnum.member.name()).toString());
BigDecimal score = new BigDecimal(entry.get(RedisZSetEnum.score.name()).toString());
if (rank <= 10){
theTenScore = score;
top10SerialValue = top10SerialValue.add(score);
}
if (uid.equals(u.getUid())){
vo.setRanking(rank);
vo.setScore(score);
break;
}
rank++;
top10SerialValue = top10SerialValue.add(score);
if (rank <= 10){
rank++;
}
}
vo.setTheTenScore(theTenScore);
if (u.getUid().equals(roomUid)){
vo.setOwnerReward(rewardInfoVo.getOwnerReward());
if (isToday){
vo.setOwnerRewardStatus(rewardInfoVo.getOwnerReward()>0L? Constant.StatusV2.invalid: Constant.StatusV2.delete);
} else {
RoomDaySendRankUserRecord ownerRewardRecord = userRecordService.getUserRecordByType(roomUid, u.getPartitionId(), u.getUid(), Constant.status.delete);
vo.setOwnerRewardStatus(null == ownerRewardRecord? Constant.StatusV2.delete: ownerRewardRecord.getUserReceiveReward() > 0L ? Constant.status.invalid: Constant.status.valid);
}
}
if (vo.getRanking() > 0 && rewardInfoVo.getTopTenReward() > 0L){
BigDecimal ratio = vo.getScore().divide(top10SerialValue, 2, RoundingMode.HALF_DOWN);
long myReward = BigDecimal.valueOf(rewardInfoVo.getTopTenReward()).divide(ratio, 0, RoundingMode.HALF_DOWN).longValue();
if (vo.getRanking() == 0){
vo.setOwnerReward(0L);
vo.setOwnerRewardStatus(Constant.StatusV2.delete);
} else {
long myReward = 0L;
if (top10SerialValue.compareTo(BigDecimal.ZERO) > 0 && rewardInfoVo.getTopTenReward() > 0L){
BigDecimal ratio = vo.getScore().divide(top10SerialValue, 2, RoundingMode.HALF_DOWN);
myReward = BigDecimal.valueOf(rewardInfoVo.getTopTenReward()).divide(ratio, 0, RoundingMode.HALF_DOWN).longValue();
}
vo.setMyReward(myReward);
if (isToday){
vo.setMyRewardStatus(myReward > 0L? Constant.StatusV2.invalid: Constant.StatusV2.delete);
} else {
RoomDaySendRankUserRecord myRewardRecord = userRecordService.getUserRecordByType(roomUid, u.getPartitionId(), u.getUid(), Constant.status.valid);
vo.setMyRewardStatus(null == myRewardRecord? Constant.StatusV2.delete: myRewardRecord.getUserReceiveReward() > 0L ? Constant.status.invalid: Constant.status.valid);
}
}
return vo;
@@ -315,9 +361,11 @@ public class RoomDaySendRankRewardManager {
/**
* 计算每日奖励(供定时任务调用)
*/
public void calculateDailyRewards() {
public void calculateDailyRewards(Date date) {
// 具体业务逻辑由您手动实现
// 这里只提供接口供定时任务调用
}
}

View File

@@ -8,7 +8,9 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
/**
* <p>
@@ -43,22 +45,30 @@ public class RoomDaySendRankRewardService extends ServiceImpl<RoomDaySendRankRew
return vo;
}
List<RoomDaySendRankReward> levelList = rewardList.stream().filter(reward -> roomSerialValue.compareTo(reward.getSerialValue()) >= 0).limit(2).toList();
if (CollectionUtils.isEmpty(levelList)){
RoomDaySendRankReward nextLevel = rewardList.get(0);
vo.setNextLevel(nextLevel.getName());
vo.setNextLevelLimit(nextLevel.getSerialValue());
} else {
RoomDaySendRankReward curLevel = levelList.get(0);
vo.setCurLevel(curLevel.getName());
vo.setOwnerReward(curLevel.getRoomOwnerReward());
vo.setTopTenReward(curLevel.getTopTenTotalReward());
RoomDaySendRankReward nextLevel = levelList.get(levelList.size() - 1);
vo.setNextLevel(nextLevel.getName());
vo.setNextLevelLimit(nextLevel.getSerialValue());
Optional<RoomDaySendRankReward> curLevelOptional = rewardList.stream()
.filter(reward -> roomSerialValue.compareTo(reward.getSerialValue()) >= 0)
.max(Comparator.comparing(RoomDaySendRankReward::getSerialValue));
if (curLevelOptional.isEmpty()){
return vo;
}
RoomDaySendRankReward curLevel = curLevelOptional.get();
vo.setCurLevel(curLevel.getName());
vo.setOwnerReward(curLevel.getRoomOwnerReward());
vo.setTopTenReward(curLevel.getTopTenTotalReward());
Optional<RoomDaySendRankReward> nextLevelOptional = rewardList.stream().filter(reward -> reward.getSerialValue().compareTo(curLevel.getSerialValue()) > 0).min(Comparator.comparing(RoomDaySendRankReward::getSerialValue));
if (nextLevelOptional.isEmpty()){
vo.setNextLevel(curLevel.getName());
vo.setNextLevelLimit(curLevel.getSerialValue());
vo.setNextLevelReward(curLevel.getRoomOwnerReward() + curLevel.getTopTenTotalReward());
return vo;
}
RoomDaySendRankReward nextLevel = nextLevelOptional.get();
vo.setNextLevel(nextLevel.getName());
vo.setNextLevelLimit(nextLevel.getSerialValue());
vo.setNextLevelReward(nextLevel.getRoomOwnerReward() + nextLevel.getTopTenTotalReward());
return vo;
}

View File

@@ -8,5 +8,12 @@ import org.springframework.stereotype.Service;
@Service
public class RoomDaySendRankUserRecordService extends ServiceImpl<RoomDaySendRankUserRecordMapper, RoomDaySendRankUserRecord> {
// 根据业务需要添加自定义方法
public RoomDaySendRankUserRecord getUserRecordByType(Long roomUid, Integer partitionId, Long uid, Byte type){
return lambdaQuery().eq(RoomDaySendRankUserRecord::getRoomUid, roomUid)
.eq(RoomDaySendRankUserRecord::getPartitionId, partitionId)
.eq(RoomDaySendRankUserRecord::getUid, uid)
.eq(RoomDaySendRankUserRecord::getType, type)
.one();
}
}

View File

@@ -5,6 +5,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.Date;
@Component
public class RoomDaySendRankRewardTask {
@@ -14,11 +16,12 @@ public class RoomDaySendRankRewardTask {
/**
* 每天利雅得时间零点执行奖励计算任务
* 利雅得时间比UTC时间快3小时
* Cron表达式: 0 0 0 * * ? (UTC时间21:00即利雅得时间00:00)
* Cron表达式: 0 0 1 * * ? (UTC时间21:00即利雅得时间00:00)
*/
@Scheduled(cron = "0 0 21 * * ?", zone = "Asia/Riyadh")
@Scheduled(cron = "0 0 1 * * ?", zone = "Asia/Riyadh")
public void calculateDailyRewards() {
// 调用Manager处理每日奖励计算
roomDaySendRankRewardManager.calculateDailyRewards();
Date date = new Date();
roomDaySendRankRewardManager.calculateDailyRewards(date);
}
}