发红包优化

This commit is contained in:
wells
2026-08-08 22:22:48 +08:00
parent cfb5b4f2a8
commit b227f33d9f
4 changed files with 71 additions and 13 deletions
@@ -29,9 +29,9 @@ public class RedPacketController {
@PostMapping("/send") @PostMapping("/send")
public R<RedPacket> sendRp(@RequestBody SendRpDTO dto) { public R<RedPacket> sendRp(@RequestBody SendRpDTO dto) {
Long userId = UserContext.getUserId(); Long userId = UserContext.getUserId();
// roundId从当前group的进行中局获取 // roundId从当前group的RP_SENDING状态局获取
var ongoingRound = gameService.getOngoingRound(dto.getGroupId()); var sendingRound = gameService.getRpSendingRound(dto.getGroupId());
Long roundId = ongoingRound == null ? null : ongoingRound.getId(); Long roundId = sendingRound == null ? null : sendingRound.getId();
var rp = redPacketService.sendRp(userId, dto.getGroupId(), var rp = redPacketService.sendRp(userId, dto.getGroupId(),
dto.getTotalAmount(), dto.getTotalCount(), roundId); dto.getTotalAmount(), dto.getTotalCount(), roundId);
return R.ok(rp); return R.ok(rp);
+33 -10
View File
@@ -187,6 +187,14 @@ public class GameJob {
} }
} }
/**
* 获取字符串配置值(带默认值)
*/
public String getConfig(String key, String defaultValue) {
String value = configCache.get(key);
return value == null ? defaultValue : value;
}
/** /**
* 检查红包是否需要托领取(每3秒执行) * 检查红包是否需要托领取(每3秒执行)
*/ */
@@ -470,10 +478,26 @@ public class GameJob {
*/ */
public void botSendRp(Long roundId, Long groupId) { public void botSendRp(Long roundId, Long groupId) {
GameRound round = gameRoundMapper.selectById(roundId); GameRound round = gameRoundMapper.selectById(roundId);
if (round == null || round.getTargetDigit() == null) { if (round == null) {
return; return;
} }
// 仅在"开始发红包"状态下才执行,避免误触发
if (round.getStatus() == null || round.getStatus() != IGameService.STATUS_RP_SENDING) {
log.debug("本局{}当前状态非发红包中(status={}),机器人跳过发包",
roundId, round.getStatus());
return;
}
// 已有用户先发包,机器人不再重复发包(让用户的红包触发开奖)
if (round.getFirstRpId() != null) {
log.info("本局{}已有用户先发包(firstRpId={}),机器人跳过发包",
roundId, round.getFirstRpId());
return;
}
// 即使未设置目标尾数,机器人也会发包(由RedPacketService按随机金额处理)
// 查找机器人账号 // 查找机器人账号
User bot = userMapper.selectOne(new LambdaQueryWrapper<User>() User bot = userMapper.selectOne(new LambdaQueryWrapper<User>()
.eq(User::getIsBot, 1) .eq(User::getIsBot, 1)
@@ -485,17 +509,16 @@ public class GameJob {
} }
try { try {
// 机器人发1元3个包 // 从配置读取金额和数量,默认1元3个包
RedPacket rp = redPacketService.sendRp(bot.getId(), groupId, BigDecimal amount = new BigDecimal(getConfig("bot_rp_amount", "1"));
new BigDecimal("1"), 3, roundId); int count = getConfigInt("bot_rp_count", 3);
// 红包尾数控制: 需要在发红包时预计算各份额金额 // 机器人发包
// 确保手气王金额的尾数等于目标尾数 RedPacket rp = redPacketService.sendRp(bot.getId(), groupId, amount, count, roundId);
// 注: 当前实现中红包金额随机分配,实际生产需要调用RedPacketService控制尾数 log.info("机器人自动发包: roundId={}, rpId={}, amount={}, count={}, targetDigit={}",
log.info("机器人自动发包: roundId={}, rpId={}, targetDigit={}", roundId, rp.getId(), amount, count, round.getTargetDigit());
roundId, rp.getId(), round != null ? round.getTargetDigit() : "null");
} catch (Exception e) { } catch (Exception e) {
log.error("机器人发包失败: roundId={}, error={}", roundId, e.getMessage()); log.error("机器人发包失败: roundId={}, error={}", roundId, e.getMessage(), e);
} }
} }
@@ -43,6 +43,16 @@ public interface IGameService {
*/ */
GameRound getBettingRound(Long groupId); GameRound getBettingRound(Long groupId);
/**
* 获取群当前正在发红包的局
*/
GameRound getRpSendingRound(Long groupId);
/**
* 获取群当前可发红包的局(已封盘或正在发红包中)
*/
GameRound getActiveSendRound(Long groupId);
/** /**
* 生成期号 * 生成期号
*/ */
@@ -67,6 +67,31 @@ public class GameServiceImpl implements IGameService {
.last("LIMIT 1")); .last("LIMIT 1"));
} }
/**
* 获取群当前正在发红包的局
*/
@Override
public GameRound getRpSendingRound(Long groupId) {
return gameRoundMapper.selectOne(new LambdaQueryWrapper<GameRound>()
.eq(GameRound::getGroupId, groupId)
.eq(GameRound::getStatus, STATUS_RP_SENDING)
.orderByDesc(GameRound::getCreateTime)
.last("LIMIT 1"));
}
/**
* 获取群当前可发红包的局(已封盘或正在发红包中)
* 改尾数阶段已封盘也允许玩家发红包(普通游戏红包,无尾数控制)
*/
@Override
public GameRound getActiveSendRound(Long groupId) {
return gameRoundMapper.selectOne(new LambdaQueryWrapper<GameRound>()
.eq(GameRound::getGroupId, groupId)
.in(GameRound::getStatus, java.util.Arrays.asList(STATUS_BET_CLOSED, STATUS_RP_SENDING))
.orderByDesc(GameRound::getCreateTime)
.last("LIMIT 1"));
}
/** /**
* 生成期号 * 生成期号
*/ */