diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomCountryListQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomCountryListQryExe.java index 2305999d..2d3ededd 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomCountryListQryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomCountryListQryExe.java @@ -1,15 +1,16 @@ package com.red.circle.other.app.command.room.query; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon.RegionCountryScope; import com.red.circle.other.app.dto.clientobject.room.CountryCO; 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.model.user.UserProfile; -import com.red.circle.other.infra.constant.RegionConstants; 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.tool.core.text.StringUtils; import java.util.ArrayList; import java.util.List; +import java.util.Set; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -23,42 +24,39 @@ import org.springframework.stereotype.Component; public class RoomCountryListQryExe { private final SysCountryCodeService sysCountryCodeService; - private final UserRegionGateway userRegionGateway; private final UserProfileGateway userProfileGateway; + private final RoomRegionCountryCommon roomRegionCountryCommon; public List execute(Long userId) { List all = sysCountryCodeService.listOpenCountry(); - String userRegion = userRegionGateway.getRegionCode(userId); UserProfile userProfile = userProfileGateway.getByUserId(userId); - String userCountryCode = userProfile != null ? userProfile.getCountryCode() : null; - - boolean isArRegion = RegionConstants.AR.equals(userRegion); + String sysOrigin = userProfile == null ? null : userProfile.getOriginSys(); + String userCountryCode = userProfile == null + ? null + : roomRegionCountryCommon.normalizeCountryCode(userProfile.getCountryCode()); + RegionCountryScope regionScope = roomRegionCountryCommon.resolve(userId, sysOrigin); + Set visibleCountryCodes = regionScope.getCountryCodes(); List current = new ArrayList<>(); - List arList = new ArrayList<>(); - List otherList = new ArrayList<>(); + List others = new ArrayList<>(); for (SysCountryCode entity : all) { + String countryCode = roomRegionCountryCommon.normalizeCountryCode(entity.getAlphaTwo()); + if (!visibleCountryCodes.contains(countryCode)) { + continue; + } CountryCO co = toCountryCO(entity); - if (StringUtils.isNotBlank(userCountryCode) && userCountryCode.equals(entity.getAlphaTwo())) { + if (StringUtils.isNotBlank(userCountryCode) && userCountryCode.equals(countryCode)) { current.add(co); - } else if (RegionConstants.AR_REGIONS.contains(entity.getAlphaTwo())) { - arList.add(co); } else { - otherList.add(co); + others.add(co); } } List result = new ArrayList<>(); result.addAll(current); - if (isArRegion) { - result.addAll(arList); - result.addAll(otherList); - } else { - result.addAll(otherList); - result.addAll(arList); - } + result.addAll(others); return result; } 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 6f4a08ad..62240b4c 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 @@ -6,6 +6,8 @@ import com.google.gson.Gson; import com.red.circle.common.business.dto.cmd.AppExtCommand; import com.red.circle.common.business.enums.SVIPLevelEnum; import com.red.circle.live.inner.endpoint.LiveMicClient; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon.RegionCountryScope; 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.game.GameLudoService; @@ -67,27 +69,35 @@ public class RoomVoiceDiscoverQryExe { private final GameLudoService gameLudoService; private final UserProfileGateway userProfileGateway; private final MicUserCacheService micUserCacheService; + private final RoomRegionCountryCommon roomRegionCountryCommon; private static final String EMPTY_ROOM_CACHE_KEY = "empty_room_cache:*"; public List execute(AppExtCommand cmd) { cmd.setAllRegion(false); - String region = cmd.isAllRegion() ? "ALL" : userRegionGateway.getRegionCode(cmd.requiredReqUserId()); + RegionCountryScope regionScope = roomRegionCountryCommon.resolve( + cmd.requiredReqUserId(), cmd.requireReqSysOrigin()); + String region = regionScope.getRegionCode(); UserProfile userProfile = userProfileGateway.getByUserId(cmd.requiredReqUserId()); - String key = cmd.requireReqSysOrigin() + region; + String key = cmd.requireReqSysOrigin() + region + ":" + String.join(",", regionScope.getCountryCodes()); String regionsRoom = regionRoomCacheService.getRegionsRoom(key); if (Objects.nonNull(regionsRoom)) { List roomList = JSON.parseArray(regionsRoom, RoomVoiceProfileCO.class); return roomList; } - List activeVoiceRooms = activeVoiceRoomService.listDiscover(cmd.requireReqSysOrigin(), cmd.isAllRegion(), region, 50); + String userCountryCode = userProfile == null + ? "" + : roomRegionCountryCommon.normalizeCountryCode(userProfile.getCountryCode()); + List activeVoiceRooms = activeVoiceRoomService.listDiscoverByCountryCodes( + cmd.requireReqSysOrigin(), region, userCountryCode, regionScope.getCountryCodes(), 50); // 查询没人的房间缓存,加入进去 List emptyRooms = getEmptyRoomsFromCache(); if (CollectionUtils.isNotEmpty(emptyRooms)) { - List matchedEmptyRooms = filterEmptyRoomsByRegion(emptyRooms, cmd.requireReqSysOrigin(), cmd.isAllRegion(), region); + List matchedEmptyRooms = filterEmptyRoomsByRegion( + emptyRooms, cmd.requireReqSysOrigin(), regionScope.getCountryCodes()); if (CollectionUtils.isNotEmpty(matchedEmptyRooms)) { List allRooms = new ArrayList<>(activeVoiceRooms); Set existingRoomIds = activeVoiceRooms.stream() @@ -282,20 +292,13 @@ public class RoomVoiceDiscoverQryExe { } } - private List filterEmptyRoomsByRegion(List emptyRooms, String sysOrigin, boolean isAllRegion, String region) { + private List filterEmptyRoomsByRegion( + List emptyRooms, String sysOrigin, Set countryCodes) { return emptyRooms.stream() - .filter(room -> Objects.equals(sysOrigin, room.getSysOrigin())) - .filter(room -> { - if (isAllRegion) { - return true; - } - if (RegionConstant.isArabicRegionByCode(region)) { - return RegionConstant.isArabicRegionByCode(room.getRegion()); - } else { - return !RegionConstant.isArabicRegionByCode(room.getRegion()); - } - }) - .collect(Collectors.toList()); + .filter(room -> Objects.equals(sysOrigin, room.getSysOrigin())) + .filter(room -> countryCodes.contains( + roomRegionCountryCommon.normalizeCountryCode(room.getCountryCode()))) + .collect(Collectors.toList()); } diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceExploreQryExe.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceExploreQryExe.java index 75cae9e6..4b1e665c 100644 --- a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceExploreQryExe.java +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/command/room/query/RoomVoiceExploreQryExe.java @@ -1,21 +1,18 @@ package com.red.circle.other.app.command.room.query; -import com.red.circle.common.business.enums.SVIPLevelEnum; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon; +import com.red.circle.other.app.common.room.RoomRegionCountryCommon.RegionCountryScope; 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.dto.cmd.room.RoomExploreQryCmd; import com.red.circle.other.app.service.game.GameLudoService; 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.mongo.entity.live.ActiveVoiceRoom; import com.red.circle.other.infra.database.mongo.service.live.ActiveVoiceRoomService; import com.red.circle.tool.core.collection.CollectionUtils; -import com.red.circle.tool.core.text.StringUtils; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Component; @@ -31,20 +28,20 @@ public class RoomVoiceExploreQryExe { private static final int EXPLORE_LIMIT = 100; - private final UserRegionGateway userRegionGateway; - private final UserSVipGateway userSVipGateway; private final ActiveVoiceRoomService activeVoiceRoomService; private final RoomVoiceProfileCommon roomVoiceProfileCommon; private final RocketStatusCacheService rocketStatusCacheService; private final GameLudoService gameLudoService; + private final RoomRegionCountryCommon roomRegionCountryCommon; public List execute(RoomExploreQryCmd cmd) { - String userRegion = StringUtils.isNotBlank(cmd.getCountryCode()) - ? null - : userRegionGateway.getRegionCode(cmd.requiredReqUserId()); + RegionCountryScope regionScope = roomRegionCountryCommon.resolve( + cmd.requiredReqUserId(), cmd.requireReqSysOrigin()); + String countryCode = roomRegionCountryCommon.normalizeCountryCode(cmd.getCountryCode()); List rooms = activeVoiceRoomService.listExplore( - cmd.requireReqSysOrigin(), userRegion, cmd.getCountryCode(), EXPLORE_LIMIT); + cmd.requireReqSysOrigin(), regionScope.getRegionCode(), countryCode, + regionScope.getCountryCodes(), EXPLORE_LIMIT); List roomList = roomVoiceProfileCommon.toListRoomVoiceProfileCO(rooms); if (CollectionUtils.isEmpty(roomList)) { diff --git a/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/common/room/RoomRegionCountryCommon.java b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/common/room/RoomRegionCountryCommon.java new file mode 100644 index 00000000..5dd7e4ee --- /dev/null +++ b/rc-service/rc-service-other/other-application/src/main/java/com/red/circle/other/app/common/room/RoomRegionCountryCommon.java @@ -0,0 +1,94 @@ +package com.red.circle.other.app.common.room; + +import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway; +import com.red.circle.other.infra.database.mongo.entity.user.region.SysRegionConfig; +import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService; +import com.red.circle.tool.core.text.StringUtils; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.Locale; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +/** + * 房间区域国家范围. + */ +@Component +@RequiredArgsConstructor +public class RoomRegionCountryCommon { + + private static final Pattern COUNTRY_CODE_PATTERN = Pattern.compile("[A-Za-z0-9_]+"); + + private final UserRegionGateway userRegionGateway; + private final SysRegionConfigService sysRegionConfigService; + + public RegionCountryScope resolve(Long userId, String sysOrigin) { + String regionCode = userRegionGateway.getRegionCode(userId); + String regionId = userRegionGateway.getRegionId(userId); + + SysRegionConfig regionConfig = null; + if (StringUtils.isNotBlank(regionId)) { + regionConfig = sysRegionConfigService.getById(regionId); + } + if (regionConfig == null && StringUtils.isNotBlank(regionCode) + && StringUtils.isNotBlank(sysOrigin)) { + regionConfig = sysRegionConfigService.getByRegionCode(regionCode, sysOrigin); + } + + return new RegionCountryScope( + regionId, + regionCode, + parseCountryCodes(regionConfig == null ? null : regionConfig.getCountryCodes()) + ); + } + + public Set parseCountryCodes(String countryCodes) { + if (StringUtils.isBlank(countryCodes)) { + return Collections.emptySet(); + } + + Set result = new LinkedHashSet<>(); + Matcher matcher = COUNTRY_CODE_PATTERN.matcher(countryCodes); + while (matcher.find()) { + String code = normalizeCountryCode(matcher.group()); + if (StringUtils.isNotBlank(code)) { + result.add(code); + } + } + return Collections.unmodifiableSet(result); + } + + public String normalizeCountryCode(String countryCode) { + return StringUtils.isBlank(countryCode) + ? "" + : countryCode.trim().toUpperCase(Locale.ROOT); + } + + public static class RegionCountryScope { + + private final String regionId; + private final String regionCode; + private final Set countryCodes; + + private RegionCountryScope(String regionId, String regionCode, Set countryCodes) { + this.regionId = regionId; + this.regionCode = regionCode; + this.countryCodes = countryCodes; + } + + public String getRegionId() { + return regionId; + } + + public String getRegionCode() { + return regionCode; + } + + public Set getCountryCodes() { + return countryCodes; + } + } +} diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/ActiveVoiceRoomService.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/ActiveVoiceRoomService.java index 9bb9500f..63a7818c 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/ActiveVoiceRoomService.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/ActiveVoiceRoomService.java @@ -4,6 +4,7 @@ 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 java.util.List; +import java.util.Set; /** * 活跃语音房间. @@ -67,6 +68,12 @@ public interface ActiveVoiceRoomService { */ List listDiscover(String sysOrigin, boolean isAllRegion, String region, Integer limit); + /** + * 按后台区域配置的国家范围获取发现页数据. + */ + List listDiscoverByCountryCodes( + String sysOrigin, String region, String countryCode, Set countryCodes, Integer limit); + /** * 获取区域房间. */ @@ -96,4 +103,11 @@ public interface ActiveVoiceRoomService { */ List listExplore(String sysOrigin, String userRegion, String countryCode, Integer limit); + /** + * explore 页查询. + * 按后台区域配置的国家范围过滤,同区域排前. + */ + List listExplore( + String sysOrigin, String userRegion, String countryCode, Set countryCodes, Integer limit); + } diff --git a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/impl/ActiveVoiceRoomServiceImpl.java b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/impl/ActiveVoiceRoomServiceImpl.java index 9978d76c..9adfe55b 100644 --- a/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/impl/ActiveVoiceRoomServiceImpl.java +++ b/rc-service/rc-service-other/other-infrastructure/src/main/java/com/red/circle/other/infra/database/mongo/service/live/impl/ActiveVoiceRoomServiceImpl.java @@ -138,6 +138,47 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService { return mongoTemplate.find(query, ActiveVoiceRoom.class); } + @Override + public List listDiscoverByCountryCodes( + String sysOrigin, String region, String countryCode, Set countryCodes, Integer limit) { + Set safeCountryCodes = safeCountryCodes(countryCodes); + if (safeCountryCodes.isEmpty()) { + return Collections.emptyList(); + } + + Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin) + .and("countryCode").in(safeCountryCodes); + + log.info("首页房间按后台区域国家过滤 region:{}, countries:{}", region, safeCountryCodes); + + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(criteria), + Aggregation.project("id", "timeId", "sysOrigin", "userId", "roomAccount", + "familyProfile", "runGame", "superVipLevel", "hot", "fixedWeights", + "region", "countryCode", "countryName", "onlineQuantity", "weights", + "expiredTime", "createTime", "updateTime") + .and(ConditionalOperators.when(Criteria.where("countryCode").is(countryCode)) + .then(1).otherwise(0)).as("countryMatchScore") + .and(ConditionalOperators.when(Criteria.where("region").is(region)) + .then(1).otherwise(0)).as("regionMatchScore") + .and(ConditionalOperators.when(Criteria.where("region").is(region)) + .then("$fixedWeights").otherwise(0)).as("fixedWeightsScore") + .and("weights").as("weights"), + Aggregation.sort(Sort.by( + Sort.Order.desc("countryMatchScore"), + Sort.Order.desc("regionMatchScore"), + Sort.Order.desc("fixedWeightsScore"), + Sort.Order.desc("weights"), + Sort.Order.desc("onlineQuantity") + )), + Aggregation.skip(0), + Aggregation.limit(limit) + ); + + return mongoTemplate.aggregate(aggregation, ActiveVoiceRoom.class, ActiveVoiceRoom.class) + .getMappedResults(); + } + @Override public List listSearchCountryRoom(String sysOrigin, String countryCode, @@ -234,6 +275,47 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService { } return criteria; } + + @Override + public List listExplore( + String sysOrigin, String userRegion, String countryCode, Set countryCodes, Integer limit) { + Set safeCountryCodes = safeCountryCodes(countryCodes); + if (safeCountryCodes.isEmpty()) { + return Collections.emptyList(); + } + + Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin); + if (StringUtils.isNotBlank(countryCode)) { + if (!safeCountryCodes.contains(countryCode)) { + return Collections.emptyList(); + } + criteria.and("countryCode").is(countryCode); + } else { + criteria.and("countryCode").in(safeCountryCodes); + } + + Aggregation aggregation = Aggregation.newAggregation( + Aggregation.match(criteria), + Aggregation.project("id", "timeId", "sysOrigin", "userId", "roomAccount", "familyProfile", + "runGame", "superVipLevel", "hot", "fixedWeights", "region", "countryCode", + "countryName", "onlineQuantity", "weights", "expiredTime", "createTime", "updateTime") + .and(ConditionalOperators.when(Criteria.where("region").is(userRegion)) + .then(1).otherwise(0)).as("regionMatchScore") + .and(ConditionalOperators.when(Criteria.where("region").is(userRegion)) + .then("$fixedWeights").otherwise(0)).as("fixedWeightsScore"), + Aggregation.sort(Sort.by( + Sort.Order.desc("regionMatchScore"), + Sort.Order.desc("fixedWeightsScore"), + Sort.Order.desc("weights"), + Sort.Order.desc("onlineQuantity") + )), + Aggregation.limit(limit) + ); + + return mongoTemplate.aggregate(aggregation, ActiveVoiceRoom.class, ActiveVoiceRoom.class) + .getMappedResults(); + } + @Override public List listExplore(String sysOrigin, String userRegion, String countryCode, Integer limit) { Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin); @@ -272,6 +354,10 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService { return mongoTemplate.aggregate(aggregation, ActiveVoiceRoom.class, ActiveVoiceRoom.class).getMappedResults(); } + private Set safeCountryCodes(Set countryCodes) { + return countryCodes == null ? Collections.emptySet() : countryCodes; + } + @Override public List listGetActiveRooms(List roomIds, String sysOrigin,Integer onlineQuantity) { Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin)