fix(other): auto send room weekly reward packets
This commit is contained in:
parent
bb83f2026b
commit
2279f5d640
@ -12,7 +12,6 @@ import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
|
||||
import com.red.circle.other.app.dto.clientobject.RoomRedPacketCO;
|
||||
import com.red.circle.other.app.dto.cmd.SendRoomRedPacketCmd;
|
||||
import com.red.circle.other.app.dto.cmd.task.RoomDailyTaskProgressUpdateCmd;
|
||||
import com.red.circle.other.app.enums.RoomRewardLevelEnum;
|
||||
import com.red.circle.other.app.service.task.RoomDailyTaskProgressService;
|
||||
import com.red.circle.other.app.util.OfficialNoticeUtils;
|
||||
import com.red.circle.other.domain.gateway.RoomRedPacketGateway;
|
||||
@ -23,15 +22,12 @@ import com.red.circle.other.domain.redpacket.RoomRedPacketSourceType;
|
||||
import com.red.circle.other.domain.redpacket.RoomRedPacketStatus;
|
||||
import com.red.circle.other.domain.redpacket.RoomRedPacketType;
|
||||
import com.red.circle.other.infra.database.cache.service.other.RoomRedPacketCacheService;
|
||||
import com.red.circle.other.infra.database.mongo.entity.activity.RoomContributionActivityCount;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
|
||||
import com.red.circle.other.infra.database.mongo.service.activity.RoomContributionActivityCountService;
|
||||
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
|
||||
import com.red.circle.other.inner.asserts.OtherErrorCode;
|
||||
import com.red.circle.other.inner.asserts.RoomErrorCode;
|
||||
import com.red.circle.other.inner.enums.task.RoomDailyTaskCode;
|
||||
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
|
||||
import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
|
||||
import com.red.circle.tool.core.sequence.IdWorkerUtils;
|
||||
import com.red.circle.tool.core.tuple.PennyAmount;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
@ -42,10 +38,11 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
@ -159,26 +156,7 @@ public class SendRoomRedPacketCmdExe {
|
||||
RoomRedPacket redPacket = buildRedPacket(cmd, systemUserId, packetId, expireTime, RoomRedPacketSourceType.PLATFORM);
|
||||
roomRedPacketGateway.save(redPacket);
|
||||
|
||||
// 查询上周数据
|
||||
deductRoomContribution(cmd.getRoomId(), cmd.getTotalAmount());
|
||||
|
||||
// 预生成随机金额列表(拼手气红包)
|
||||
List<Long> amounts = generateRandomAmounts(cmd.getTotalAmount(), cmd.getTotalCount());
|
||||
long expireSeconds = cmd.getExpireMinutes() * 60;
|
||||
roomRedPacketCacheService.setRandomAmounts(packetId, amounts, expireSeconds);
|
||||
|
||||
// 写入Redis(红包主数据)
|
||||
cacheRedPacketData(redPacket);
|
||||
|
||||
// 添加到房间红包列表
|
||||
roomRedPacketCacheService.addToRoomList(
|
||||
cmd.getRoomId(),
|
||||
packetId,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
||||
// 发送飘窗通知(平台红包)
|
||||
sendMessage(cmd, packetId);
|
||||
publishPlatformRedPacket(cmd, redPacket, packetId);
|
||||
|
||||
log.info("发平台红包成功 packetId={} roomId={} amount={} count={} ",
|
||||
packetId, cmd.getRoomId(), cmd.getTotalAmount(), cmd.getTotalCount());
|
||||
@ -186,27 +164,101 @@ public class SendRoomRedPacketCmdExe {
|
||||
return RoomRedPacketAppConvertor.toCO(redPacket);
|
||||
}
|
||||
|
||||
private void deductRoomContribution(Long roomId, Long totalAmount) {
|
||||
String lastWeekDateNumber = ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
|
||||
RoomContributionActivityCount lastWeek = findByRoomIdAndDateNumber(roomId, Integer.parseInt(lastWeekDateNumber));
|
||||
ResponseAssert.notNull(RoomErrorCode.ROOM_CONTRIBUTION_NOT_FOUND, lastWeek);
|
||||
/**
|
||||
* 执行房间周流水奖励平台红包.
|
||||
*/
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public RoomRedPacketCO executeRoomContributionReward(SendRoomRedPacketCmd cmd,
|
||||
String activityCountId) {
|
||||
cmd.setPacketType(2);
|
||||
validateParams(cmd);
|
||||
|
||||
Long amount = lastWeek.getContributionValue().longValue();
|
||||
RoomRewardLevelEnum level = RoomRewardLevelEnum.getLevelByAmount(amount);
|
||||
ResponseAssert.notNull(RoomErrorCode.ROOM_CONTRIBUTION_NOT_COMPLETED, level);
|
||||
ResponseAssert.isTrue(CommonErrorCode.DATA_ERROR, Objects.equals(totalAmount, level.getRewardCoins()));
|
||||
String packetId = buildRoomContributionRewardPacketId(activityCountId);
|
||||
boolean locked = roomContributionActivityCountService
|
||||
.markRewardCoinsSending(activityCountId, packetId);
|
||||
if (!locked) {
|
||||
log.warn("房间周流水奖励已被处理 activityCountId={} roomId={}", activityCountId,
|
||||
cmd.getRoomId());
|
||||
return null;
|
||||
}
|
||||
|
||||
boolean updated = roomContributionActivityCountService.updateRewardCoinsSent(lastWeek.getId());
|
||||
ResponseAssert.isTrue(CommonErrorCode.OPERATING_FAILURE, updated);
|
||||
try {
|
||||
RoomRedPacket redPacket = roomRedPacketGateway.findByPacketId(packetId);
|
||||
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(cmd.getExpireMinutes());
|
||||
if (Objects.isNull(redPacket)) {
|
||||
Long systemUserId = 0L;
|
||||
redPacket = buildRedPacket(cmd, systemUserId, packetId, expireTime,
|
||||
RoomRedPacketSourceType.PLATFORM);
|
||||
roomRedPacketGateway.save(redPacket);
|
||||
} else if (isExpired(redPacket)) {
|
||||
roomRedPacketGateway.resetPlatformPacket(packetId, cmd.getTotalAmount(),
|
||||
cmd.getTotalCount(), cmd.getExpireMinutes(), expireTime);
|
||||
redPacket = buildRedPacket(cmd, 0L, packetId, expireTime,
|
||||
RoomRedPacketSourceType.PLATFORM);
|
||||
}
|
||||
|
||||
RoomRedPacket finalRedPacket = redPacket;
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
publishRoomContributionRewardAfterCommit(cmd, finalRedPacket, activityCountId,
|
||||
packetId);
|
||||
}
|
||||
});
|
||||
|
||||
log.info("房间周流水奖励红包已提交 packetId={} roomId={} activityCountId={} amount={} count={}",
|
||||
packetId, cmd.getRoomId(), activityCountId, cmd.getTotalAmount(),
|
||||
cmd.getTotalCount());
|
||||
return RoomRedPacketAppConvertor.toCO(redPacket);
|
||||
} catch (Exception e) {
|
||||
roomContributionActivityCountService
|
||||
.resetRewardCoinsSending(activityCountId, packetId, e.getMessage());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据房间ID和日期查询数据
|
||||
*/
|
||||
private RoomContributionActivityCount findByRoomIdAndDateNumber(Long roomId, Integer dateNumber) {
|
||||
return roomContributionActivityCountService
|
||||
.findByRoomIdAndDateNumber(roomId, dateNumber)
|
||||
.orElse(null);
|
||||
private void publishRoomContributionRewardAfterCommit(SendRoomRedPacketCmd cmd,
|
||||
RoomRedPacket redPacket,
|
||||
String activityCountId,
|
||||
String packetId) {
|
||||
try {
|
||||
if (roomRedPacketCacheService.existsRedPacket(packetId)) {
|
||||
roomRedPacketCacheService.addToRoomList(
|
||||
cmd.getRoomId(),
|
||||
packetId,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
boolean sent = roomContributionActivityCountService
|
||||
.markRewardCoinsSent(activityCountId, packetId);
|
||||
if (!sent) {
|
||||
log.warn("房间周流水奖励红包已存在但状态标记失败 packetId={} activityCountId={}",
|
||||
packetId, activityCountId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
publishPlatformRedPacket(cmd, redPacket, packetId);
|
||||
boolean sent = roomContributionActivityCountService
|
||||
.markRewardCoinsSent(activityCountId, packetId);
|
||||
if (!sent) {
|
||||
log.warn("房间周流水奖励红包发布后状态标记失败 packetId={} activityCountId={}",
|
||||
packetId, activityCountId);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
roomContributionActivityCountService
|
||||
.resetRewardCoinsSending(activityCountId, packetId, e.getMessage());
|
||||
log.error("房间周流水奖励红包发布失败 packetId={} activityCountId={} roomId={}",
|
||||
packetId, activityCountId, cmd.getRoomId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private String buildRoomContributionRewardPacketId(String activityCountId) {
|
||||
return "RCWR_" + activityCountId;
|
||||
}
|
||||
|
||||
private boolean isExpired(RoomRedPacket redPacket) {
|
||||
return Objects.nonNull(redPacket.getExpireTime())
|
||||
&& !redPacket.getExpireTime().isAfter(LocalDateTime.now());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -222,9 +274,14 @@ public class SendRoomRedPacketCmdExe {
|
||||
build.put("packetId", packetId);
|
||||
|
||||
if (cmd.getTotalAmount() >= 30000) {
|
||||
SysOriginPlatformEnum sysOrigin = SysOriginPlatformEnum
|
||||
.toEnum(cmd.getReqSysOrigin().getOrigin());
|
||||
if (Objects.isNull(sysOrigin)) {
|
||||
return;
|
||||
}
|
||||
imGroupClient.sendMessageBroadcast(
|
||||
BroadcastGroupMsgBodyCmd.builder()
|
||||
.toPlatform(SysOriginPlatformEnum.ATYOU)
|
||||
.toPlatform(sysOrigin)
|
||||
.type(GroupMessageTypeEnum.ROOM_RED_PACKET)
|
||||
.data(build)
|
||||
.build()
|
||||
@ -271,6 +328,23 @@ public class SendRoomRedPacketCmdExe {
|
||||
}
|
||||
}
|
||||
|
||||
private void publishPlatformRedPacket(SendRoomRedPacketCmd cmd, RoomRedPacket redPacket,
|
||||
String packetId) {
|
||||
List<Long> amounts = generateRandomAmounts(cmd.getTotalAmount(), cmd.getTotalCount());
|
||||
long expireSeconds = cmd.getExpireMinutes() * 60;
|
||||
roomRedPacketCacheService.setRandomAmounts(packetId, amounts, expireSeconds);
|
||||
|
||||
cacheRedPacketData(redPacket);
|
||||
|
||||
roomRedPacketCacheService.addToRoomList(
|
||||
cmd.getRoomId(),
|
||||
packetId,
|
||||
System.currentTimeMillis()
|
||||
);
|
||||
|
||||
sendMessage(cmd, packetId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 扣除用户金币
|
||||
*/
|
||||
|
||||
@ -0,0 +1,202 @@
|
||||
package com.red.circle.other.app.scheduler;
|
||||
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.component.redis.annotation.TaskCacheLock;
|
||||
import com.red.circle.framework.core.dto.ReqSysOrigin;
|
||||
import com.red.circle.other.app.command.redpacket.SendRoomRedPacketCmdExe;
|
||||
import com.red.circle.other.app.dto.cmd.SendRoomRedPacketCmd;
|
||||
import com.red.circle.other.app.enums.RoomRewardLevelEnum;
|
||||
import com.red.circle.other.infra.database.mongo.entity.activity.RoomContributionActivityCount;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
|
||||
import com.red.circle.other.infra.database.mongo.service.activity.RoomContributionActivityCountService;
|
||||
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.scheduling.annotation.Scheduled;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 自动发送房间周流水奖励.
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
@ConditionalOnProperty(name = "scheduler.room-contribution-weekly-reward", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
public class RoomContributionWeeklyRewardTask {
|
||||
|
||||
private static final Integer DEFAULT_EXPIRE_MINUTES = 10;
|
||||
private static final Integer DEFAULT_TOTAL_COUNT = 10;
|
||||
private static final BigDecimal DEFAULT_MIN_CONTRIBUTION = BigDecimal.valueOf(100000);
|
||||
private static final BigDecimal TARAB_MIN_CONTRIBUTION = BigDecimal.valueOf(150000);
|
||||
|
||||
private final SendRoomRedPacketCmdExe sendRoomRedPacketCmdExe;
|
||||
private final RoomProfileManagerService roomProfileManagerService;
|
||||
private final RoomContributionActivityCountService roomContributionActivityCountService;
|
||||
|
||||
@Value("${activity.room-contribution.weekly-reward.expire-minutes:10}")
|
||||
private Integer expireMinutes;
|
||||
|
||||
@Value("${activity.room-contribution.weekly-reward.total-count:10}")
|
||||
private Integer totalCount;
|
||||
|
||||
@Value("${activity.room-contribution.weekly-reward.repair-enabled:true}")
|
||||
private Boolean repairEnabled;
|
||||
|
||||
@Value("${activity.room-contribution.weekly-reward.sys-origins:ATYOU}")
|
||||
private String enabledSysOrigins;
|
||||
|
||||
/**
|
||||
* 每周一沙特时间 00:08 发送上周房间周流水奖励.
|
||||
*/
|
||||
@Scheduled(cron = "0 8 0 ? * MON", zone = "Asia/Riyadh")
|
||||
@TaskCacheLock(key = "ROOM_CONTRIBUTION_WEEKLY_REWARD_TASK", expireSecond = 600)
|
||||
public void sendLastWeekRoomContributionRewards() {
|
||||
sendLastWeekRoomContributionRewards("weekly");
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动后和每分钟补偿上周未发奖励,防止周一任务异常后永久漏发.
|
||||
*/
|
||||
@Scheduled(
|
||||
initialDelayString = "${activity.room-contribution.weekly-reward.repair-initial-delay-ms:60000}",
|
||||
fixedDelayString = "${activity.room-contribution.weekly-reward.repair-fixed-delay-ms:60000}")
|
||||
@TaskCacheLock(key = "ROOM_CONTRIBUTION_WEEKLY_REWARD_TASK", expireSecond = 60)
|
||||
public void repairLastWeekRoomContributionRewards() {
|
||||
if (!Boolean.TRUE.equals(repairEnabled)) {
|
||||
return;
|
||||
}
|
||||
sendLastWeekRoomContributionRewards("repair");
|
||||
}
|
||||
|
||||
private void sendLastWeekRoomContributionRewards(String trigger) {
|
||||
log.warn("[RoomContributionWeeklyReward] start trigger={}", trigger);
|
||||
|
||||
List<RoomContributionActivityCount> list =
|
||||
roomContributionActivityCountService.listLastWeekRewardUnsentData();
|
||||
if (CollectionUtils.isEmpty(list)) {
|
||||
log.warn("[RoomContributionWeeklyReward] no unsent reward data trigger={}", trigger);
|
||||
return;
|
||||
}
|
||||
|
||||
int success = 0;
|
||||
int fail = 0;
|
||||
for (RoomContributionActivityCount data : list) {
|
||||
try {
|
||||
if (sendReward(data)) {
|
||||
success++;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
fail++;
|
||||
log.error("[RoomContributionWeeklyReward] send failed roomId={} dataId={} amount={}",
|
||||
data.getRoomId(), data.getId(), data.getContributionValue(), e);
|
||||
}
|
||||
}
|
||||
|
||||
log.warn("[RoomContributionWeeklyReward] end trigger={} total={} success={} fail={}",
|
||||
trigger, list.size(), success, fail);
|
||||
}
|
||||
|
||||
private boolean sendReward(RoomContributionActivityCount data) {
|
||||
if (Objects.isNull(data) || Objects.isNull(data.getRoomId())
|
||||
|| Objects.isNull(data.getContributionValue())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
RoomProfileManager room = roomProfileManagerService.getById(data.getRoomId());
|
||||
SysOriginPlatformEnum sysOrigin = getSysOrigin(room);
|
||||
if (Objects.isNull(room) || Objects.isNull(sysOrigin)) {
|
||||
log.warn("[RoomContributionWeeklyReward] skip invalid room roomId={} dataId={}",
|
||||
data.getRoomId(), data.getId());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!getEnabledSysOrigins().contains(sysOrigin)) {
|
||||
log.warn("[RoomContributionWeeklyReward] skip disabled sysOrigin roomId={} dataId={} sysOrigin={}",
|
||||
data.getRoomId(), data.getId(), sysOrigin);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!meetsPlatformThreshold(sysOrigin, data.getContributionValue())) {
|
||||
log.warn("[RoomContributionWeeklyReward] skip threshold roomId={} dataId={} sysOrigin={} amount={}",
|
||||
data.getRoomId(), data.getId(), sysOrigin, data.getContributionValue());
|
||||
return false;
|
||||
}
|
||||
|
||||
RoomRewardLevelEnum level = RoomRewardLevelEnum
|
||||
.getLevelByAmount(data.getContributionValue().longValue());
|
||||
if (Objects.isNull(level)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SendRoomRedPacketCmd cmd = new SendRoomRedPacketCmd();
|
||||
cmd.setRoomId(data.getRoomId());
|
||||
cmd.setTotalAmount(level.getRewardCoins());
|
||||
cmd.setTotalCount(getTotalCount(level.getRewardCoins()));
|
||||
cmd.setExpireMinutes(getExpireMinutes());
|
||||
cmd.setReqUserId(room.getUserId());
|
||||
cmd.setReqSysOrigin(ReqSysOrigin.of(sysOrigin.name()));
|
||||
|
||||
if (Objects.isNull(sendRoomRedPacketCmdExe.executeRoomContributionReward(cmd, data.getId()))) {
|
||||
return false;
|
||||
}
|
||||
log.info("[RoomContributionWeeklyReward] sent roomId={} dataId={} level={} rewardCoins={}",
|
||||
data.getRoomId(), data.getId(), level.getLevel(), level.getRewardCoins());
|
||||
return true;
|
||||
}
|
||||
|
||||
private SysOriginPlatformEnum getSysOrigin(RoomProfileManager room) {
|
||||
if (Objects.isNull(room) || Objects.isNull(room.getSysOrigin())) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return SysOriginPlatformEnum.valueOf(room.getSysOrigin());
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean meetsPlatformThreshold(SysOriginPlatformEnum sysOrigin, BigDecimal contribution) {
|
||||
BigDecimal minContribution = Objects.equals(sysOrigin, SysOriginPlatformEnum.TARAB)
|
||||
? TARAB_MIN_CONTRIBUTION : DEFAULT_MIN_CONTRIBUTION;
|
||||
return contribution.compareTo(minContribution) >= 0;
|
||||
}
|
||||
|
||||
private Set<SysOriginPlatformEnum> getEnabledSysOrigins() {
|
||||
if (Objects.isNull(enabledSysOrigins) || enabledSysOrigins.isBlank()) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
return Arrays.stream(enabledSysOrigins.split(","))
|
||||
.map(String::trim)
|
||||
.filter(item -> !item.isBlank())
|
||||
.map(SysOriginPlatformEnum::toEnum)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
private Integer getExpireMinutes() {
|
||||
if (Objects.isNull(expireMinutes) || !List.of(1, 3, 5, 10).contains(expireMinutes)) {
|
||||
return DEFAULT_EXPIRE_MINUTES;
|
||||
}
|
||||
return expireMinutes;
|
||||
}
|
||||
|
||||
private Integer getTotalCount(Long rewardCoins) {
|
||||
int count = Objects.isNull(totalCount) ? DEFAULT_TOTAL_COUNT : totalCount;
|
||||
count = Math.max(1, Math.min(count, 100));
|
||||
if (Objects.nonNull(rewardCoins)) {
|
||||
count = Math.min(count, rewardCoins.intValue());
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
@ -36,6 +36,12 @@ public interface RoomRedPacketGateway {
|
||||
*/
|
||||
void updateRefundStatus(String packetId, Integer refundStatus);
|
||||
|
||||
/**
|
||||
* 重置平台红包发布参数.
|
||||
*/
|
||||
void resetPlatformPacket(String packetId, Long totalAmount, Integer totalCount,
|
||||
Integer expireMinutes, LocalDateTime expireTime);
|
||||
|
||||
/**
|
||||
* 查询过期且未退款的红包
|
||||
*/
|
||||
|
||||
@ -62,6 +62,31 @@ public class RoomContributionActivityCount extends Convert implements Serializab
|
||||
*/
|
||||
Boolean rewardCoinsSent;
|
||||
|
||||
/**
|
||||
* 奖励金币是否发送中.
|
||||
*/
|
||||
Boolean rewardCoinsSending;
|
||||
|
||||
/**
|
||||
* 奖励金币红包ID.
|
||||
*/
|
||||
String rewardCoinsPacketId;
|
||||
|
||||
/**
|
||||
* 奖励金币发送时间.
|
||||
*/
|
||||
Timestamp rewardCoinsSentTime;
|
||||
|
||||
/**
|
||||
* 奖励金币发送中时间.
|
||||
*/
|
||||
Timestamp rewardCoinsSendingTime;
|
||||
|
||||
/**
|
||||
* 奖励金币发送失败原因.
|
||||
*/
|
||||
String rewardCoinsSendError;
|
||||
|
||||
/**
|
||||
* 比例.
|
||||
*/
|
||||
|
||||
@ -92,11 +92,26 @@ public interface RoomContributionActivityCountService {
|
||||
*/
|
||||
List<RoomContributionActivityCount> listRoomContributionByPH(Long roomId,BigDecimal number);
|
||||
|
||||
/**
|
||||
* 更新奖励金币状态为已发放
|
||||
*/
|
||||
/**
|
||||
* 更新奖励金币状态为已发放
|
||||
*/
|
||||
boolean updateRewardCoinsSent(String id);
|
||||
|
||||
/**
|
||||
* 抢占奖励金币发送记录.
|
||||
*/
|
||||
boolean markRewardCoinsSending(String id, String packetId);
|
||||
|
||||
/**
|
||||
* 标记奖励金币已发送.
|
||||
*/
|
||||
boolean markRewardCoinsSent(String id, String packetId);
|
||||
|
||||
/**
|
||||
* 释放奖励金币发送中状态,等待重试.
|
||||
*/
|
||||
void resetRewardCoinsSending(String id, String packetId, String reason);
|
||||
|
||||
/**
|
||||
* 获取所有房间上周贡献数据(未领取状态)
|
||||
*
|
||||
@ -104,6 +119,13 @@ public interface RoomContributionActivityCountService {
|
||||
*/
|
||||
List<RoomContributionActivityCount> getAllRoomsLastWeekData();
|
||||
|
||||
/**
|
||||
* 获取所有房间上周贡献数据(平台奖励未发放状态)
|
||||
*
|
||||
* @return 所有房间上周贡献数据列表
|
||||
*/
|
||||
List<RoomContributionActivityCount> listLastWeekRewardUnsentData();
|
||||
|
||||
/**
|
||||
* 根据房间ID和日期查询数据
|
||||
*
|
||||
|
||||
@ -14,6 +14,7 @@ import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@ -45,6 +46,7 @@ public class RoomContributionActivityCountServiceImpl implements
|
||||
private final MongoPageHelper mongoPageHelper;
|
||||
private static final BigDecimal integralMin = BigDecimal.valueOf(100000);
|
||||
private static final BigDecimal otherIntegralMin = BigDecimal.valueOf(150000);
|
||||
private static final long REWARD_SENDING_EXPIRE_MILLIS = 2 * 60 * 1000L;
|
||||
|
||||
private Criteria getUniquenessCriteria(Long roomId, Integer dateNumber) {
|
||||
return Criteria.where("id").is(getUniqueId(roomId, dateNumber));
|
||||
@ -291,10 +293,53 @@ public class RoomContributionActivityCountServiceImpl implements
|
||||
return result.getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markRewardCoinsSending(String id, String packetId) {
|
||||
Query query = Query.query(new Criteria().andOperator(
|
||||
Criteria.where("_id").is(id),
|
||||
unsentRewardCriteria(),
|
||||
rewardNotSendingOrExpiredCriteria()
|
||||
));
|
||||
Update update = new Update()
|
||||
.set("rewardCoinsSending", Boolean.TRUE)
|
||||
.set("rewardCoinsPacketId", packetId)
|
||||
.set("rewardCoinsSendingTime", TimestampUtils.now())
|
||||
.unset("rewardCoinsSendError");
|
||||
UpdateResult result = mongoTemplate.updateFirst(query, update,
|
||||
RoomContributionActivityCount.class);
|
||||
return result.getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean markRewardCoinsSent(String id, String packetId) {
|
||||
Query query = Query.query(Criteria.where("_id").is(id)
|
||||
.and("rewardCoinsPacketId").is(packetId));
|
||||
Update update = new Update()
|
||||
.set("rewardCoinsSent", Boolean.TRUE)
|
||||
.set("rewardCoinsSending", Boolean.FALSE)
|
||||
.set("rewardCoinsSentTime", TimestampUtils.now())
|
||||
.unset("rewardCoinsSendError");
|
||||
UpdateResult result = mongoTemplate.updateFirst(query, update,
|
||||
RoomContributionActivityCount.class);
|
||||
return result.getModifiedCount() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetRewardCoinsSending(String id, String packetId, String reason) {
|
||||
Query query = Query.query(new Criteria().andOperator(
|
||||
Criteria.where("_id").is(id),
|
||||
Criteria.where("rewardCoinsPacketId").is(packetId),
|
||||
unsentRewardCriteria()
|
||||
));
|
||||
Update update = new Update()
|
||||
.set("rewardCoinsSending", Boolean.FALSE)
|
||||
.set("rewardCoinsSendError", limitErrorReason(reason));
|
||||
mongoTemplate.updateFirst(query, update, RoomContributionActivityCount.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoomContributionActivityCount> getAllRoomsLastWeekData() {
|
||||
// 获取上周的 dateNumber
|
||||
Integer lastWeekDateNumber = ZonedDateTimeAsiaRiyadhUtils.getThisMonday() - 7;
|
||||
Integer lastWeekDateNumber = getLastWeekDateNumber();
|
||||
|
||||
Criteria criteria = Criteria.where("dateNumber").is(lastWeekDateNumber)
|
||||
.and("received").is(Boolean.FALSE);
|
||||
@ -302,6 +347,18 @@ public class RoomContributionActivityCountServiceImpl implements
|
||||
return mongoTemplate.find(Query.query(criteria), RoomContributionActivityCount.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoomContributionActivityCount> listLastWeekRewardUnsentData() {
|
||||
Criteria criteria = new Criteria().andOperator(
|
||||
Criteria.where("dateNumber").is(getLastWeekDateNumber()),
|
||||
Criteria.where("contributionValue").gte(integralMin),
|
||||
unsentRewardCriteria(),
|
||||
rewardNotSendingOrExpiredCriteria()
|
||||
);
|
||||
|
||||
return mongoTemplate.find(Query.query(criteria), RoomContributionActivityCount.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<RoomContributionActivityCount> findByRoomIdAndDateNumber(Long roomId, Integer dateNumber) {
|
||||
Criteria criteria = Criteria.where("roomId").is(roomId)
|
||||
@ -315,4 +372,32 @@ public class RoomContributionActivityCountServiceImpl implements
|
||||
return Optional.ofNullable(result);
|
||||
}
|
||||
|
||||
private Integer getLastWeekDateNumber() {
|
||||
return Integer.valueOf(ZonedDateTimeAsiaRiyadhUtils.getLastWeekMonday()
|
||||
.format(DateTimeFormatter.ofPattern("yyyyMMdd")));
|
||||
}
|
||||
|
||||
private Criteria unsentRewardCriteria() {
|
||||
return new Criteria().orOperator(
|
||||
Criteria.where("rewardCoinsSent").exists(false),
|
||||
Criteria.where("rewardCoinsSent").ne(Boolean.TRUE)
|
||||
);
|
||||
}
|
||||
|
||||
private Criteria rewardNotSendingOrExpiredCriteria() {
|
||||
return new Criteria().orOperator(
|
||||
Criteria.where("rewardCoinsSending").exists(false),
|
||||
Criteria.where("rewardCoinsSending").ne(Boolean.TRUE),
|
||||
Criteria.where("rewardCoinsSendingTime")
|
||||
.lt(new java.sql.Timestamp(System.currentTimeMillis() - REWARD_SENDING_EXPIRE_MILLIS))
|
||||
);
|
||||
}
|
||||
|
||||
private String limitErrorReason(String reason) {
|
||||
if (StringUtils.isBlank(reason) || reason.length() <= 500) {
|
||||
return reason;
|
||||
}
|
||||
return reason.substring(0, 500);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -36,6 +36,15 @@ public interface RoomRedPacketDAO {
|
||||
*/
|
||||
int updateRefundStatus(@Param("packetId") String packetId, @Param("refundStatus") Integer refundStatus);
|
||||
|
||||
/**
|
||||
* 重置平台红包发布参数
|
||||
*/
|
||||
int resetPlatformPacket(@Param("packetId") String packetId,
|
||||
@Param("totalAmount") Long totalAmount,
|
||||
@Param("totalCount") Integer totalCount,
|
||||
@Param("expireMinutes") Integer expireMinutes,
|
||||
@Param("expireTime") LocalDateTime expireTime);
|
||||
|
||||
/**
|
||||
* 查询过期且未退款的红包
|
||||
*/
|
||||
|
||||
@ -53,6 +53,13 @@ public class RoomRedPacketGatewayImpl implements RoomRedPacketGateway {
|
||||
roomRedPacketDAO.updateRefundStatus(packetId, refundStatus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void resetPlatformPacket(String packetId, Long totalAmount, Integer totalCount,
|
||||
Integer expireMinutes, LocalDateTime expireTime) {
|
||||
roomRedPacketDAO.resetPlatformPacket(packetId, totalAmount, totalCount, expireMinutes,
|
||||
expireTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoomRedPacket> findExpiredAndNotRefunded(LocalDateTime now) {
|
||||
List<RoomRedPacketEntity> entities = roomRedPacketDAO.selectExpiredAndNotRefunded(now);
|
||||
|
||||
@ -75,6 +75,21 @@
|
||||
WHERE packet_id = #{packetId}
|
||||
</update>
|
||||
|
||||
<update id="resetPlatformPacket">
|
||||
UPDATE room_red_packet
|
||||
SET total_amount = #{totalAmount},
|
||||
total_count = #{totalCount},
|
||||
remain_amount = #{totalAmount},
|
||||
remain_count = #{totalCount},
|
||||
expire_minutes = #{expireMinutes},
|
||||
expire_time = #{expireTime},
|
||||
status = 1,
|
||||
refund_status = 0,
|
||||
update_time = NOW()
|
||||
WHERE packet_id = #{packetId}
|
||||
AND source_type = 2
|
||||
</update>
|
||||
|
||||
<select id="selectExpiredAndNotRefunded" resultMap="BaseResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user