From 7f96115a6ad14f1c055bac367cd577f0e7e0bac4 Mon Sep 17 00:00:00 2001 From: wells <123456@qq.com> Date: Wed, 5 Aug 2026 18:18:49 +0800 Subject: [PATCH] =?UTF-8?q?fix=20=E9=A2=86=E7=BA=A2=E5=8C=85=E5=8A=A0?= =?UTF-8?q?=E9=94=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RedPacketController.java | 8 +- src/main/java/com/tailbet/job/GameJob.java | 78 ++++++++++++++----- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/tailbet/controller/RedPacketController.java b/src/main/java/com/tailbet/controller/RedPacketController.java index 2f643b0..a590876 100644 --- a/src/main/java/com/tailbet/controller/RedPacketController.java +++ b/src/main/java/com/tailbet/controller/RedPacketController.java @@ -7,6 +7,7 @@ import com.tailbet.model.entity.RedPacketRecv; import com.tailbet.model.vo.R; import com.tailbet.model.vo.UserContext; import com.tailbet.service.IRedPacketService; +import com.tailbet.util.RedisLockUtil; import lombok.RequiredArgsConstructor; import org.springframework.web.bind.annotation.*; @@ -42,7 +43,12 @@ public class RedPacketController { public R receiveRp(@RequestBody ReceiveRpDTO dto) { try { Long userId = UserContext.getUserId(); - var recv = redPacketService.receiveRp(dto.getRpId(), userId); + // 使用分布式锁防止多领 + var recv = RedisLockUtil.lock("rp:receive:" + dto.getRpId(), + () -> redPacketService.receiveRp(dto.getRpId(), userId)); + if (recv == null) { + return R.fail("领取失败,请重试"); + } return R.ok(recv); } catch (RuntimeException e) { return R.fail(e.getMessage()); diff --git a/src/main/java/com/tailbet/job/GameJob.java b/src/main/java/com/tailbet/job/GameJob.java index c9e91ae..00494ed 100644 --- a/src/main/java/com/tailbet/job/GameJob.java +++ b/src/main/java/com/tailbet/job/GameJob.java @@ -3,21 +3,22 @@ package com.tailbet.job; import com.tailbet.model.entity.GameRound; import com.tailbet.model.entity.RedPacket; import com.tailbet.model.entity.User; +import com.tailbet.mapper.DrawRecordMapper; +import com.tailbet.mapper.DigitWhiteMapper; import com.tailbet.mapper.GameRoundMapper; import com.tailbet.mapper.RedPacketMapper; import com.tailbet.mapper.RedPacketRecvMapper; -import com.tailbet.mapper.UserMapper; -import com.tailbet.mapper.DigitWhiteMapper; -import com.tailbet.mapper.DrawRecordMapper; import com.tailbet.mapper.SysConfigMapper; +import com.tailbet.mapper.UserMapper; import com.tailbet.model.entity.DigitWhite; import com.tailbet.model.entity.DrawRecord; import com.tailbet.model.entity.RedPacketRecv; import com.tailbet.model.entity.SysConfig; +import com.tailbet.openim.OpenIMClient; import com.tailbet.service.IGameService; import com.tailbet.service.IRedPacketService; import com.tailbet.service.IFakeUserService; -import com.tailbet.openim.OpenIMClient; +import com.tailbet.util.RedisLockUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -161,13 +162,15 @@ public class GameJob { break; } + final User fakeUser = fakeToUse; try { - redPacketService.receiveRp(rp.getId(), fakeToUse.getId()); + // 使用分布式锁防止多领 + RedisLockUtil.lock("rp:receive:" + rp.getId(), + () -> redPacketService.receiveRp(rp.getId(), fakeUser.getId())); log.info("假人{}领取红包{}剩余份额", fakeToUse.getId(), rp.getId()); + } catch (Exception e) { - log.error("假人领取红包失败: rpId={}, fakeId={}, error={}", rp.getId(), fakeToUse.getId(), e.getMessage()); - // 可能是红包已领完,退出循环 - break; + log.error("假人领取红包失败: rpId={}, fakeId={}, error={}", rp.getId(), fakeUser.getId(), e.getMessage()); } } } @@ -493,18 +496,53 @@ public class GameJob { private Integer digit; private LocalDateTime executeTime; - public String getTaskId() { return taskId; } - public void setTaskId(String taskId) { this.taskId = taskId; } - public String getType() { return type; } - public void setType(String type) { this.type = type; } - public Long getRoundId() { return roundId; } - public void setRoundId(Long roundId) { this.roundId = roundId; } - public Long getGroupId() { return groupId; } - public void setGroupId(Long groupId) { this.groupId = groupId; } - public Integer getDigit() { return digit; } - public void setDigit(Integer digit) { this.digit = digit; } - public LocalDateTime getExecuteTime() { return executeTime; } - public void setExecuteTime(LocalDateTime executeTime) { this.executeTime = executeTime; } + public String getTaskId() { + return taskId; + } + + public void setTaskId(String taskId) { + this.taskId = taskId; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Long getRoundId() { + return roundId; + } + + public void setRoundId(Long roundId) { + this.roundId = roundId; + } + + public Long getGroupId() { + return groupId; + } + + public void setGroupId(Long groupId) { + this.groupId = groupId; + } + + public Integer getDigit() { + return digit; + } + + public void setDigit(Integer digit) { + this.digit = digit; + } + + public LocalDateTime getExecuteTime() { + return executeTime; + } + + public void setExecuteTime(LocalDateTime executeTime) { + this.executeTime = executeTime; + } } /**