火箭问题处理

This commit is contained in:
tianfeng 2025-11-13 12:19:48 +08:00
parent f2a73010b4
commit ea9ded11b9
9 changed files with 94 additions and 67 deletions

View File

@ -50,12 +50,4 @@ public class RocketRestController {
public RocketRewardCO claimReward(@Valid @RequestBody RocketRewardClaimCmd cmd) {
return rocketService.claimReward(cmd);
}
/**
* 手动触发发射 (测试用)
*/
// @PostMapping("/manual-launch")
public void manualLaunch(@RequestParam Long roomId) {
rocketService.manualLaunch(roomId);
}
}

View File

@ -1,22 +1,32 @@
package com.red.circle.other.app.command.rocket;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.external.inner.model.cmd.message.BroadcastGroupMsgBodyCmd;
import com.red.circle.external.inner.model.enums.message.GroupMessageTypeEnum;
import com.red.circle.other.app.convertor.RocketConvertor;
import com.red.circle.other.app.convertor.user.UserProfileAppConvertor;
import com.red.circle.other.app.dto.clientobject.RocketStatusCO;
import com.red.circle.other.app.manager.RocketImPushManager;
import com.red.circle.other.app.util.DistributedLockUtil;
import com.red.circle.other.app.util.OfficialNoticeUtils;
import com.red.circle.other.domain.gateway.RocketConfigGateway;
import com.red.circle.other.domain.gateway.RocketHistoryGateway;
import com.red.circle.other.domain.gateway.RocketStatusGateway;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.rocket.RocketHistory;
import com.red.circle.other.domain.rocket.RocketStatus;
import com.red.circle.other.domain.rocket.RocketStatusEnum;
import com.red.circle.other.infra.database.cache.key.RocketKeys;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.inner.model.dto.user.UserProfileDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Map;
/**
* 火箭发射命令执行器
@ -36,15 +46,20 @@ public class RocketLaunchCmdExe {
private final RocketImPushManager rocketImPushManager;
private final RocketConfigGateway rocketConfigGateway;
private final RoomProfileManagerService roomProfileManagerService;
private final ImGroupClient imGroupClient;
private final UserProfileGateway userProfileGateway;
private final UserProfileAppConvertor userProfileAppConvertor;
/**
* 执行火箭发射
* @param roomId 房间ID
* @param triggerUserId 触发升级的用户ID
*/
public void execute(Long roomId) {
public void execute(Long roomId, Long triggerUserId) {
String lockKey = RocketKeys.LOCK.getKey(roomId);
distributedLockUtil.executeWithLock(lockKey, 10L, () -> {
doLaunch(roomId);
doLaunch(roomId, triggerUserId);
return null;
}, "火箭发射操作过于频繁,请稍后重试");
}
@ -52,7 +67,7 @@ public class RocketLaunchCmdExe {
/**
* 执行发射逻辑
*/
private void doLaunch(Long roomId) {
private void doLaunch(Long roomId, Long triggerUserId) {
// 1. 查询当前火箭状态需要完整数据包含贡献者
String today = LocalDate.now().toString();
RocketStatus rocketStatus = rocketStatusGateway.findByRoomIdAndDate(roomId, today);
@ -82,6 +97,7 @@ public class RocketLaunchCmdExe {
// 5. 保存历史记录发射前保存保留贡献者信息
try {
rocketStatus.setLaunchTime(LocalDateTime.now());
RocketHistory history = RocketHistory.fromRocketStatus(rocketStatus);
String historyId = rocketHistoryGateway.save(history);
log.info("保存火箭历史记录成功: historyId={}, roomId={}, level={}", historyId, roomId, launchedLevel);
@ -89,39 +105,59 @@ public class RocketLaunchCmdExe {
log.error("保存火箭历史记录失败: roomId={}", roomId, e);
}
// 6. 推送发射动画消息发射前推送包含贡献者信息
try {
RocketStatusCO statusCO = RocketConvertor.toStatusCO(rocketStatus);
rocketImPushManager.pushRocketLaunch( statusCO);
} catch (Exception e) {
log.error("推送火箭发射消息失败: roomId={}", roomId, e);
}
// 7. 发射并自动升级到下一级
rocketStatus.launchAndUpgrade(rocketConfigGateway);
// 8. 保存新状态
rocketStatusGateway.save(rocketStatus);
log.info("火箭发射并升级成功: roomId={}, 发射等级={}, 最终能量={}, 贡献者数={}, 升级到={}",
// 9. 广播升级消息带触发用户信息
try {
broadcastRocketUpgrade(roomId, launchedLevel, rocketStatus.getLevel().getLevel(), triggerUserId);
} catch (Exception e) {
log.error("广播火箭升级消息失败: roomId={}", roomId, e);
}
log.info("火箭发射并升级成功: roomId={}, 发射等级={}, 最终能量={}, 贡献者数={}, 升级到={}, 触发用户={}",
roomId,
launchedLevel,
finalEnergy,
contributorCount,
rocketStatus.getLevel().getLevel());
rocketStatus.getLevel().getLevel(),
triggerUserId);
// 9. 如果升级成功推送升级消息
if (rocketStatus.getLevel().getLevel() > launchedLevel) {
try {
RocketStatusCO newStatusCO = RocketConvertor.toStatusCO(rocketStatus);
String roomAccount = roomProfileManagerService.getRoomAccount(roomId);
rocketImPushManager.pushEnergyUpdate(roomAccount, newStatusCO);
String upgradeMsg = launchedLevel == 3 ? "重置为一级火箭" : "升级到" + rocketStatus.getLevel().getName();
log.info("推送火箭升级消息: roomId={}, {}", roomId, upgradeMsg);
} catch (Exception e) {
log.error("推送火箭升级消息失败: roomId={}", roomId, e);
}
// 10. 推送升级后的状态消息
try {
RocketStatusCO newStatusCO = RocketConvertor.toStatusCO(rocketStatus);
String roomAccount = roomProfileManagerService.getRoomAccount(roomId);
rocketImPushManager.pushEnergyUpdate(roomAccount, newStatusCO);
} catch (Exception e) {
log.error("推送火箭升级消息失败: roomId={}", roomId, e);
}
}
/**
* 广播火箭升级消息
*/
private void broadcastRocketUpgrade(Long roomId, int fromLevel, int toLevel, Long triggerUserId) {
try {
UserProfileDTO userProfile = userProfileAppConvertor.toUserProfileDTO(
userProfileGateway.getByUserId(triggerUserId));
Map<Object, Object> build = OfficialNoticeUtils.buildUserProfile(userProfile);
build.put("roomId", roomId);
build.put("fromLevel", fromLevel);
// build.put("toLevel", toLevel);
imGroupClient.sendMessageBroadcast(
BroadcastGroupMsgBodyCmd.builder()
.toPlatform(SysOriginPlatformEnum.LIKEI)
.type(GroupMessageTypeEnum.ROCKET_ENERGY_LAUNCH)
.data(build)
.build()
);
} catch (Exception e) {
log.error("广播火箭升级消息失败: roomId={}, triggerUserId={}", roomId, triggerUserId, e);
throw e;
}
}
}

View File

@ -118,16 +118,6 @@ public class RocketRewardClaimCmdExe {
// 8. 保存领取记录
saveRewardLog(roomId, userId, latestHistory, selectedReward, walletBizNo);
// 9. 推送领取成功消息
try {
String userName = "用户" + userId;
Long rewardAmount = getRewardAmount(selectedReward);
rocketImPushManager.pushRewardClaimed(roomId, userId, userName, rewardAmount);
} catch (Exception e) {
log.error("推送奖励领取消息失败: roomId={}, userId={}", roomId, userId, e);
}
// 10. 构建返回结果
RocketRewardCO rewardCO = new RocketRewardCO();
rewardCO.setRewardType(selectedReward.getType());

View File

@ -154,33 +154,52 @@ public class RocketEnergyAggregator {
return;
}
// 3. 批量增加能量
// 3. 记录增加能量前的状态
long energyBeforeAdd = rocketStatus.getCurrentEnergy();
long maxEnergy = rocketStatus.getMaxEnergy();
// 4. 批量增加能量并找出触发升级的用户
long totalEnergy = 0L;
Long triggerUserId = null;
for (RocketEnergyAddCmd cmd : batch) {
// 增加前的能量
long beforeEnergy = rocketStatus.getCurrentEnergy();
// 增加能量
rocketStatus.addEnergy(
cmd.getUserId(),
cmd.getGiftGoldValue()
);
totalEnergy += cmd.getGiftGoldValue();
// 增加后的能量
long afterEnergy = rocketStatus.getCurrentEnergy();
// 判断是否是这个用户触发了满能量
if (beforeEnergy < maxEnergy && afterEnergy >= maxEnergy && triggerUserId == null) {
triggerUserId = cmd.getUserId();
log.info("找到触发升级的用户: userId={}, beforeEnergy={}, afterEnergy={}, maxEnergy={}",
triggerUserId, beforeEnergy, afterEnergy, maxEnergy);
}
}
// 4. 保存状态一次性保存
// 5. 保存状态一次性保存
rocketStatusGateway.save(rocketStatus);
log.info("批量增加火箭能量: roomId={}, 批次数量={}, 总能量={}, 当前能量={}/{}",
roomId, batch.size(), totalEnergy,
rocketStatus.getCurrentEnergy(), rocketStatus.getMaxEnergy());
// 5. 推送更新消息节流
// 6. 推送更新消息节流
pushEnergyUpdate(roomId, rocketStatus);
// 6. 检查是否需要发射
// 7. 检查是否需要发射
if (rocketStatus.isFullEnergy()) {
log.info("火箭能量已满, 准备发射, roomId={}, level={}",
roomId, rocketStatus.getLevel().getLevel());
log.info("火箭能量已满, 准备发射, roomId={}, level={}, 触发用户={}",
roomId, rocketStatus.getLevel().getLevel(), triggerUserId);
// 异步触发发射
rocketLaunchManager.launchAsync(roomId);
// 异步触发发射传入触发用户信息
rocketLaunchManager.launchAsync(roomId, triggerUserId);
}
}

View File

@ -22,12 +22,14 @@ public class RocketLaunchManager {
/**
* 异步发射火箭
* @param roomId 房间ID
* @param triggerUserId 触发用户ID
*/
@Async("rocketTaskExecutor")
public void launchAsync(Long roomId) {
public void launchAsync(Long roomId, Long triggerUserId) {
try {
log.info("异步执行火箭发射: roomId={}", roomId);
rocketLaunchCmdExe.execute(roomId);
log.info("异步执行火箭发射: roomId={}, 触发用户={}", roomId, triggerUserId);
rocketLaunchCmdExe.execute(roomId, triggerUserId);
} catch (Exception e) {
log.error("异步火箭发射失败: roomId={}", roomId, e);
}

View File

@ -43,9 +43,4 @@ public class RocketServiceImpl implements RocketService {
public RocketRewardCO claimReward(RocketRewardClaimCmd cmd) {
return rocketRewardClaimCmdExe.execute(cmd);
}
@Override
public void manualLaunch(Long roomId) {
rocketLaunchCmdExe.execute(roomId);
}
}

View File

@ -28,9 +28,4 @@ public interface RocketService {
* 领取奖励
*/
RocketRewardCO claimReward(RocketRewardClaimCmd cmd);
/**
* 手动触发火箭发射 (测试用)
*/
void manualLaunch(Long roomId);
}

View File

@ -116,8 +116,6 @@ public class RocketHistory {
// 设置时间
history.setLaunchTime(status.getLaunchTime());
history.setClaimStartTime(status.getLaunchTime());
history.setClaimEndTime(status.getClaimExpireTime());
history.setCreatedAt(LocalDateTime.now());
history.setUpdatedAt(LocalDateTime.now());

View File

@ -17,7 +17,7 @@ import java.util.List;
*/
@Data
@Document(collection = "room_rocket_status")
@CompoundIndex(name = "uk_room_date", def = "{'room_id': 1, 'date': 1}", unique = true)
@CompoundIndex(name = "uk_room_date", def = "{'roomId': 1, 'date': 1}", unique = true)
public class RocketStatusDocument {
/**