diff --git a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RoomRedPacketRestController.java b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RoomRedPacketRestController.java index e19b9fcc..88d9b320 100644 --- a/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RoomRedPacketRestController.java +++ b/rc-service/rc-service-other/other-adapter/src/main/java/com/red/circle/other/adapter/app/RoomRedPacketRestController.java @@ -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); + } + /** * 抢红包 */ diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/redpacket/SendRoomRedPacketCmdExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/redpacket/SendRoomRedPacketCmdExe.java index 29c1b9fc..bc35f10d 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/redpacket/SendRoomRedPacketCmdExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/redpacket/SendRoomRedPacketCmdExe.java @@ -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 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 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()); diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/RoomRedPacketServiceImpl.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/RoomRedPacketServiceImpl.java index 3d831b9e..5b29979e 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/RoomRedPacketServiceImpl.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/RoomRedPacketServiceImpl.java @@ -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(); diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/RoomRedPacketService.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/RoomRedPacketService.java index e216a5f0..8e9083da 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/RoomRedPacketService.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/service/RoomRedPacketService.java @@ -20,6 +20,11 @@ public interface RoomRedPacketService { */ RoomRedPacketCO sendRedPacket(SendRoomRedPacketCmd cmd); + /** + * 发送平台红包 + */ + RoomRedPacketCO sendPlatformRedPacket(SendRoomRedPacketCmd cmd); + /** * 抢红包 */