新增火箭用户领取奖励
This commit is contained in:
parent
75c1e5522d
commit
3bdfc23433
@ -264,7 +264,12 @@ public enum SendPropsOrigin {
|
||||
*/
|
||||
LOTTERY_REWARD("Lottery Rewards"),
|
||||
|
||||
/**
|
||||
/**
|
||||
* 火箭奖励
|
||||
*/
|
||||
ROCKET_REWARD("Rocket reward"),
|
||||
|
||||
/**
|
||||
* 道具券兑换
|
||||
*/
|
||||
COUPON_EXCHANGE("Coupon Exchange"),
|
||||
|
||||
@ -703,6 +703,11 @@ public enum GoldOrigin {
|
||||
*/
|
||||
LOTTERY_REWARD("Lottery reward"),
|
||||
|
||||
/**
|
||||
* 火箭奖励
|
||||
*/
|
||||
ROCKET_REWARD("Rocket reward"),
|
||||
|
||||
/**
|
||||
* 抽奖兑换金币
|
||||
*/
|
||||
|
||||
@ -39,6 +39,11 @@ public class RocketConfigCO {
|
||||
* 奖励配置(JSON)
|
||||
*/
|
||||
private JSONArray rewardConfig;
|
||||
|
||||
/**
|
||||
* 奖励礼物数量
|
||||
*/
|
||||
private Integer rewardQuantity;
|
||||
|
||||
/**
|
||||
* 贡献者奖励比例%
|
||||
|
||||
@ -46,7 +46,7 @@ public class RocketRestController {
|
||||
/**
|
||||
* 领取奖励
|
||||
*/
|
||||
// @PostMapping("/claim")
|
||||
@PostMapping("/claim")
|
||||
public RocketRewardCO claimReward(@Valid @RequestBody RocketRewardClaimCmd cmd) {
|
||||
return rocketService.claimReward(cmd);
|
||||
}
|
||||
|
||||
@ -1,22 +1,38 @@
|
||||
package com.red.circle.other.app.command.rocket;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
|
||||
import com.red.circle.common.business.enums.SendPropsOrigin;
|
||||
import com.red.circle.other.app.dto.clientobject.RocketRewardCO;
|
||||
import com.red.circle.other.app.dto.cmd.RocketRewardClaimCmd;
|
||||
import com.red.circle.other.app.manager.RocketImPushManager;
|
||||
import com.red.circle.other.app.util.DistributedLockUtil;
|
||||
import com.red.circle.other.domain.gateway.RocketConfigGateway;
|
||||
import com.red.circle.other.domain.gateway.RocketHistoryGateway;
|
||||
import com.red.circle.other.domain.gateway.RocketRewardLogGateway;
|
||||
import com.red.circle.other.domain.gateway.RocketStatusGateway;
|
||||
import com.red.circle.other.domain.rocket.RocketContributor;
|
||||
import com.red.circle.other.domain.rocket.RocketRewardLog;
|
||||
import com.red.circle.other.domain.rocket.RocketStatus;
|
||||
import com.red.circle.other.domain.rocket.*;
|
||||
import com.red.circle.other.infra.database.cache.key.RocketKeys;
|
||||
import com.red.circle.other.inner.endpoint.material.props.BadgeBackpackClient;
|
||||
import com.red.circle.other.inner.endpoint.material.props.PropsBackpackClient;
|
||||
import com.red.circle.other.inner.enums.material.BadgeBackpackExpireTypeEnum;
|
||||
import com.red.circle.other.inner.enums.sys.SysBadgeConfigTypeEnum;
|
||||
import com.red.circle.other.inner.model.cmd.material.GiveBadgeCmd;
|
||||
import com.red.circle.other.inner.model.cmd.material.GivePropsBackpackCmd;
|
||||
import com.red.circle.other.inner.model.dto.material.PropsActivityRewardConfigInfoDTO;
|
||||
import com.red.circle.wallet.inner.endpoint.wallet.WalletGoldClient;
|
||||
import com.red.circle.wallet.inner.model.cmd.GoldReceiptCmd;
|
||||
import com.red.circle.wallet.inner.model.enums.GoldOrigin;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* 火箭奖励领取命令执行器
|
||||
@ -30,113 +46,276 @@ import java.time.LocalDateTime;
|
||||
public class RocketRewardClaimCmdExe {
|
||||
|
||||
private final RocketStatusGateway rocketStatusGateway;
|
||||
private final RocketConfigGateway rocketConfigGateway;
|
||||
private final RocketRewardLogGateway rocketRewardLogGateway;
|
||||
private final RocketHistoryGateway rocketHistoryGateway;
|
||||
private final DistributedLockUtil distributedLockUtil;
|
||||
private final RocketImPushManager rocketImPushManager;
|
||||
private final WalletGoldClient walletGoldClient;
|
||||
private final PropsBackpackClient propsBackpackClient;
|
||||
private final BadgeBackpackClient badgeBackpackClient;
|
||||
|
||||
// TODO: 注入钱包服务Feign Client
|
||||
// private final WalletGoldClient walletGoldClient;
|
||||
private final Random random = new Random();
|
||||
|
||||
/**
|
||||
* 执行奖励领取
|
||||
*/
|
||||
public RocketRewardCO execute(RocketRewardClaimCmd cmd) {
|
||||
// 构建锁Key (防止同一用户并发领取)
|
||||
String lockKey = RocketKeys.LOCK.getKey(cmd.getRoomId(), "claim", cmd.getUserId());
|
||||
Long userId = cmd.getReqUserId();
|
||||
String lockKey = RocketKeys.LOCK.getKey(cmd.getRoomId(), "claim", userId);
|
||||
|
||||
return distributedLockUtil.executeWithLock(lockKey, 3L, () -> {
|
||||
return doClaim(cmd);
|
||||
}, "奖励领取操作过于频繁,请稍后重试");
|
||||
return distributedLockUtil.executeWithLock(lockKey, 5L, () -> doClaim(cmd), "奖励领取操作过于频繁,请稍后重试");
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行领取逻辑
|
||||
*/
|
||||
private RocketRewardCO doClaim(RocketRewardClaimCmd cmd) {
|
||||
// 1. 查询火箭状态
|
||||
Long userId = cmd.getReqUserId();
|
||||
Long roomId = cmd.getRoomId();
|
||||
String today = LocalDate.now().toString();
|
||||
RocketStatus rocketStatus = rocketStatusGateway.findByRoomIdAndDate(cmd.getRoomId(), today);
|
||||
|
||||
// 1. 查询火箭状态
|
||||
RocketStatus rocketStatus = rocketStatusGateway.findByRoomIdAndDate(roomId, today);
|
||||
if (rocketStatus == null) {
|
||||
throw new RuntimeException("火箭状态不存在");
|
||||
}
|
||||
|
||||
// 2. 校验领取资格
|
||||
if (!rocketStatus.canClaim()) {
|
||||
if (rocketStatus.isExpired()) {
|
||||
throw new RuntimeException("奖励领取已过期");
|
||||
}
|
||||
throw new RuntimeException("当前状态不可领取奖励");
|
||||
Integer rocketLevel = rocketStatus.getLevel().getLevel();
|
||||
|
||||
// 2. 校验是否已发射
|
||||
if (rocketStatus.getStatus() != RocketStatusEnum.LAUNCHED) {
|
||||
throw new RuntimeException("火箭尚未发射,无法领取奖励");
|
||||
}
|
||||
|
||||
// 3. 检查是否已领取 (MySQL防重)
|
||||
boolean hasClaimed = rocketRewardLogGateway.existsByRocketAndUser(
|
||||
cmd.getRocketHistoryId(), cmd.getUserId());
|
||||
// 3. 检查是否已领取(每天每个房间每个等级只能领一次)
|
||||
boolean hasClaimed = rocketRewardLogGateway.existsByRoomAndUserAndDateAndLevel(roomId, userId, today, rocketLevel);
|
||||
if (hasClaimed) {
|
||||
throw new RuntimeException("您已经领取过奖励了");
|
||||
throw new RuntimeException("今日该等级火箭已领取,请等待下一级或明天再来");
|
||||
}
|
||||
|
||||
// 4. 判断是否为贡献者
|
||||
RocketContributor contributor = findContributor(rocketStatus, cmd.getUserId());
|
||||
boolean isContributor = contributor != null;
|
||||
// 4. 查询火箭配置
|
||||
RocketConfig config = rocketConfigGateway.findByLevel(rocketLevel);
|
||||
if (config == null) {
|
||||
throw new RuntimeException("火箭配置不存在");
|
||||
}
|
||||
|
||||
// 5. 计算奖励 (TODO: 后续根据配置计算)
|
||||
Long rewardAmount = calculateReward(isContributor, contributor, rocketStatus);
|
||||
// 5. 检查奖励数量是否已达上限
|
||||
Integer rewardQuantity = config.getRewardQuantity() != null ? config.getRewardQuantity() : 20;
|
||||
if (rocketStatus.getClaimCount() >= rewardQuantity) {
|
||||
throw new RuntimeException("奖励已被领完,请下次早点来");
|
||||
}
|
||||
|
||||
// 6. 解析奖励配置
|
||||
List<PropsActivityRewardConfigInfoDTO> rewardList = parseRewardConfig(config.getRewardConfig().toJSONString());
|
||||
if (rewardList == null || rewardList.isEmpty()) {
|
||||
throw new RuntimeException("奖励配置为空");
|
||||
}
|
||||
|
||||
// 7. 随机选择一个奖励
|
||||
PropsActivityRewardConfigInfoDTO selectedReward = rewardList.get(random.nextInt(rewardList.size()));
|
||||
|
||||
RocketRewardCO rewardCO = new RocketRewardCO();
|
||||
rewardCO.setIsContributor(isContributor);
|
||||
rewardCO.setRewardType("GOLD");
|
||||
rewardCO.setRewardAmount(rewardAmount);
|
||||
|
||||
if (isContributor) {
|
||||
rewardCO.setContributionEnergy(contributor.getEnergy());
|
||||
rewardCO.setContributionRate(contributor.getContributionRate());
|
||||
rewardCO.setMessage("恭喜您获得贡献者奖励!");
|
||||
} else {
|
||||
rewardCO.setMessage("恭喜您获得参与奖励!");
|
||||
}
|
||||
// 8. 发放奖励
|
||||
String walletBizNo = RocketRewardLog.buildBizNo(roomId.toString(), userId);
|
||||
grantReward(userId, selectedReward, walletBizNo);
|
||||
|
||||
// 6. 发放奖励 (调用钱包服务)
|
||||
String walletBizNo = RocketRewardLog.buildBizNo(cmd.getRocketHistoryId(), cmd.getUserId());
|
||||
try {
|
||||
sendRewardToWallet(cmd.getUserId(), rewardAmount, walletBizNo);
|
||||
} catch (Exception e) {
|
||||
log.error("调用钱包服务发放奖励失败: userId={}, amount={}", cmd.getUserId(), rewardAmount, e);
|
||||
throw new RuntimeException("奖励发放失败,请稍后重试");
|
||||
}
|
||||
// 9. 保存领取记录
|
||||
saveRewardLog(roomId, userId, today, rocketLevel, selectedReward, walletBizNo);
|
||||
|
||||
// 7. 记录领取日志 (MySQL)
|
||||
saveRewardLog(cmd, rocketStatus, isContributor, contributor, rewardAmount, walletBizNo);
|
||||
|
||||
// 8. 更新领取人数
|
||||
// 10. 更新领取人数
|
||||
rocketStatus.incrementClaimCount();
|
||||
rocketStatusGateway.save(rocketStatus);
|
||||
|
||||
// 9. 更新历史记录的领取统计
|
||||
// 11. 推送领取成功消息
|
||||
try {
|
||||
rocketHistoryGateway.updateClaimStats(cmd.getRocketHistoryId(), 1, rewardAmount);
|
||||
String userName = "用户" + userId;
|
||||
Long rewardAmount = getRewardAmount(selectedReward);
|
||||
rocketImPushManager.pushRewardClaimed(roomId, userId, userName, rewardAmount);
|
||||
} catch (Exception e) {
|
||||
log.error("更新历史记录领取统计失败: historyId={}", cmd.getRocketHistoryId(), e);
|
||||
log.error("推送奖励领取消息失败: roomId={}, userId={}", roomId, userId, e);
|
||||
}
|
||||
|
||||
// 10. 推送领取成功消息
|
||||
try {
|
||||
// TODO: 获取用户名称
|
||||
String userName = "用户" + cmd.getUserId();
|
||||
rocketImPushManager.pushRewardClaimed(cmd.getRoomId(), cmd.getUserId(), userName, rewardAmount);
|
||||
} catch (Exception e) {
|
||||
log.error("推送奖励领取消息失败: roomId={}, userId={}", cmd.getRoomId(), cmd.getUserId(), e);
|
||||
}
|
||||
// 12. 构建返回结果
|
||||
RocketRewardCO rewardCO = new RocketRewardCO();
|
||||
rewardCO.setRewardType(selectedReward.getType());
|
||||
rewardCO.setRewardItemId(selectedReward.getId());
|
||||
rewardCO.setRewardItemName(selectedReward.getName());
|
||||
rewardCO.setRewardAmount(getRewardAmount(selectedReward));
|
||||
rewardCO.setMessage("恭喜您获得火箭奖励!");
|
||||
|
||||
log.info("火箭奖励领取成功, roomId={}, userId={}, isContributor={}, rewardAmount={}",
|
||||
cmd.getRoomId(), cmd.getUserId(), isContributor, rewardAmount);
|
||||
log.info("火箭奖励领取成功: roomId={}, userId={}, level={}, rewardType={}, rewardId={}",
|
||||
roomId, userId, rocketLevel, selectedReward.getType(), selectedReward.getId());
|
||||
|
||||
return rewardCO;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找贡献者
|
||||
* 解析奖励配置
|
||||
*/
|
||||
private List<PropsActivityRewardConfigInfoDTO> parseRewardConfig(String rewardConfigJson) {
|
||||
try {
|
||||
JSONArray jsonArray = JSON.parseArray(rewardConfigJson);
|
||||
return jsonArray.toJavaList(PropsActivityRewardConfigInfoDTO.class);
|
||||
} catch (Exception e) {
|
||||
log.error("解析奖励配置失败", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放奖励(手动实现)
|
||||
*/
|
||||
private void grantReward(Long userId, PropsActivityRewardConfigInfoDTO reward, String bizNo) {
|
||||
try {
|
||||
String rewardType = reward.getType();
|
||||
|
||||
switch (rewardType) {
|
||||
case "GOLD" -> {
|
||||
// 发放金币
|
||||
Long goldAmount = Long.parseLong(reward.getContent());
|
||||
grantGold(userId, goldAmount, bizNo);
|
||||
}
|
||||
case "PROPS" -> {
|
||||
// 发放道具(头饰/座驾等)
|
||||
Long propId = Long.parseLong(reward.getContent());
|
||||
Integer quantity = reward.getQuantity() != null ? reward.getQuantity() : 1;
|
||||
String detailType = reward.getDetailType(); // AVATAR_FRAME / RIDE
|
||||
grantProp(userId, propId, quantity, detailType, bizNo);
|
||||
}
|
||||
case "BADGE" -> {
|
||||
// 发放徽章
|
||||
Long badgeId = Long.parseLong(reward.getContent());
|
||||
Integer quantity = reward.getQuantity() != null ? reward.getQuantity() : 1;
|
||||
grantBadge(userId, badgeId, quantity, bizNo);
|
||||
}
|
||||
default -> throw new RuntimeException("不支持的奖励类型: " + rewardType);
|
||||
}
|
||||
|
||||
log.info("奖励发放成功: userId={}, type={}, bizNo={}", userId, rewardType, bizNo);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("发放奖励失败: userId={}, reward={}", userId, reward, e);
|
||||
throw new RuntimeException("发放奖励失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放金币
|
||||
*/
|
||||
private void grantGold(Long userId, Long goldAmount, String bizNo) {
|
||||
try {
|
||||
// 防止配错导致发送大量金币
|
||||
BigDecimal amount = BigDecimal.valueOf(goldAmount);
|
||||
walletGoldClient.changeBalance(
|
||||
GoldReceiptCmd.builder()
|
||||
.opsIncome()
|
||||
.userId(userId)
|
||||
.eventId(bizNo)
|
||||
.sysOrigin(SysOriginPlatformEnum.LIKEI)
|
||||
.origin(GoldOrigin.ROCKET_REWARD)
|
||||
.originDescribe(GoldOrigin.ROCKET_REWARD.name())
|
||||
.amount(amount)
|
||||
.remark("")
|
||||
.build()
|
||||
);
|
||||
|
||||
log.info("金币发放成功: userId={}, amount={}", userId, goldAmount);
|
||||
} catch (Exception e) {
|
||||
log.error("金币发放失败: userId={}, amount={}", userId, goldAmount, e);
|
||||
throw new RuntimeException("金币发放失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放道具(头饰/座驾等)
|
||||
*/
|
||||
private void grantProp(Long userId, Long propId, Integer quantity, String detailType, String bizNo) {
|
||||
try {
|
||||
|
||||
GivePropsBackpackCmd cmd = new GivePropsBackpackCmd()
|
||||
.setAcceptUserId(userId)
|
||||
.setPropsId(propId)
|
||||
.setType("PROPS")
|
||||
.setOrigin(SendPropsOrigin.ROCKET_REWARD.name())
|
||||
.setOriginDesc(SendPropsOrigin.ROCKET_REWARD.getDesc())
|
||||
.setDays(quantity)
|
||||
.setUseProps(Boolean.FALSE)
|
||||
.setAllowGive(Boolean.FALSE)
|
||||
.setOpUser(userId);
|
||||
|
||||
propsBackpackClient.giveProps(cmd);
|
||||
log.info("道具发放成功(TODO): userId={}, propId={}, quantity={}, type={}",
|
||||
userId, propId, quantity, detailType);
|
||||
} catch (Exception e) {
|
||||
log.error("道具发放失败: userId={}, propId={}", userId, propId, e);
|
||||
throw new RuntimeException("道具发放失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放徽章
|
||||
*/
|
||||
private void grantBadge(Long userId, Long badgeId, Integer quantity, String bizNo) {
|
||||
try {
|
||||
|
||||
// 徽章赠送天数大于1000天则为永久赠送
|
||||
BadgeBackpackExpireTypeEnum expireType = quantity >= 1000
|
||||
? BadgeBackpackExpireTypeEnum.PERMANENT
|
||||
: BadgeBackpackExpireTypeEnum.TEMPORARY;
|
||||
|
||||
badgeBackpackClient.giveBadge(new GiveBadgeCmd()
|
||||
.setAcceptUserId(userId)
|
||||
.setBadgeId(badgeId)
|
||||
.setExpireType(expireType)
|
||||
.setDays(quantity)
|
||||
.setBadgeType(SysBadgeConfigTypeEnum.ACTIVITY)
|
||||
);
|
||||
|
||||
log.info("徽章发放成功(TODO): userId={}, badgeId={}", userId, badgeId);
|
||||
} catch (Exception e) {
|
||||
log.error("徽章发放失败: userId={}, badgeId={}", userId, badgeId, e);
|
||||
throw new RuntimeException("徽章发放失败");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存领取记录
|
||||
*/
|
||||
private void saveRewardLog(Long roomId, Long userId, String date, Integer level,
|
||||
PropsActivityRewardConfigInfoDTO reward, String walletBizNo) {
|
||||
RocketRewardLog log = new RocketRewardLog();
|
||||
log.setRoomId(roomId);
|
||||
log.setUserId(userId);
|
||||
log.setRocketLevel(level);
|
||||
log.setIsContributor(0);
|
||||
log.setContributionEnergy(0L);
|
||||
log.setContributionRate(null);
|
||||
log.setRewardType(reward.getType());
|
||||
log.setRewardItemId(reward.getId());
|
||||
log.setRewardAmount(getRewardAmount(reward));
|
||||
log.setWalletBizNo(walletBizNo);
|
||||
log.setClaimedAt(LocalDateTime.now());
|
||||
log.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
rocketRewardLogGateway.save(log);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取奖励金额
|
||||
*/
|
||||
private Long getRewardAmount(PropsActivityRewardConfigInfoDTO reward) {
|
||||
if ("GOLD".equals(reward.getType())) {
|
||||
try {
|
||||
return Long.parseLong(reward.getContent());
|
||||
} catch (Exception e) {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
int quantity = reward.getQuantity() == null ? 0 : reward.getQuantity();
|
||||
return Long.parseLong(Integer.toString(quantity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查找贡献者(备用)
|
||||
*/
|
||||
private RocketContributor findContributor(RocketStatus rocketStatus, Long userId) {
|
||||
if (rocketStatus.getContributors() == null) {
|
||||
@ -147,73 +326,4 @@ public class RocketRewardClaimCmdExe {
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算奖励金额
|
||||
* TODO: 后续根据配置表计算
|
||||
*/
|
||||
private Long calculateReward(boolean isContributor, RocketContributor contributor, RocketStatus rocketStatus) {
|
||||
if (isContributor) {
|
||||
// 贡献者奖励 = 基础奖励 + 按贡献率分配的额外奖励
|
||||
// 目前固定返回1000,后续根据配置计算
|
||||
return 1000L;
|
||||
} else {
|
||||
// 普通用户固定奖励
|
||||
return 100L;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用钱包服务发放奖励
|
||||
* TODO: 集成wallet-inner-api
|
||||
*/
|
||||
private void sendRewardToWallet(Long userId, Long amount, String bizNo) {
|
||||
// 示例代码,需要引入实际的Feign Client
|
||||
/*
|
||||
WalletReceiptReqDTO req = new WalletReceiptReqDTO();
|
||||
req.setUserId(userId);
|
||||
req.setAmount(PennyAmount.of(amount)); // 金币
|
||||
req.setBizType(WalletBizType.ROCKET_REWARD);
|
||||
req.setBizNo(bizNo);
|
||||
req.setRemark("火箭奖励");
|
||||
|
||||
ResultResponse<Void> response = walletGoldClient.income(req);
|
||||
if (!response.isSuccess()) {
|
||||
throw new RuntimeException("钱包服务调用失败: " + response.getMessage());
|
||||
}
|
||||
*/
|
||||
|
||||
log.info("TODO: 调用钱包服务发放奖励, userId={}, amount={}, bizNo={}", userId, amount, bizNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存领取记录
|
||||
*/
|
||||
private void saveRewardLog(RocketRewardClaimCmd cmd, RocketStatus rocketStatus,
|
||||
boolean isContributor, RocketContributor contributor,
|
||||
Long rewardAmount, String walletBizNo) {
|
||||
RocketRewardLog log = new RocketRewardLog();
|
||||
log.setRocketHistoryId(cmd.getRocketHistoryId());
|
||||
log.setRoomId(cmd.getRoomId());
|
||||
log.setUserId(cmd.getUserId());
|
||||
log.setRocketLevel(rocketStatus.getLevel().getLevel());
|
||||
log.setIsContributor(isContributor ? 1 : 0);
|
||||
|
||||
if (isContributor && contributor != null) {
|
||||
log.setContributionEnergy(contributor.getEnergy());
|
||||
log.setContributionRate(contributor.getContributionRate());
|
||||
} else {
|
||||
log.setContributionEnergy(0L);
|
||||
log.setContributionRate(null);
|
||||
}
|
||||
|
||||
log.setRewardType("GOLD");
|
||||
log.setRewardItemId(null);
|
||||
log.setRewardAmount(rewardAmount);
|
||||
log.setWalletBizNo(walletBizNo);
|
||||
log.setClaimedAt(LocalDateTime.now());
|
||||
log.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
rocketRewardLogGateway.save(log);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,11 @@ public class RocketRewardCO {
|
||||
*/
|
||||
private Long rewardItemId;
|
||||
|
||||
/**
|
||||
* 奖励物品名称
|
||||
*/
|
||||
private String rewardItemName;
|
||||
|
||||
/**
|
||||
* 奖励数量
|
||||
*/
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
package com.red.circle.other.app.dto.cmd;
|
||||
|
||||
import com.red.circle.common.business.dto.cmd.AppExtCommand;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 火箭奖励领取命令
|
||||
@ -10,8 +12,9 @@ import lombok.Data;
|
||||
* @author system
|
||||
* @date 2025-01-15
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class RocketRewardClaimCmd {
|
||||
public class RocketRewardClaimCmd extends AppExtCommand {
|
||||
|
||||
/**
|
||||
* 房间ID
|
||||
@ -19,15 +22,4 @@ public class RocketRewardClaimCmd {
|
||||
@NotNull(message = "房间ID不能为空")
|
||||
private Long roomId;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
@NotNull(message = "用户ID不能为空")
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 火箭历史ID (MongoDB _id)
|
||||
*/
|
||||
@NotBlank(message = "火箭历史ID不能为空")
|
||||
private String rocketHistoryId;
|
||||
}
|
||||
|
||||
@ -22,6 +22,16 @@ public interface RocketRewardLogGateway {
|
||||
*/
|
||||
boolean existsByRocketAndUser(String rocketHistoryId, Long userId);
|
||||
|
||||
/**
|
||||
* 检查用户是否已领取(带等级)
|
||||
* @param roomId 房间ID
|
||||
* @param userId 用户ID
|
||||
* @param date 日期
|
||||
* @param level 火箭等级
|
||||
* @return 是否已领取
|
||||
*/
|
||||
boolean existsByRoomAndUserAndDateAndLevel(Long roomId, Long userId, String date, Integer level);
|
||||
|
||||
/**
|
||||
* 根据火箭历史ID查询所有领取记录
|
||||
*/
|
||||
|
||||
@ -36,6 +36,11 @@ public class RocketConfig {
|
||||
*/
|
||||
private JSONArray rewardConfig;
|
||||
|
||||
/**
|
||||
* 奖励礼物数量(默认20个)
|
||||
*/
|
||||
private Integer rewardQuantity;
|
||||
|
||||
/**
|
||||
* 贡献者奖励比例%
|
||||
*/
|
||||
|
||||
@ -25,6 +25,5 @@ public interface RocketRewardLogConvertor {
|
||||
/**
|
||||
* Domain转Entity
|
||||
*/
|
||||
@Mapping(target = "createdAt", ignore = true)
|
||||
RocketRewardClaimLogEntity toEntity(RocketRewardLog log);
|
||||
}
|
||||
|
||||
@ -24,6 +24,14 @@ public interface RocketRewardClaimLogDAO {
|
||||
int countByRocketAndUser(@Param("rocketHistoryId") String rocketHistoryId,
|
||||
@Param("userId") Long userId);
|
||||
|
||||
/**
|
||||
* 检查用户是否已领取(带等级)
|
||||
*/
|
||||
int countByRoomAndUserAndDateAndLevel(@Param("userId") Long userId,
|
||||
@Param("roomId") Long roomId,
|
||||
@Param("date") String date,
|
||||
@Param("level") Integer level);
|
||||
|
||||
/**
|
||||
* 根据火箭历史ID查询
|
||||
*/
|
||||
|
||||
@ -36,6 +36,11 @@ public class RocketConfigEntity {
|
||||
*/
|
||||
private String rewardConfig;
|
||||
|
||||
/**
|
||||
* 奖励礼物数量(默认20个)
|
||||
*/
|
||||
private Integer rewardQuantity;
|
||||
|
||||
/**
|
||||
* 贡献者奖励比例%
|
||||
*/
|
||||
|
||||
@ -39,6 +39,12 @@ public class RocketRewardLogGatewayImpl implements RocketRewardLogGateway {
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByRoomAndUserAndDateAndLevel(Long roomId, Long userId, String date, Integer level) {
|
||||
int count = rocketRewardClaimLogDAO.countByRoomAndUserAndDateAndLevel(userId, roomId, date, level);
|
||||
return count > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RocketRewardLog> findByRocketHistoryId(String rocketHistoryId) {
|
||||
List<RocketRewardClaimLogEntity> entities =
|
||||
|
||||
@ -68,4 +68,12 @@
|
||||
WHERE rocket_history_id = #{rocketHistoryId}
|
||||
</select>
|
||||
|
||||
<select id="countByRoomAndUserAndDateAndLevel" resultType="int">
|
||||
SELECT COUNT(1)
|
||||
FROM rocket_reward_claim_log
|
||||
WHERE user_id = #{userId}
|
||||
AND room_id = #{roomId}
|
||||
AND DATE(claimed_at) = #{date}
|
||||
AND rocket_level = #{level}
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user