新增房间奖励红包功能

This commit is contained in:
tianfeng 2025-12-01 19:45:47 +08:00
parent d063ce5f0d
commit 85afa5c113
4 changed files with 101 additions and 5 deletions

View File

@ -32,6 +32,19 @@ public class RoomRedPacketRestController {
return roomRedPacketService.sendRedPacket(cmd);
}
/**
* 发送平台红包
*
* @eo.name 发送平台红包
* @eo.url /send-platform
* @eo.method post
* @eo.request-type json
*/
@PostMapping("/send-platform")
public RoomRedPacketCO sendPlatformRedPacket(@Valid @RequestBody SendRoomRedPacketCmd cmd) {
return roomRedPacketService.sendPlatformRedPacket(cmd);
}
/**
* 抢红包
*/

View File

@ -9,6 +9,7 @@ import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.other.app.convertor.RoomRedPacketAppConvertor;
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.SendPlatformRoomRedPacketCmd;
import com.red.circle.other.app.dto.cmd.SendRoomRedPacketCmd;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.gateway.RoomRedPacketGateway;
@ -56,7 +57,7 @@ public class SendRoomRedPacketCmdExe {
private final RoomProfileManagerService roomProfileManagerService;
/**
* 执行发红包
* 执行发红包用户红包
*/
@Transactional(rollbackFor = Exception.class)
public RoomRedPacketCO execute(SendRoomRedPacketCmd cmd) {
@ -72,7 +73,7 @@ public class SendRoomRedPacketCmdExe {
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(cmd.getExpireMinutes());
// 创建红包记录
RoomRedPacket redPacket = buildRedPacket(cmd, userId, packetId, expireTime);
RoomRedPacket redPacket = buildRedPacket(cmd, userId, packetId, expireTime, RoomRedPacketSourceType.USER);
roomRedPacketGateway.save(redPacket);
// 扣除用户金币同步调用钱包服务
@ -105,6 +106,55 @@ public class SendRoomRedPacketCmdExe {
return RoomRedPacketAppConvertor.toCO(redPacket);
}
/**
* 执行发平台红包
*/
@Transactional(rollbackFor = Exception.class)
public RoomRedPacketCO executePlatform(SendRoomRedPacketCmd cmd) {
// 平台红包固定参数
cmd.setPacketType(2);
// 参数校验
validateParams(cmd);
String packetId = IdWorkerUtils.getIdStr();
// 计算过期时间
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(cmd.getExpireMinutes());
// 创建平台红包记录
Long systemUserId = 0L;
RoomRedPacket redPacket = buildRedPacket(cmd, systemUserId, packetId, expireTime, RoomRedPacketSourceType.PLATFORM);
roomRedPacketGateway.save(redPacket);
// 预生成随机金额列表拼手气红包
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);
log.info("发平台红包成功 packetId={} roomId={} amount={} count={} ",
packetId, cmd.getRoomId(), cmd.getTotalAmount(), cmd.getTotalCount());
return RoomRedPacketAppConvertor.toCO(redPacket);
}
/**
* 发送消息通知
*/
private void sendMessage(SendRoomRedPacketCmd cmd, String packetId) {
try {
String roomAccount = roomProfileManagerService.getRoomAccount(cmd.getRoomId());
@ -135,7 +185,7 @@ public class SendRoomRedPacketCmdExe {
}
/**
* 参数校验
* 参数校验用户红包
*/
private void validateParams(SendRoomRedPacketCmd cmd) {
// 校验红包类型
@ -164,6 +214,26 @@ public class SendRoomRedPacketCmdExe {
}
}
/**
* 参数校验平台红包
*/
private void validatePlatformParams(SendPlatformRoomRedPacketCmd cmd) {
// 校验金额平台红包至少100金币
if (cmd.getTotalAmount() < 100) {
throw new RuntimeException("平台红包金额不能小于100金币");
}
// 校验个数
if (cmd.getTotalCount() < 1 || cmd.getTotalCount() > 100) {
throw new RuntimeException("红包个数必须在1-100之间");
}
// 校验平均金额至少1金币/
if (cmd.getTotalAmount() < cmd.getTotalCount()) {
throw new RuntimeException("红包总金额必须大于等于红包个数");
}
}
/**
* 扣除用户金币
*/
@ -189,13 +259,14 @@ public class SendRoomRedPacketCmdExe {
* 构建红包对象
*/
private RoomRedPacket buildRedPacket(SendRoomRedPacketCmd cmd, Long userId,
String packetId, LocalDateTime expireTime) {
String packetId, LocalDateTime expireTime,
RoomRedPacketSourceType sourceType) {
return RoomRedPacket.builder()
.packetId(packetId)
.roomId(cmd.getRoomId())
.userId(userId)
.packetType(cmd.getPacketType())
.sourceType(RoomRedPacketSourceType.USER.getCode()) // 用户红包
.sourceType(sourceType.getCode())
.totalAmount(cmd.getTotalAmount())
.totalCount(cmd.getTotalCount())
.remainAmount(cmd.getTotalAmount())
@ -249,6 +320,7 @@ public class SendRoomRedPacketCmdExe {
private void cacheRedPacketData(RoomRedPacket redPacket) {
Map<String, Object> packetData = new HashMap<>();
packetData.put("packetType", redPacket.getPacketType());
packetData.put("sourceType", redPacket.getSourceType());
packetData.put("totalAmount", redPacket.getTotalAmount());
packetData.put("totalCount", redPacket.getTotalCount());
packetData.put("remainAmount", redPacket.getRemainAmount());

View File

@ -10,6 +10,7 @@ import com.red.circle.other.app.dto.clientobject.RoomRedPacketDetailCO;
import com.red.circle.other.app.dto.cmd.GrabRoomRedPacketCmd;
import com.red.circle.other.app.dto.cmd.QueryRoomRedPacketDetailCmd;
import com.red.circle.other.app.dto.cmd.QueryRoomRedPacketListCmd;
import com.red.circle.other.app.dto.cmd.SendPlatformRoomRedPacketCmd;
import com.red.circle.other.app.dto.cmd.SendRoomRedPacketCmd;
import com.red.circle.other.app.util.DistributedLockUtil;
import lombok.RequiredArgsConstructor;
@ -37,6 +38,11 @@ public class RoomRedPacketServiceImpl implements RoomRedPacketService {
return sendRoomRedPacketCmdExe.execute(cmd);
}
@Override
public RoomRedPacketCO sendPlatformRedPacket(SendRoomRedPacketCmd cmd) {
return sendRoomRedPacketCmdExe.executePlatform(cmd);
}
@Override
public GrabRoomRedPacketResultCO grabRedPacket(GrabRoomRedPacketCmd cmd) {
String key = "room:red_packet:" + cmd.getPacketId() + ":" + cmd.getReqUserId();

View File

@ -20,6 +20,11 @@ public interface RoomRedPacketService {
*/
RoomRedPacketCO sendRedPacket(SendRoomRedPacketCmd cmd);
/**
* 发送平台红包
*/
RoomRedPacketCO sendPlatformRedPacket(SendRoomRedPacketCmd cmd);
/**
* 抢红包
*/