From 0be2965c8b02d142637c5b56dc79ff6f4e90bf22 Mon Sep 17 00:00:00 2001 From: tianfeng <769204422@qq.com> Date: Wed, 19 Nov 2025 15:53:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=88=BF=E9=97=B4=E5=88=97=E8=A1=A8=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E7=81=AB=E7=AE=AD=E7=8A=B6=E6=80=81=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../command/rocket/RocketLaunchCmdExe.java | 6 ++ .../room/query/RoomVoiceDiscoverQryExe.java | 34 +++++++ .../app/scheduler/RocketStatusSyncTask.java | 56 +++++++++++ .../room/RocketStatusCacheService.java | 92 +++++++++++++++++++ .../clientobject/room/RoomVoiceProfileCO.java | 11 +++ .../domain/gateway/RocketStatusGateway.java | 8 ++ .../repository/RocketStatusRepository.java | 8 ++ .../gateway/RocketStatusGatewayImpl.java | 9 ++ .../src/test/java/DailTaskTest.java | 9 ++ 9 files changed, 233 insertions(+) create mode 100644 rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/RocketStatusSyncTask.java create mode 100644 rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/room/RocketStatusCacheService.java diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketLaunchCmdExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketLaunchCmdExe.java index 43ee6bb0..6508d9e1 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketLaunchCmdExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/rocket/RocketLaunchCmdExe.java @@ -10,6 +10,7 @@ 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.service.room.RocketStatusCacheService; import com.red.circle.other.app.util.DistributedLockUtil; import com.red.circle.other.app.util.OfficialNoticeUtils; import com.red.circle.other.domain.gateway.RocketConfigGateway; @@ -29,6 +30,7 @@ import org.springframework.stereotype.Component; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -55,6 +57,7 @@ public class RocketLaunchCmdExe { private final UserProfileAppConvertor userProfileAppConvertor; private final RocketRewardClaimCmdExe rocketRewardClaimCmdExe; private final LiveRoomUserClient liveRoomUserClient; + private final RocketStatusCacheService rocketStatusCacheService; /** * 执行火箭发射 @@ -137,6 +140,9 @@ public class RocketLaunchCmdExe { log.error("广播火箭升级消息失败: roomId={}", roomId, e); } + // 设置新的火箭状态 + rocketStatusCacheService.batchSetRocketStatus(List.of(rocketStatus)); + String roomAccount = roomProfileManagerService.getRoomAccount(roomId); // 给所有在线的用户发送奖励 diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceDiscoverQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceDiscoverQryExe.java index 03cc1013..093d35ad 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceDiscoverQryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceDiscoverQryExe.java @@ -8,8 +8,10 @@ import com.red.circle.common.business.enums.SVIPLevelEnum; import com.red.circle.live.inner.endpoint.LiveMicClient; import com.red.circle.other.app.common.room.RoomVoiceProfileCommon; import com.red.circle.other.app.dto.clientobject.room.RoomVoiceProfileCO; +import com.red.circle.other.app.service.room.RocketStatusCacheService; import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway; import com.red.circle.other.domain.gateway.user.ability.UserSVipGateway; +import com.red.circle.other.domain.rocket.RocketStatus; import com.red.circle.other.infra.database.cache.service.user.RegionRoomCacheService; import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom; import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager; @@ -55,6 +57,7 @@ public class RoomVoiceDiscoverQryExe { private final RegionRoomCacheService regionRoomCacheService; private final LiveMicClient liveMicClient; private final RedisTemplate redisTemplate; + private final RocketStatusCacheService rocketStatusCacheService; private static final String EMPTY_ROOM_CACHE_KEY = "empty_room_cache:*"; @@ -113,9 +116,40 @@ public class RoomVoiceDiscoverQryExe { room.setUserSVipLevel(svipLevelEnumMap.get(room.getUserId())); }) .toList(); + + // 填充火箭状态 + fillRocketStatus(roomList); + return roomList; } + /** + * 填充房间的火箭状态信息 + * + * @param roomList 房间列表 + */ + private void fillRocketStatus(List roomList) { + if (CollectionUtils.isEmpty(roomList)) { + return; + } + + List roomIds = roomList.stream().map(RoomVoiceProfileCO::getId).toList(); + Map rocketStatusMap = rocketStatusCacheService.batchGetRocketStatus(roomIds); + + roomList.forEach(room -> { + RocketStatus rocketStatus = rocketStatusMap.get(room.getId()); + if (rocketStatus != null) { + room.setRocketLevel(rocketStatus.getLevel().getLevel()); + room.setRocketEnergy(rocketStatus.getCurrentEnergy()); + } else { + // 没有火箭状态时设置默认值 + room.setRocketLevel(0); + room.setRocketEnergy(0L); + } + }); + } + + /** * 筛选有人房间,删除没人房间 * diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/RocketStatusSyncTask.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/RocketStatusSyncTask.java new file mode 100644 index 00000000..1f3dfdb1 --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/RocketStatusSyncTask.java @@ -0,0 +1,56 @@ +// 路径: rc-service-other/other-application/src/main/java/com/red/circle/other/app/scheduler/RocketStatusSyncTask.java + +package com.red.circle.other.app.scheduler; + +import cn.hutool.core.date.DateUtil; +import com.red.circle.other.app.service.room.RocketStatusCacheService; +import com.red.circle.other.domain.gateway.RocketStatusGateway; +import com.red.circle.other.domain.rocket.RocketStatus; +import com.red.circle.tool.core.date.ZonedDateTimeAsiaRiyadhUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; +import org.springframework.util.CollectionUtils; + +import java.util.Date; +import java.util.List; + +/** + * 火箭状态同步定时任务 + * 每5分钟同步一次所有房间的火箭状态到缓存 + */ +@Slf4j +@Component +@RequiredArgsConstructor +public class RocketStatusSyncTask { + + private final RocketStatusGateway rocketStatusGateway; + private final RocketStatusCacheService rocketStatusCacheService; + + /** + * 每5分钟同步一次火箭状态 + */ + @Scheduled(cron = "0 */5 * * * ?") + public void syncRocketStatus() { + try { + // 获取当前日期 格式: yyyyMMdd + String riyadhToday = ZonedDateTimeAsiaRiyadhUtils.nowFormat("yyyy-MM-dd"); + + // 查询今天所有房间的火箭状态 + List rocketStatusList = rocketStatusGateway.listByDate(riyadhToday); + + if (CollectionUtils.isEmpty(rocketStatusList)) { + log.info("火箭状态同步完成,当前无活跃火箭"); + return; + } + + // 批量更新缓存 + rocketStatusCacheService.batchSetRocketStatus(rocketStatusList); + + log.info("火箭状态同步完成,同步数量: {}", rocketStatusList.size()); + } catch (Exception e) { + log.error("火箭状态同步失败", e); + } + } +} \ No newline at end of file diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/room/RocketStatusCacheService.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/room/RocketStatusCacheService.java new file mode 100644 index 00000000..adaa658c --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/service/room/RocketStatusCacheService.java @@ -0,0 +1,92 @@ +// 路径: rc-service-other/other-application/src/main/java/com/red/circle/other/app/common/RocketStatusCacheService.java + +package com.red.circle.other.app.service.room; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.red.circle.other.domain.rocket.RocketStatus; +import com.red.circle.tool.core.collection.CollectionUtils; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +/** + * 火箭状态缓存服务 + */ +@Slf4j +@Service +@RequiredArgsConstructor +public class RocketStatusCacheService { + + private final RedisTemplate redisTemplate; + + private static final String ROCKET_STATUS_KEY = "room:rocket:status:"; + private static final long CACHE_EXPIRE_MINUTES = 10; + + /** + * 批量设置火箭状态缓存 + * + * @param rocketStatusList 火箭状态列表 + */ + public void batchSetRocketStatus(List rocketStatusList) { + if (CollectionUtils.isEmpty(rocketStatusList)) { + return; + } + + Map cacheMap = new HashMap<>(); + for (RocketStatus status : rocketStatusList) { + String key = ROCKET_STATUS_KEY + status.getRoomId(); + cacheMap.put(key, JSON.toJSONString(status)); + } + + // 批量设置缓存 + redisTemplate.opsForValue().multiSet(cacheMap); + + // 设置过期时间 + for (String key : cacheMap.keySet()) { + redisTemplate.expire(key, CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES); + } + } + + /** + * 获取房间火箭状态 + * + * @param roomId 房间ID + * @return 火箭状态 + */ + public RocketStatus getRocketStatus(Long roomId) { + String key = ROCKET_STATUS_KEY + roomId; + try { + return JSON.parseObject((String) redisTemplate.opsForValue().get(key), RocketStatus.class); + } catch (Exception e) { + } + return null; + } + + /** + * 批量获取房间火箭状态 + * + * @param roomIds 房间ID列表 + * @return 房间ID -> 火箭状态 映射 + */ + public Map batchGetRocketStatus(List roomIds) { + if (CollectionUtils.isEmpty(roomIds)) { + return new HashMap<>(); + } + + Map resultMap = new HashMap<>(); + for (Long roomId : roomIds) { + RocketStatus status = getRocketStatus(roomId); + if (status != null) { + resultMap.put(roomId, status); + } + } + return resultMap; + } +} \ No newline at end of file diff --git a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/room/RoomVoiceProfileCO.java b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/room/RoomVoiceProfileCO.java index 65b115e8..38a1cf2b 100644 --- a/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/room/RoomVoiceProfileCO.java +++ b/rc-service/rc-service-other/other-client/src/main/java/com/red/circle/other/app/dto/clientobject/room/RoomVoiceProfileCO.java @@ -135,6 +135,17 @@ public class RoomVoiceProfileCO extends ClientObject { */ private SVIPLevelEnum userSVipLevel; + + /** + * 火箭等级 (1-3) + */ + private Integer rocketLevel; + + /** + * 火箭能量值 + */ + private Long rocketEnergy; + /** * 设置房间成员数量. */ diff --git a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/RocketStatusGateway.java b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/RocketStatusGateway.java index 340e98f1..e671ce15 100644 --- a/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/RocketStatusGateway.java +++ b/rc-service/rc-service-other/other-domain/src/main/java/com/red/circle/other/domain/gateway/RocketStatusGateway.java @@ -36,4 +36,12 @@ public interface RocketStatusGateway { * 删除火箭状态 */ void delete(String id); + + /** + * 根据日期查询所有火箭状态 + * + * @param date 日期字符串 格式: yyyyMMdd + * @return 火箭状态列表 + */ + List listByDate(String date); } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java index 4f58ea4e..01779381 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/repository/RocketStatusRepository.java @@ -59,4 +59,12 @@ public interface RocketStatusRepository extends MongoRepository findAllByDate(String date); } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java index 2ba57d99..4b7929bc 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/gateway/RocketStatusGatewayImpl.java @@ -189,4 +189,13 @@ public class RocketStatusGatewayImpl implements RocketStatusGateway { doc.setUpdatedAt(status.getUpdatedAt()); return doc; } + + @Override + public List listByDate(String date) { + List documents = rocketStatusRepository.findAllByDate(date); + return documents.stream() + .map(this::toDomain) + .collect(Collectors.toList()); + } + } diff --git a/rc-service/rc-service-other/other-start/src/test/java/DailTaskTest.java b/rc-service/rc-service-other/other-start/src/test/java/DailTaskTest.java index 587f005f..f196e2c6 100644 --- a/rc-service/rc-service-other/other-start/src/test/java/DailTaskTest.java +++ b/rc-service/rc-service-other/other-start/src/test/java/DailTaskTest.java @@ -1,6 +1,8 @@ import com.red.circle.OtherServiceApplication; import com.red.circle.other.app.scheduler.DailyTask; import com.red.circle.other.app.scheduler.RankingActivityRewardTask; +import com.red.circle.other.app.scheduler.RocketStatusSyncTask; +import com.red.circle.other.app.service.room.RocketStatusCacheService; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -15,6 +17,8 @@ public class DailTaskTest { private DailyTask dailyTask; @Autowired private RankingActivityRewardTask rankingActivityRewardTask; + @Autowired + private RocketStatusSyncTask rocketStatusSyncTask; @Test public void DailTaskTest() { @@ -26,4 +30,9 @@ public class DailTaskTest { rankingActivityRewardTask.sendRankingActivityReward(); } + @Test + public void DailTaskTest3() { + rocketStatusSyncTask.syncRocketStatus(); + } + }