新增房间奖励红包功能

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); 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.RoomRedPacketAppConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor; 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.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.dto.cmd.SendRoomRedPacketCmd;
import com.red.circle.other.app.util.OfficialNoticeUtils; import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.gateway.RoomRedPacketGateway; import com.red.circle.other.domain.gateway.RoomRedPacketGateway;
@ -56,7 +57,7 @@ public class SendRoomRedPacketCmdExe {
private final RoomProfileManagerService roomProfileManagerService; private final RoomProfileManagerService roomProfileManagerService;
/** /**
* 执行发红包 * 执行发红包用户红包
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public RoomRedPacketCO execute(SendRoomRedPacketCmd cmd) { public RoomRedPacketCO execute(SendRoomRedPacketCmd cmd) {
@ -72,7 +73,7 @@ public class SendRoomRedPacketCmdExe {
LocalDateTime expireTime = LocalDateTime.now().plusMinutes(cmd.getExpireMinutes()); 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); roomRedPacketGateway.save(redPacket);
// 扣除用户金币同步调用钱包服务 // 扣除用户金币同步调用钱包服务
@ -105,6 +106,55 @@ public class SendRoomRedPacketCmdExe {
return RoomRedPacketAppConvertor.toCO(redPacket); 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) { private void sendMessage(SendRoomRedPacketCmd cmd, String packetId) {
try { try {
String roomAccount = roomProfileManagerService.getRoomAccount(cmd.getRoomId()); String roomAccount = roomProfileManagerService.getRoomAccount(cmd.getRoomId());
@ -135,7 +185,7 @@ public class SendRoomRedPacketCmdExe {
} }
/** /**
* 参数校验 * 参数校验用户红包
*/ */
private void validateParams(SendRoomRedPacketCmd cmd) { 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, private RoomRedPacket buildRedPacket(SendRoomRedPacketCmd cmd, Long userId,
String packetId, LocalDateTime expireTime) { String packetId, LocalDateTime expireTime,
RoomRedPacketSourceType sourceType) {
return RoomRedPacket.builder() return RoomRedPacket.builder()
.packetId(packetId) .packetId(packetId)
.roomId(cmd.getRoomId()) .roomId(cmd.getRoomId())
.userId(userId) .userId(userId)
.packetType(cmd.getPacketType()) .packetType(cmd.getPacketType())
.sourceType(RoomRedPacketSourceType.USER.getCode()) // 用户红包 .sourceType(sourceType.getCode())
.totalAmount(cmd.getTotalAmount()) .totalAmount(cmd.getTotalAmount())
.totalCount(cmd.getTotalCount()) .totalCount(cmd.getTotalCount())
.remainAmount(cmd.getTotalAmount()) .remainAmount(cmd.getTotalAmount())
@ -249,6 +320,7 @@ public class SendRoomRedPacketCmdExe {
private void cacheRedPacketData(RoomRedPacket redPacket) { private void cacheRedPacketData(RoomRedPacket redPacket) {
Map<String, Object> packetData = new HashMap<>(); Map<String, Object> packetData = new HashMap<>();
packetData.put("packetType", redPacket.getPacketType()); packetData.put("packetType", redPacket.getPacketType());
packetData.put("sourceType", redPacket.getSourceType());
packetData.put("totalAmount", redPacket.getTotalAmount()); packetData.put("totalAmount", redPacket.getTotalAmount());
packetData.put("totalCount", redPacket.getTotalCount()); packetData.put("totalCount", redPacket.getTotalCount());
packetData.put("remainAmount", redPacket.getRemainAmount()); 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.GrabRoomRedPacketCmd;
import com.red.circle.other.app.dto.cmd.QueryRoomRedPacketDetailCmd; 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.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.dto.cmd.SendRoomRedPacketCmd;
import com.red.circle.other.app.util.DistributedLockUtil; import com.red.circle.other.app.util.DistributedLockUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -37,6 +38,11 @@ public class RoomRedPacketServiceImpl implements RoomRedPacketService {
return sendRoomRedPacketCmdExe.execute(cmd); return sendRoomRedPacketCmdExe.execute(cmd);
} }
@Override
public RoomRedPacketCO sendPlatformRedPacket(SendRoomRedPacketCmd cmd) {
return sendRoomRedPacketCmdExe.executePlatform(cmd);
}
@Override @Override
public GrabRoomRedPacketResultCO grabRedPacket(GrabRoomRedPacketCmd cmd) { public GrabRoomRedPacketResultCO grabRedPacket(GrabRoomRedPacketCmd cmd) {
String key = "room:red_packet:" + cmd.getPacketId() + ":" + cmd.getReqUserId(); String key = "room:red_packet:" + cmd.getPacketId() + ":" + cmd.getReqUserId();

View File

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