From 4c448efe229ec7b8e467eefcb0929072a472f91d Mon Sep 17 00:00:00 2001 From: tianfeng <769204422@qq.com> Date: Tue, 16 Sep 2025 20:20:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B2=A1=E4=BA=BA=E7=9A=84=E6=88=BF=E9=97=B4?= =?UTF-8?q?=E7=BC=93=E5=AD=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../live/api/ActiveVoiceRoomClientApi.java | 5 +- .../model/dto/live/ActiveVoiceRoomCO.java | 103 +++++++++++ .../app/command/user/LiveQuitRoomExe.java | 26 +++ .../room/query/RoomVoiceDiscoverQryExe.java | 175 +++++++++++++++++- .../room/ActiveVoiceRoomClientEndpoint.java | 13 +- .../live/ActiveVoiceRoomClientService.java | 6 + .../ActiveVoiceRoomClientServiceImpl.java | 77 ++++++++ 7 files changed, 396 insertions(+), 9 deletions(-) create mode 100644 rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/live/ActiveVoiceRoomCO.java diff --git a/rc-service/rc-inner-api/other-inner/other-inner-api/src/main/java/com/red/circle/other/inner/endpoint/live/api/ActiveVoiceRoomClientApi.java b/rc-service/rc-inner-api/other-inner/other-inner-api/src/main/java/com/red/circle/other/inner/endpoint/live/api/ActiveVoiceRoomClientApi.java index 2febc42d..4f1a6540 100644 --- a/rc-service/rc-inner-api/other-inner/other-inner-api/src/main/java/com/red/circle/other/inner/endpoint/live/api/ActiveVoiceRoomClientApi.java +++ b/rc-service/rc-inner-api/other-inner/other-inner-api/src/main/java/com/red/circle/other/inner/endpoint/live/api/ActiveVoiceRoomClientApi.java @@ -1,9 +1,9 @@ package com.red.circle.other.inner.endpoint.live.api; -import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; import com.red.circle.framework.dto.ResultResponse; import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd; +import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomCO; import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomDTO; import java.util.List; import org.springframework.web.bind.annotation.GetMapping; @@ -30,4 +30,7 @@ public interface ActiveVoiceRoomClientApi { @PostMapping("/listOps") ResultResponse> listOps(@RequestBody AppActiveVoiceRoomQryCmd qryCmd); + @GetMapping("/createNoBody") + ResultResponse createNoBodyRoom(@RequestParam("roomId") Long roomId); + } diff --git a/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/live/ActiveVoiceRoomCO.java b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/live/ActiveVoiceRoomCO.java new file mode 100644 index 00000000..be64262a --- /dev/null +++ b/rc-service/rc-inner-api/other-inner/other-inner-model/src/main/java/com/red/circle/other/inner/model/dto/live/ActiveVoiceRoomCO.java @@ -0,0 +1,103 @@ +package com.red.circle.other.inner.model.dto.live; + +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.sql.Timestamp; + +/** + * 活跃语音房间 copy + */ +@Data +public class ActiveVoiceRoomCO implements Serializable { + + @Serial + private static final long serialVersionUID = 1L; + + /** + * id. + */ + @JsonSerialize(using = ToStringSerializer.class) + Long id; + + /** + * 时序ID每次创建刷新. + */ + @JsonSerialize(using = ToStringSerializer.class) + Long timeId; + + /** + * 归属系统平台. + */ + String sysOrigin; + + /** + * 房主id. + */ + @JsonSerialize(using = ToStringSerializer.class) + Long userId; + + /** + * 房间account. + */ + String roomAccount; + + /** + * SVip等级. + */ + String superVipLevel; + + /** + * 热门房间(true 不是热门, false 热门). + */ + Boolean hot; + + /** + * 置顶房间. + */ + Integer fixedWeights; + + /** + * 国家code. + */ + String countryCode; + + /** + * 国家名字. + */ + String countryName; + + /** + * 区域. + */ + String region; + + /** + * 在线数量. + */ + Long onlineQuantity; + + /** + * 权重. + */ + Integer weights; + + /** + * 过期时间. + */ + Timestamp expiredTime; + + /** + * 创建时间. + */ + Timestamp createTime; + + /** + * 修改时间. + */ + Timestamp updateTime; + +} diff --git a/rc-service/rc-service-live/live-application/src/main/java/com/red/circle/live/app/command/user/LiveQuitRoomExe.java b/rc-service/rc-service-live/live-application/src/main/java/com/red/circle/live/app/command/user/LiveQuitRoomExe.java index 4f8384b1..fe59ce79 100644 --- a/rc-service/rc-service-live/live-application/src/main/java/com/red/circle/live/app/command/user/LiveQuitRoomExe.java +++ b/rc-service/rc-service-live/live-application/src/main/java/com/red/circle/live/app/command/user/LiveQuitRoomExe.java @@ -1,14 +1,20 @@ package com.red.circle.live.app.command.user; +import com.alibaba.fastjson.JSON; import com.red.circle.common.business.dto.cmd.app.AppRoomIdCmd; +import com.red.circle.component.redis.service.RedisService; +import com.red.circle.framework.dto.ResultResponse; import com.red.circle.live.domain.gateway.LiveMicrophoneGateway; import com.red.circle.live.domain.live.LiveMicrophone; import com.red.circle.live.domain.live.LiveMusicStatus; import com.red.circle.live.infra.database.cache.service.LiveMicCacheService; import com.red.circle.live.infra.database.cache.service.LiveMusicHeartbeatService; +import com.red.circle.other.inner.endpoint.live.ActiveVoiceRoomClient; +import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomCO; import com.red.circle.tool.core.collection.CollectionUtils; import java.util.List; import java.util.Objects; +import java.util.concurrent.TimeUnit; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -24,6 +30,11 @@ public class LiveQuitRoomExe { private final LiveMicCacheService liveMicCacheService; private final LiveMicrophoneGateway liveMicrophoneGateway; private final LiveMusicHeartbeatService liveMusicHeartbeatService; + private final ActiveVoiceRoomClient activeVoiceRoomClient; + private final RedisService redisService; + + private static final String EMPTY_ROOM_CACHE_KEY = "empty_room_cache:"; + private static final int CACHE_EXPIRE_MINUTES = 10; public void execute(AppRoomIdCmd cmd) { // 移除在线用户 @@ -50,6 +61,21 @@ public class LiveQuitRoomExe { && Objects.equals(musicStatus.getUserId(), cmd.requiredReqUserId())) { liveMusicHeartbeatService.removeMickUser(cmd.getRoomId()); } + + //将没人的房间存入缓存10分钟 + try { + ResultResponse noBodyRoom = activeVoiceRoomClient.createNoBodyRoom(cmd.getRoomId()); + ActiveVoiceRoomCO body = noBodyRoom.getBody(); + if (Objects.nonNull(body)) { + // 缓存空房间信息,设置10分钟过期 + String cacheKey = EMPTY_ROOM_CACHE_KEY + cmd.getRoomId(); + redisService.setIfAbsent(cacheKey, JSON.toJSONString(body), CACHE_EXPIRE_MINUTES, TimeUnit.MINUTES); + } + } catch (Exception e) { + //ignore + } + + } } 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 830d3986..edaa6311 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 @@ -21,6 +21,7 @@ import com.red.circle.other.infra.database.rds.entity.sys.SysCountryCode; import com.red.circle.other.infra.database.rds.service.sys.SysCountryCodeService; import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService; import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd; +import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomCO; import com.red.circle.tool.core.collection.CollectionUtils; import com.google.gson.reflect.TypeToken; import java.lang.reflect.Type; @@ -30,6 +31,8 @@ import java.util.function.Function; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; /** @@ -44,7 +47,6 @@ public class RoomVoiceDiscoverQryExe { private final UserSVipGateway userSVipGateway; private final UserRegionGateway userRegionGateway; - private final SysCountryCodeService sysCountryCodeService; private final RoomVoiceProfileCommon roomVoiceProfileCommon; private final ActiveVoiceRoomService activeVoiceRoomService; private final RoomUserBlacklistService roomUserBlacklistService; @@ -52,6 +54,14 @@ public class RoomVoiceDiscoverQryExe { private final RoomProfileManagerService roomProfileManagerService; private final RegionRoomCacheService regionRoomCacheService; private final LiveMicClient liveMicClient; + private final RedisTemplate redisTemplate; + + private static final String EMPTY_ROOM_CACHE_KEY = "empty_room_cache:*"; + + // 区域隔离常量 - 与ActiveVoiceRoomServiceImpl保持一致 + private static final Set SA_REGIONS = Set.of("BD", "IN", "PK"); + private static final Set AR_REGIONS = Set.of("AE", "BH", "DJ", "DZ", "EG", "EY", "ER", "IL", "IQ", "JO", "KM", "KW", "LB", "LY", "MA", "MR", "OM", "PS", "QA", "SA", "SD", "SO", "SS", "SY", "TD", "TN", "YE"); + private static final Set OTHER_REGIONS = Set.of("OTHER", "PH", "ID", "TR", "GH", "IR", "AF", "NG", "DE", "MYS", "TM", "AZ", "NP"); public List execute(AppExtCommand cmd) { String region = cmd.isAllRegion() ? "ALL" : userRegionGateway.getRegionCode(cmd.requiredReqUserId()); @@ -64,12 +74,21 @@ public class RoomVoiceDiscoverQryExe { } List activeVoiceRooms = activeVoiceRoomService.listDiscover(cmd.requireReqSysOrigin(), cmd.isAllRegion(), region, 50); + + // 查询没人的房间缓存,加入进去 + List emptyRooms = getEmptyRoomsFromCache(); + if (CollectionUtils.isNotEmpty(emptyRooms)) { + // 按照listDiscover的过滤规则过滤空房间 + List matchedEmptyRooms = filterEmptyRoomsByRegion(emptyRooms, cmd.requireReqSysOrigin(), cmd.isAllRegion(), region); + if (CollectionUtils.isNotEmpty(matchedEmptyRooms)) { + // 创建新的可修改列表,合并活跃房间和空房间 + List allRooms = new ArrayList<>(activeVoiceRooms); + allRooms.addAll(matchedEmptyRooms); + activeVoiceRooms = allRooms; + } + } log.info("activeVoiceRooms:{}", JSON.toJSONString(activeVoiceRooms)); - // 处理没有人的房间,有缓存不会大量创建线程 - List longs = formatRoomList(activeVoiceRooms); - List list = activeVoiceRooms.stream().filter(e -> !longs.contains(e.getId())).toList(); - - List roomList = roomVoiceProfileCommon.toListRoomVoiceProfileCO(list); + List roomList = roomVoiceProfileCommon.toListRoomVoiceProfileCO(activeVoiceRooms); if (CollectionUtils.isEmpty(roomList)) { //roomList = getHomeData(cmd,latestMobileDeviceService.getLatestLanguage(cmd.requiredReqUserId())); @@ -87,7 +106,6 @@ public class RoomVoiceDiscoverQryExe { room.setUserSVipLevel(svipLevelEnumMap.get(room.getUserId())); }) .toList(); - regionRoomCacheService.saveRegionsRoom(JSON.toJSONString(roomList), key); return roomList; } @@ -181,6 +199,149 @@ public class RoomVoiceDiscoverQryExe { } } + /** + * 按照listDiscover的过滤规则过滤空房间 + * + * @param emptyRooms 空房间列表 + * @param sysOrigin 系统来源 + * @param isAllRegion 是否显示所有区域 + * @param region 当前用户区域 + * @return 过滤后的空房间列表 + */ + private List filterEmptyRoomsByRegion(List emptyRooms, String sysOrigin, boolean isAllRegion, String region) { + List excludeRegions = getRegions(region); + List includeRegions = getSpecialRegions(region); + + return emptyRooms.stream() + .filter(room -> Objects.equals(sysOrigin, room.getSysOrigin())) + .filter(room -> { + if (isAllRegion) { + return true; // 如果是所有区域,不进行区域过滤 + } + + String roomRegion = room.getRegion(); + + if (CollectionUtils.isNotEmpty(includeRegions)) { + // 如果当前用户属于特殊区域组,只显示该区域组内的房间 + return includeRegions.contains(roomRegion); + } + + if (CollectionUtils.isNotEmpty(excludeRegions)) { + // 如果当前用户不属于特殊区域组,排除所有特殊区域组的房间 + return !excludeRegions.contains(roomRegion); + } + + return true; + }) + .collect(Collectors.toList()); + } + + /** + * 获取需要排除的区域列表 + */ + private List getRegions(String region) { + List excludeRegions = new ArrayList<>(); + + if (SA_REGIONS.contains(region)) { + excludeRegions.addAll(AR_REGIONS); + excludeRegions.addAll(OTHER_REGIONS); + } else if (AR_REGIONS.contains(region)) { + excludeRegions.addAll(SA_REGIONS); + excludeRegions.addAll(OTHER_REGIONS); + } else if (OTHER_REGIONS.contains(region)) { + excludeRegions.addAll(SA_REGIONS); + excludeRegions.addAll(AR_REGIONS); + } else { + excludeRegions.addAll(SA_REGIONS); + excludeRegions.addAll(AR_REGIONS); + excludeRegions.addAll(OTHER_REGIONS); + } + + return excludeRegions; + } + + /** + * 获取特殊区域组列表 + */ + private List getSpecialRegions(String region) { + if (SA_REGIONS.contains(region)) { + return new ArrayList<>(SA_REGIONS); + } + + if (AR_REGIONS.contains(region)) { + return new ArrayList<>(AR_REGIONS); + } + + if (OTHER_REGIONS.contains(region)) { + return new ArrayList<>(OTHER_REGIONS); + } + + return new ArrayList<>(); + } + + /** + * 从缓存中获取没人的房间 + * + * @return + */ + private List getEmptyRoomsFromCache() { + try { + Set keys = redisTemplate.keys(EMPTY_ROOM_CACHE_KEY); + if (CollectionUtils.isEmpty(keys)) { + return new ArrayList<>(); + } + + List emptyRooms = new ArrayList<>(); + for (String key : keys) { + String cachedRoom = (String) redisTemplate.opsForValue().get(key); + if (cachedRoom != null) { + try { + // 将缓存对象转换为ActiveVoiceRoomCO,再转换为ActiveVoiceRoom + ActiveVoiceRoomCO roomCO = JSON.parseObject(cachedRoom, ActiveVoiceRoomCO.class); + if (roomCO != null) { + ActiveVoiceRoom room = convertToActiveVoiceRoom(roomCO); + if (room != null) { + emptyRooms.add(room); + } + } + } catch (Exception e) { + log.warn("转换缓存房间对象失败, key: {}", key, e); + } + } + } + return emptyRooms; + } catch (Exception e) { + log.error("获取空房间缓存失败", e); + return new ArrayList<>(); + } + } + + /** + * 将ActiveVoiceRoomCO转换为ActiveVoiceRoom + * + * @param roomCO + * @return + */ + private ActiveVoiceRoom convertToActiveVoiceRoom(ActiveVoiceRoomCO roomCO) { + try { + ActiveVoiceRoom room = new ActiveVoiceRoom(); + BeanUtils.copyProperties(roomCO, room); + // 设置在线人数为0,因为这是没人的房间 + room.setOnlineQuantity(0L); + // 设置默认权重(如果未设置的话) + if (room.getWeights() == null) { + room.setWeights(0); + } + if (room.getFixedWeights() == null) { + room.setFixedWeights(0); + } + return room; + } catch (Exception e) { + log.error("转换ActiveVoiceRoomCO失败", e); + return null; + } + } + /** * 去除拉黑和被上锁的的房间 * diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/endpoint/room/ActiveVoiceRoomClientEndpoint.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/endpoint/room/ActiveVoiceRoomClientEndpoint.java index 611af29a..229010b6 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/endpoint/room/ActiveVoiceRoomClientEndpoint.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/endpoint/room/ActiveVoiceRoomClientEndpoint.java @@ -1,13 +1,16 @@ package com.red.circle.other.app.inner.endpoint.room; -import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; import com.red.circle.framework.dto.ResultResponse; import com.red.circle.other.app.inner.service.live.ActiveVoiceRoomClientService; +import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom; +import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomCO; import com.red.circle.other.inner.endpoint.live.ActiveVoiceRoomClient; import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd; import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomDTO; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.RequestMapping; @@ -36,4 +39,12 @@ public class ActiveVoiceRoomClientEndpoint implements ActiveVoiceRoomClient { return ResultResponse.success(activeVoiceRoomClientService.listOps(qryCmd)); } + @Override + public ResultResponse createNoBodyRoom(Long roomId) { + ActiveVoiceRoomCO activeVoiceRoomCO = new ActiveVoiceRoomCO(); + ActiveVoiceRoom nobodyRoom = activeVoiceRoomClientService.createNobodyRoom(roomId); + BeanUtils.copyProperties(nobodyRoom, activeVoiceRoomCO); + return ResultResponse.success(activeVoiceRoomCO); + } + } diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/ActiveVoiceRoomClientService.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/ActiveVoiceRoomClientService.java index 4c2a9087..f9a3e345 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/ActiveVoiceRoomClientService.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/ActiveVoiceRoomClientService.java @@ -1,6 +1,7 @@ package com.red.circle.other.app.inner.service.live; import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; +import com.red.circle.other.infra.database.mongo.entity.live.ActiveVoiceRoom; import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd; import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomDTO; import java.util.List; @@ -22,4 +23,9 @@ public interface ActiveVoiceRoomClientService { */ List listOps(AppActiveVoiceRoomQryCmd qryCmd); + /** + * 创建没人的房间缓存 + */ + ActiveVoiceRoom createNobodyRoom(Long roomId); + } diff --git a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/impl/ActiveVoiceRoomClientServiceImpl.java b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/impl/ActiveVoiceRoomClientServiceImpl.java index 6f6188be..9794aa0a 100644 --- a/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/impl/ActiveVoiceRoomClientServiceImpl.java +++ b/rc-service/rc-service-other/other-inner-endpoint/src/main/java/com/red/circle/other/app/inner/service/live/impl/ActiveVoiceRoomClientServiceImpl.java @@ -1,12 +1,28 @@ package com.red.circle.other.app.inner.service.live.impl; import com.red.circle.common.business.core.enums.SysOriginPlatformEnum; +import com.red.circle.live.inner.endpoint.LiveMicClient; import com.red.circle.other.app.inner.service.live.ActiveVoiceRoomClientService; +import com.red.circle.other.domain.gateway.user.UserProfileGateway; +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.model.user.UserProfile; import com.red.circle.other.infra.convertor.live.ActiveVoiceInfraConvertor; +import com.red.circle.other.infra.database.cache.service.other.HotRoomCacheService; +import com.red.circle.other.infra.database.cache.service.other.RoomManagerCacheService; +import com.red.circle.other.infra.database.mongo.entity.live.*; import com.red.circle.other.infra.database.mongo.service.live.ActiveVoiceRoomService; +import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService; +import com.red.circle.other.infra.database.mongo.service.live.RoomTopFixedService; import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd; import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomDTO; import java.util.List; +import java.util.Objects; +import java.util.Optional; + +import com.red.circle.tool.core.date.TimestampUtils; +import com.red.circle.tool.core.sequence.IdWorkerUtils; +import com.red.circle.tool.core.text.StringUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -19,6 +35,14 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe private final ActiveVoiceRoomService activeVoiceRoomService; private final ActiveVoiceInfraConvertor activeVoiceInfraConvertor; + private final RoomProfileManagerService roomProfileManagerService; + private final HotRoomCacheService hotRoomCacheService; + private final LiveMicClient liveMicClient; + private final RoomManagerCacheService roomManagerCacheService; + private final UserSVipGateway userSVipGateway; + private final UserProfileGateway userProfileGateway; + private final UserRegionGateway userRegionGateway; + private final RoomTopFixedService roomTopFixedService; @Override public Long count(String sysOrigin) { @@ -32,4 +56,57 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe ); } + @Override + public ActiveVoiceRoom createNobodyRoom(Long roomId) { + RoomProfileManager room = roomProfileManagerService.getById(roomId); + UserProfile userProfile = userProfileGateway.getByUserId(room.getUserId()); + String roomOwnRegionCode = userRegionGateway.getRegionCode(room.getUserId()); + + RoomTopFixed roomTopFixed = roomTopFixedService.getByRoomId(room.getId()); + Integer roomTopFixedWeights = Optional.ofNullable(roomTopFixed) + .map(fixed -> Objects.nonNull(fixed.getWeights()) ? fixed.getWeights() : 0) + .orElse(0); + + boolean topRoomForeverOnline = Optional.ofNullable(roomTopFixed) + .map(fixed -> Objects.equals(fixed.getForeverOnline(), Boolean.TRUE)) + .orElse(Boolean.FALSE); + + // 房间上锁. + Integer weights = StringUtils.isNotBlank(Optional.ofNullable(room.getSetting()) + .map(RoomSetting::getPassword) + .orElse("")) ? 0 : 1; + + return new ActiveVoiceRoom() + .setId(roomId) + .setTimeId(IdWorkerUtils.getId()) + .setSysOrigin(room.getSysOrigin()) + .setUserId(room.getUserId()) + .setRoomAccount(room.getRoomAccount()) + .setFixedWeights(roomTopFixedWeights) + .setRunGame(null) + .setHot( + Objects.nonNull(hotRoomCacheService.getAvailable(room.getSysOrigin(), room.getId()))) + .setCountryCode(StringUtils.toUpperCase(userProfile.getCountryCode())) + .setCountryName(userProfile.getCountryName()) + // ALL所有、DEFAULT默认区域、其他根据语言分割. + .setRegion(roomOwnRegionCode) + .setExpiredTime(TimestampUtils.nowPlusMinutes(topRoomForeverOnline ? 60 : 3)) + .setCreateTime(TimestampUtils.now()) + .setUpdateTime(TimestampUtils.now()) + .setOnlineQuantity(getAvRoomOnlineMemberNum(room)) + .setWeights(weights) + .setSuperVipLevel(Objects.toString( + userSVipGateway.checkSVipIdentity(room.getUserId())) + ); + } + + private Long getAvRoomOnlineMemberNum(RoomProfile roomProfile) { + Long resultQuantity = liveMicClient.getLiveRoomUserSize(roomProfile.getId()).getBody(); + if (Objects.nonNull(resultQuantity)) { + roomManagerCacheService.setNumberPeople(roomProfile.getRoomAccount(), resultQuantity); + return resultQuantity; + } + return 0L; + } + }