房间置顶
This commit is contained in:
parent
fc7d248171
commit
e8975dca9d
@ -68,6 +68,7 @@ public class RoomVoiceDiscoverQryExe {
|
||||
|
||||
private static final String EMPTY_ROOM_CACHE_KEY = "empty_room_cache:*";
|
||||
private static final String MEMBER_QUANTITY_EXT_KEY = "memberQuantity";
|
||||
private static final String FIXED_WEIGHTS_EXT_KEY = "fixedWeights";
|
||||
private static final int DISCOVERY_LIMIT = 50;
|
||||
private static final long DISCOVERY_SLOW_STEP_MILLIS = 100L;
|
||||
private static final long DISCOVERY_SLOW_TOTAL_MILLIS = 300L;
|
||||
@ -164,7 +165,7 @@ public class RoomVoiceDiscoverQryExe {
|
||||
DISCOVERY_LIMIT);
|
||||
}
|
||||
stepStart = logDiscoveryStep("fallback-room-profiles", stepStart, reqUserId, sysOrigin, region);
|
||||
roomList = sortByMemberQuantityDesc(roomList);
|
||||
roomList = sortByTopWeightAndMemberQuantityDesc(roomList);
|
||||
stepStart = logDiscoveryStep("sort-rooms", stepStart, reqUserId, sysOrigin, region);
|
||||
|
||||
if (CollectionUtils.isEmpty(roomList)) {
|
||||
@ -194,20 +195,30 @@ public class RoomVoiceDiscoverQryExe {
|
||||
return roomList;
|
||||
}
|
||||
|
||||
private List<RoomVoiceProfileCO> sortByMemberQuantityDesc(List<RoomVoiceProfileCO> roomList) {
|
||||
private List<RoomVoiceProfileCO> sortByTopWeightAndMemberQuantityDesc(
|
||||
List<RoomVoiceProfileCO> roomList) {
|
||||
if (CollectionUtils.isEmpty(roomList)) {
|
||||
return CollectionUtils.newArrayList();
|
||||
}
|
||||
return roomList.stream()
|
||||
.sorted(Comparator.comparingInt(this::roomMemberQuantity).reversed())
|
||||
.sorted(Comparator.comparingInt(this::roomFixedWeights).reversed()
|
||||
.thenComparing(Comparator.comparingInt(this::roomMemberQuantity).reversed()))
|
||||
.toList();
|
||||
}
|
||||
|
||||
private int roomFixedWeights(RoomVoiceProfileCO room) {
|
||||
return roomIntExtValue(room, FIXED_WEIGHTS_EXT_KEY);
|
||||
}
|
||||
|
||||
private int roomMemberQuantity(RoomVoiceProfileCO room) {
|
||||
return roomIntExtValue(room, MEMBER_QUANTITY_EXT_KEY);
|
||||
}
|
||||
|
||||
private int roomIntExtValue(RoomVoiceProfileCO room, String key) {
|
||||
if (Objects.isNull(room) || Objects.isNull(room.getExtValues())) {
|
||||
return 0;
|
||||
}
|
||||
Object value = room.getExtValues().get(MEMBER_QUANTITY_EXT_KEY);
|
||||
Object value = room.getExtValues().get(key);
|
||||
if (value instanceof Number number) {
|
||||
return Math.max(number.intValue(), 0);
|
||||
}
|
||||
|
||||
@ -19,6 +19,8 @@ import com.red.circle.other.infra.database.mongo.entity.live.assist.FamilyProfil
|
||||
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.infra.database.mongo.entity.user.region.SysRegionConfig;
|
||||
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService;
|
||||
import com.red.circle.other.infra.database.mongo.service.user.status.OnlineUserService;
|
||||
import com.red.circle.other.infra.database.rds.entity.family.FamilyMemberInfo;
|
||||
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
|
||||
@ -51,6 +53,7 @@ public class OnlineRoomCommon {
|
||||
private final OnlineUserService onlineUserService;
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final RoomTopFixedService roomTopFixedService;
|
||||
private final SysRegionConfigService sysRegionConfigService;
|
||||
private final HotRoomCacheService hotRoomCacheService;
|
||||
private final ActiveVoiceRoomService activeVoiceRoomService;
|
||||
private final FamilyMemberInfoService familyMemberInfoService;
|
||||
@ -127,7 +130,7 @@ public class OnlineRoomCommon {
|
||||
// ? ActiveVoiceRegion.LANG_AR
|
||||
// : ActiveVoiceRegion.toRegion(userProfile.getCountryCode());
|
||||
|
||||
RoomTopFixed roomTopFixed = roomTopFixedService.getByRoomId(room.getId());
|
||||
RoomTopFixed roomTopFixed = roomTopFixedService.getEffectiveByRoomId(room.getId());
|
||||
Integer roomTopFixedWeights = Optional.ofNullable(roomTopFixed)
|
||||
.map(fixed -> Objects.nonNull(fixed.getWeights()) ? fixed.getWeights() : 0)
|
||||
.orElse(0);
|
||||
@ -150,7 +153,7 @@ public class OnlineRoomCommon {
|
||||
.setCountryCode(StringUtils.toUpperCase(userProfile.getCountryCode()))
|
||||
.setCountryName(userProfile.getCountryName())
|
||||
// ALL所有、DEFAULT默认区域、其他根据语言分割.
|
||||
.setRegion(roomOwnRegionCode)
|
||||
.setRegion(resolveActiveRoomRegion(roomOwnRegionCode, roomTopFixed))
|
||||
.setExpiredTime(TimestampUtils.nowPlusMinutes(topRoomForeverOnline ? 60 : 3))
|
||||
.setCreateTime(TimestampUtils.now())
|
||||
.setUpdateTime(TimestampUtils.now())
|
||||
@ -161,6 +164,16 @@ public class OnlineRoomCommon {
|
||||
);
|
||||
}
|
||||
|
||||
private String resolveActiveRoomRegion(String defaultRegionCode, RoomTopFixed roomTopFixed) {
|
||||
if (Objects.isNull(roomTopFixed) || StringUtils.isBlank(roomTopFixed.getRegion())) {
|
||||
return defaultRegionCode;
|
||||
}
|
||||
return Optional.ofNullable(sysRegionConfigService.getById(roomTopFixed.getRegion()))
|
||||
.map(SysRegionConfig::getRegionCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.orElse(defaultRegionCode);
|
||||
}
|
||||
|
||||
private FamilyProfile getFamilyProfile(Long userId) {
|
||||
FamilyMemberInfo memberInfo = familyMemberInfoService.getFamilyMemberByUserId(userId);
|
||||
|
||||
|
||||
@ -56,16 +56,18 @@ public class RoomRegionFilterCommon {
|
||||
|
||||
public List<ActiveVoiceRoom> filterActiveVoiceRoomsByRegion(
|
||||
List<ActiveVoiceRoom> activeVoiceRooms, String regionCode) {
|
||||
return filterByRegionCode(activeVoiceRooms, ActiveVoiceRoom::getUserId, regionCode);
|
||||
return filterByRegionCode(activeVoiceRooms, ActiveVoiceRoom::getUserId,
|
||||
ActiveVoiceRoom::getRegion, regionCode);
|
||||
}
|
||||
|
||||
public List<RoomProfileManager> filterRoomProfileManagersByRegion(
|
||||
List<RoomProfileManager> roomProfileManagers, String regionCode) {
|
||||
return filterByRegionCode(roomProfileManagers, RoomProfileManager::getUserId, regionCode);
|
||||
return filterByRegionCode(roomProfileManagers, RoomProfileManager::getUserId,
|
||||
item -> null, regionCode);
|
||||
}
|
||||
|
||||
private <T> List<T> filterByRegionCode(List<T> source, Function<T, Long> userIdGetter,
|
||||
String regionCode) {
|
||||
Function<T, String> regionCodeGetter, String regionCode) {
|
||||
if (CollectionUtils.isEmpty(source) || StringUtils.isBlank(regionCode)) {
|
||||
return Lists.newArrayList();
|
||||
}
|
||||
@ -84,7 +86,8 @@ public class RoomRegionFilterCommon {
|
||||
}
|
||||
|
||||
return source.stream()
|
||||
.filter(item -> StringUtils.equalsIgnoreCase(regionCode, regionCodeMap.get(userIdGetter.apply(item))))
|
||||
.filter(item -> StringUtils.equalsIgnoreCase(regionCode, regionCodeGetter.apply(item))
|
||||
|| StringUtils.equalsIgnoreCase(regionCode, regionCodeMap.get(userIdGetter.apply(item))))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,6 +152,7 @@ public class RoomVoiceProfileCommon {
|
||||
return null;
|
||||
}
|
||||
roomVoiceProfile.putRoomMemberQuantity(toRoomMemberQuantity(activeVoiceRoom.getOnlineQuantity()));
|
||||
roomVoiceProfile.putFixedWeights(activeVoiceRoom.getFixedWeights());
|
||||
roomVoiceProfile.setHotRoom(activeVoiceRoom.getHot());
|
||||
roomVoiceProfile.setRoomGameIcon("");
|
||||
roomVoiceProfile.setUserSVipLevel(SVIPLevelEnum.valueOf(activeVoiceRoom.getSuperVipLevel()));
|
||||
|
||||
@ -124,6 +124,88 @@ class RoomVoiceDiscoverQryExeTest {
|
||||
verify(activeVoiceRoomService, never()).listDiscover("YOLO", true, "AE", null, 50);
|
||||
}
|
||||
|
||||
@Test
|
||||
void execute_shouldKeepTopRoomBeforeHigherMemberRoom() {
|
||||
UserSVipGateway userSVipGateway = mock(UserSVipGateway.class);
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
RoomRegionFilterCommon roomRegionFilterCommon = mock(RoomRegionFilterCommon.class);
|
||||
RoomVoiceProfileCommon roomVoiceProfileCommon = mock(RoomVoiceProfileCommon.class);
|
||||
ActiveVoiceRoomService activeVoiceRoomService = mock(ActiveVoiceRoomService.class);
|
||||
RoomUserBlacklistService roomUserBlacklistService = mock(RoomUserBlacklistService.class);
|
||||
LatestMobileDeviceService latestMobileDeviceService = mock(LatestMobileDeviceService.class);
|
||||
RoomProfileManagerService roomProfileManagerService = mock(RoomProfileManagerService.class);
|
||||
RegionRoomCacheService regionRoomCacheService = mock(RegionRoomCacheService.class);
|
||||
LiveMicClient liveMicClient = mock(LiveMicClient.class);
|
||||
RedisTemplate<String, Object> redisTemplate = mock(RedisTemplate.class);
|
||||
RocketStatusCacheService rocketStatusCacheService = mock(RocketStatusCacheService.class);
|
||||
GameLudoService gameLudoService = mock(GameLudoService.class);
|
||||
UserProfileGateway userProfileGateway = mock(UserProfileGateway.class);
|
||||
CountryCodeAliasSupport countryCodeAliasSupport = mock(CountryCodeAliasSupport.class);
|
||||
RoomVoiceDiscoverQryExe exe = new RoomVoiceDiscoverQryExe(
|
||||
userSVipGateway,
|
||||
userRegionGateway,
|
||||
roomRegionFilterCommon,
|
||||
roomVoiceProfileCommon,
|
||||
activeVoiceRoomService,
|
||||
roomUserBlacklistService,
|
||||
latestMobileDeviceService,
|
||||
roomProfileManagerService,
|
||||
regionRoomCacheService,
|
||||
liveMicClient,
|
||||
redisTemplate,
|
||||
rocketStatusCacheService,
|
||||
gameLudoService,
|
||||
userProfileGateway,
|
||||
countryCodeAliasSupport
|
||||
);
|
||||
|
||||
AppExtCommand cmd = new AppExtCommand();
|
||||
cmd.setReqUserId(1L);
|
||||
cmd.setReqSysOrigin(ReqSysOrigin.of("YOLO", "YOLO"));
|
||||
|
||||
RegionConfig currentRegion = new RegionConfig().setRegionCode("AE").setCountryCodes("AE,SA");
|
||||
UserProfile userProfile = new UserProfile();
|
||||
ActiveVoiceRoom activeVoiceRoom = new ActiveVoiceRoom().setId(101L).setUserId(201L);
|
||||
RoomProfileManager fallbackRoomManager = new RoomProfileManager();
|
||||
fallbackRoomManager.setId(102L);
|
||||
fallbackRoomManager.setUserId(202L);
|
||||
|
||||
RoomVoiceProfileCO topRoomCo = new RoomVoiceProfileCO().setId(101L).setUserId(201L)
|
||||
.putRoomMemberQuantity(0)
|
||||
.putFixedWeights(100);
|
||||
RoomVoiceProfileCO fallbackRoomCo = new RoomVoiceProfileCO().setId(102L).setUserId(202L)
|
||||
.putRoomMemberQuantity(2);
|
||||
|
||||
when(roomRegionFilterCommon.requireRegionConfig(1L)).thenReturn(currentRegion);
|
||||
when(userProfileGateway.getByUserId(1L)).thenReturn(userProfile);
|
||||
when(regionRoomCacheService.getRegionsRoom("YOLOAE")).thenReturn(null);
|
||||
when(activeVoiceRoomService.listByRegion("YOLO", "AE", 50)).thenReturn(List.of(activeVoiceRoom));
|
||||
when(roomRegionFilterCommon.filterActiveVoiceRoomsByRegion(List.of(activeVoiceRoom), "AE"))
|
||||
.thenReturn(List.of(activeVoiceRoom));
|
||||
when(roomVoiceProfileCommon.toListRoomVoiceProfileCO(List.of(activeVoiceRoom))).thenReturn(
|
||||
List.of(topRoomCo)
|
||||
);
|
||||
when(roomRegionFilterCommon.listCountryCodes(currentRegion)).thenReturn(List.of("AE", "SA"));
|
||||
when(roomProfileManagerService.listSelectiveLimitByCountryCodes(
|
||||
"YOLO", List.of("AE", "SA"), List.of(101L), 50
|
||||
)).thenReturn(List.of(fallbackRoomManager));
|
||||
when(roomRegionFilterCommon.filterRoomProfileManagersByRegion(
|
||||
List.of(fallbackRoomManager), "AE"
|
||||
)).thenReturn(List.of(fallbackRoomManager));
|
||||
when(roomVoiceProfileCommon.listRoomVoiceProfilesV2(List.of(fallbackRoomManager))).thenReturn(
|
||||
List.of(fallbackRoomCo)
|
||||
);
|
||||
when(userSVipGateway.checkSVipIdentity(anySet())).thenReturn(
|
||||
Map.of(201L, SVIPLevelEnum.NONE, 202L, SVIPLevelEnum.NONE)
|
||||
);
|
||||
when(rocketStatusCacheService.batchGetRocketStatus(List.of(101L, 102L))).thenReturn(Map.of());
|
||||
when(gameLudoService.listGameCoverByRoomIds(List.of(101L, 102L))).thenReturn(Map.of());
|
||||
|
||||
List<RoomVoiceProfileCO> roomList = exe.execute(cmd);
|
||||
|
||||
assertEquals(List.of(topRoomCo, fallbackRoomCo), roomList);
|
||||
}
|
||||
|
||||
@Test
|
||||
void execute_shouldReturnAllRegionRoomsForWhiteListUser() {
|
||||
UserSVipGateway userSVipGateway = mock(UserSVipGateway.class);
|
||||
|
||||
@ -34,6 +34,32 @@ class RoomRegionFilterCommonTest {
|
||||
assertEquals(List.of(currentRegionRoom), filteredRooms);
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterActiveVoiceRoomsByRegion_shouldKeepConfiguredRegionRooms() {
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
RoomRegionFilterCommon roomRegionFilterCommon = new RoomRegionFilterCommon(userRegionGateway);
|
||||
|
||||
ActiveVoiceRoom topRegionRoom = new ActiveVoiceRoom()
|
||||
.setId(1001L)
|
||||
.setUserId(2001L)
|
||||
.setRegion("AE");
|
||||
ActiveVoiceRoom otherRegionRoom = new ActiveVoiceRoom()
|
||||
.setId(1002L)
|
||||
.setUserId(2002L)
|
||||
.setRegion("SA");
|
||||
|
||||
when(userRegionGateway.mapRegionCode(Set.of(2001L, 2002L))).thenReturn(
|
||||
Map.of(2001L, "SA", 2002L, "SA")
|
||||
);
|
||||
|
||||
List<ActiveVoiceRoom> filteredRooms = roomRegionFilterCommon.filterActiveVoiceRoomsByRegion(
|
||||
List.of(topRegionRoom, otherRegionRoom),
|
||||
"AE"
|
||||
);
|
||||
|
||||
assertEquals(List.of(topRegionRoom), filteredRooms);
|
||||
}
|
||||
|
||||
@Test
|
||||
void filterRoomProfileManagersByRegion_shouldKeepOnlyCurrentRegionRooms() {
|
||||
UserRegionGateway userRegionGateway = mock(UserRegionGateway.class);
|
||||
|
||||
@ -42,6 +42,7 @@ class RoomVoiceProfileCommonTest {
|
||||
.setId(10001L)
|
||||
.setUserId(20001L)
|
||||
.setOnlineQuantity(6L)
|
||||
.setFixedWeights(88)
|
||||
.setSuperVipLevel("NONE");
|
||||
|
||||
RoomProfileManager roomProfileManager = new RoomProfileManager();
|
||||
@ -75,6 +76,7 @@ class RoomVoiceProfileCommonTest {
|
||||
|
||||
assertEquals(1, roomProfiles.size());
|
||||
assertEquals("6", getExtValue(roomProfiles.get(0), "memberQuantity"));
|
||||
assertEquals(88, getExtValue(roomProfiles.get(0), "fixedWeights"));
|
||||
}
|
||||
|
||||
private Object getExtValue(RoomVoiceProfileCO roomVoiceProfileCO, String key) {
|
||||
|
||||
@ -154,6 +154,14 @@ public class RoomVoiceProfileCO extends ClientObject {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置房间置顶权重.
|
||||
*/
|
||||
public RoomVoiceProfileCO putFixedWeights(final Integer fixedWeights) {
|
||||
putExtField("fixedWeights", Objects.isNull(fixedWeights) ? 0 : fixedWeights);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否存在密码.
|
||||
*/
|
||||
|
||||
@ -29,6 +29,11 @@ public interface RoomTopFixedService {
|
||||
*/
|
||||
RoomTopFixed getByRoomId(Long roomId);
|
||||
|
||||
/**
|
||||
* 获取当前生效中的置顶房间.
|
||||
*/
|
||||
RoomTopFixed getEffectiveByRoomId(Long roomId);
|
||||
|
||||
/**
|
||||
* 房间置顶权重.
|
||||
*/
|
||||
|
||||
@ -126,7 +126,7 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService {
|
||||
|
||||
if (Objects.nonNull(qryCmd.getOrderByStrategy())) {
|
||||
query.with(
|
||||
Sort.by(Stream.of("onlineQuantity", "fixedWeights", "weights").map(Order::desc)
|
||||
Sort.by(Stream.of("fixedWeights", "onlineQuantity", "weights").map(Order::desc)
|
||||
.toArray(Order[]::new)));
|
||||
}
|
||||
|
||||
@ -174,9 +174,9 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService {
|
||||
|
||||
// 3. 排序逻辑
|
||||
Aggregation.sort(Sort.by(
|
||||
Sort.Order.desc("fixedWeightsScore"), // 如果区域不匹配,fixedWeights 为 0,不影响排序
|
||||
Sort.Order.desc("onlineQuantity"),
|
||||
Sort.Order.desc("regionMatchScore"),
|
||||
Sort.Order.desc("fixedWeightsScore"), // 如果区域不匹配,fixedWeights 为 0,不影响排序
|
||||
Sort.Order.desc("weights")
|
||||
)),
|
||||
|
||||
@ -196,8 +196,8 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService {
|
||||
Criteria.where("sysOrigin").is(sysOrigin)
|
||||
.and("region").is(region)
|
||||
).with(Sort.by(
|
||||
Sort.Order.desc("onlineQuantity"),
|
||||
Sort.Order.desc("fixedWeights"),
|
||||
Sort.Order.desc("onlineQuantity"),
|
||||
Sort.Order.desc("weights")
|
||||
));
|
||||
|
||||
|
||||
@ -6,7 +6,9 @@ import com.red.circle.framework.mybatis.constant.PageConstant;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomTopFixed;
|
||||
import com.red.circle.other.infra.database.mongo.service.live.RoomTopFixedService;
|
||||
import com.red.circle.other.inner.model.cmd.sys.RoomTopFixedQryCmd;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
import java.sql.Timestamp;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@ -44,7 +46,7 @@ public class RoomTopFixedServiceImpl implements RoomTopFixedService {
|
||||
}
|
||||
|
||||
if (StringUtils.isNotBlank(query.getRegion())) {
|
||||
criteria.and("region").lt(query.getRegion());
|
||||
criteria.and("region").is(query.getRegion());
|
||||
}
|
||||
|
||||
if (Objects.isNull(query.getLimit())) {
|
||||
@ -64,13 +66,28 @@ public class RoomTopFixedServiceImpl implements RoomTopFixedService {
|
||||
return mongoTemplate.findOne(Query.query(Criteria.where("id").is(roomId)), RoomTopFixed.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoomTopFixed getEffectiveByRoomId(Long roomId) {
|
||||
return mongoTemplate.findOne(Query.query(effectiveCriteria(roomId)), RoomTopFixed.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getWeights(Long roomId) {
|
||||
Query query = Query.query(Criteria.where("id").is(roomId));
|
||||
query.fields().include("weights");
|
||||
return Optional.ofNullable(mongoTemplate.findOne(query, RoomTopFixed.class))
|
||||
return Optional.ofNullable(getEffectiveByRoomId(roomId))
|
||||
.map(top -> Objects.nonNull(top.getWeights()) ? top.getWeights() : 0)
|
||||
.orElse(0);
|
||||
}
|
||||
|
||||
private Criteria effectiveCriteria(Long roomId) {
|
||||
Timestamp now = TimestampUtils.now();
|
||||
return new Criteria().andOperator(
|
||||
Criteria.where("id").is(roomId),
|
||||
Criteria.where("startTime").lte(now),
|
||||
new Criteria().orOperator(
|
||||
Criteria.where("expiredTime").is(null),
|
||||
Criteria.where("expiredTime").gt(now)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -43,15 +43,15 @@ class ActiveVoiceRoomServiceImplTest {
|
||||
assertEquals(50, query.getLimit());
|
||||
|
||||
Document sortObject = query.getSortObject();
|
||||
assertIterableEquals(List.of("onlineQuantity", "fixedWeights", "weights"),
|
||||
assertIterableEquals(List.of("fixedWeights", "onlineQuantity", "weights"),
|
||||
sortObject.keySet());
|
||||
assertEquals(-1, sortObject.getInteger("onlineQuantity"));
|
||||
assertEquals(-1, sortObject.getInteger("fixedWeights"));
|
||||
assertEquals(-1, sortObject.getInteger("onlineQuantity"));
|
||||
assertEquals(-1, sortObject.getInteger("weights"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void listOps_shouldUseOnlineQuantityFirstForDiscoverySort() {
|
||||
void listOps_shouldUseFixedWeightsFirstForDiscoverySort() {
|
||||
ArgumentCaptor<Query> queryCaptor = ArgumentCaptor.forClass(Query.class);
|
||||
when(mongoTemplate.find(queryCaptor.capture(), eq(ActiveVoiceRoom.class))).thenReturn(List.of());
|
||||
|
||||
@ -63,10 +63,10 @@ class ActiveVoiceRoomServiceImplTest {
|
||||
service.listOps(cmd);
|
||||
|
||||
Document sortObject = queryCaptor.getValue().getSortObject();
|
||||
assertIterableEquals(List.of("onlineQuantity", "fixedWeights", "weights"),
|
||||
assertIterableEquals(List.of("fixedWeights", "onlineQuantity", "weights"),
|
||||
sortObject.keySet());
|
||||
assertEquals(-1, sortObject.getInteger("onlineQuantity"));
|
||||
assertEquals(-1, sortObject.getInteger("fixedWeights"));
|
||||
assertEquals(-1, sortObject.getInteger("onlineQuantity"));
|
||||
assertEquals(-1, sortObject.getInteger("weights"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,8 @@ 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.infra.database.mongo.entity.user.region.SysRegionConfig;
|
||||
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService;
|
||||
import com.red.circle.other.inner.model.cmd.live.AppActiveVoiceRoomQryCmd;
|
||||
import com.red.circle.other.inner.model.dto.live.ActiveVoiceRoomDTO;
|
||||
import java.util.List;
|
||||
@ -43,6 +45,7 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe
|
||||
private final UserProfileGateway userProfileGateway;
|
||||
private final UserRegionGateway userRegionGateway;
|
||||
private final RoomTopFixedService roomTopFixedService;
|
||||
private final SysRegionConfigService sysRegionConfigService;
|
||||
|
||||
@Override
|
||||
public Long count(String sysOrigin) {
|
||||
@ -62,7 +65,7 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe
|
||||
UserProfile userProfile = userProfileGateway.getByUserId(room.getUserId());
|
||||
String roomOwnRegionCode = userRegionGateway.getRegionCode(room.getUserId());
|
||||
|
||||
RoomTopFixed roomTopFixed = roomTopFixedService.getByRoomId(room.getId());
|
||||
RoomTopFixed roomTopFixed = roomTopFixedService.getEffectiveByRoomId(room.getId());
|
||||
Integer roomTopFixedWeights = Optional.ofNullable(roomTopFixed)
|
||||
.map(fixed -> Objects.nonNull(fixed.getWeights()) ? fixed.getWeights() : 0)
|
||||
.orElse(0);
|
||||
@ -89,7 +92,7 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe
|
||||
.setCountryCode(StringUtils.toUpperCase(userProfile.getCountryCode()))
|
||||
.setCountryName(userProfile.getCountryName())
|
||||
// ALL所有、DEFAULT默认区域、其他根据语言分割.
|
||||
.setRegion(roomOwnRegionCode)
|
||||
.setRegion(resolveActiveRoomRegion(roomOwnRegionCode, roomTopFixed))
|
||||
.setExpiredTime(TimestampUtils.nowPlusMinutes(topRoomForeverOnline ? 60 : 3))
|
||||
.setCreateTime(TimestampUtils.now())
|
||||
.setUpdateTime(TimestampUtils.now())
|
||||
@ -100,5 +103,15 @@ public class ActiveVoiceRoomClientServiceImpl implements ActiveVoiceRoomClientSe
|
||||
);
|
||||
}
|
||||
|
||||
private String resolveActiveRoomRegion(String defaultRegionCode, RoomTopFixed roomTopFixed) {
|
||||
if (Objects.isNull(roomTopFixed) || StringUtils.isBlank(roomTopFixed.getRegion())) {
|
||||
return defaultRegionCode;
|
||||
}
|
||||
return Optional.ofNullable(sysRegionConfigService.getById(roomTopFixed.getRegion()))
|
||||
.map(SysRegionConfig::getRegionCode)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.orElse(defaultRegionCode);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -3,16 +3,21 @@ package com.red.circle.other.app.inner.service.live.impl;
|
||||
import com.red.circle.common.business.dto.cmd.PageRoomIdCmd;
|
||||
import com.red.circle.framework.core.asserts.ResponseAssert;
|
||||
import com.red.circle.framework.dto.PageResult;
|
||||
import com.red.circle.other.app.common.live.OnlineRoomCommon;
|
||||
import com.red.circle.other.app.inner.convertor.live.RoomProfileInnerConvertor;
|
||||
import com.red.circle.other.app.inner.service.live.HotRoomClientService;
|
||||
import com.red.circle.other.infra.database.cache.service.other.SetHotRoomCacheService;
|
||||
import com.red.circle.other.infra.database.cache.service.user.RegionRoomCacheService;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfileManager;
|
||||
import com.red.circle.other.infra.database.mongo.entity.live.RoomTopFixed;
|
||||
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.infra.database.mongo.entity.user.region.SysRegionConfig;
|
||||
import com.red.circle.other.infra.database.mongo.service.user.region.SysRegionConfigService;
|
||||
import com.red.circle.other.infra.database.rds.entity.live.HotRoom;
|
||||
import com.red.circle.other.infra.database.rds.service.live.HotRoomService;
|
||||
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
|
||||
import com.red.circle.other.inner.asserts.RoomErrorCode;
|
||||
import com.red.circle.other.inner.model.cmd.sys.RoomTopFixedCmd;
|
||||
import com.red.circle.other.inner.model.cmd.sys.RoomTopFixedQryCmd;
|
||||
@ -21,15 +26,21 @@ import com.red.circle.other.inner.model.dto.sys.SysHotRoomDTO;
|
||||
import com.red.circle.other.inner.model.dto.sys.SysTopRoomDTO;
|
||||
import com.red.circle.tool.core.collection.CollectionUtils;
|
||||
import com.red.circle.tool.core.date.TimestampUtils;
|
||||
import com.red.circle.tool.core.text.StringUtils;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* @author lisizhe on 2020/12/11
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class HotRoomClientServiceImpl implements HotRoomClientService {
|
||||
@ -38,8 +49,11 @@ public class HotRoomClientServiceImpl implements HotRoomClientService {
|
||||
private final RoomTopFixedService roomTopFixedService;
|
||||
private final SysRegionConfigService sysRegionConfigService;
|
||||
private final SetHotRoomCacheService setHotRoomCacheService;
|
||||
private final RegionRoomCacheService regionRoomCacheService;
|
||||
private final RoomProfileInnerConvertor roomProfileInnerConvertor;
|
||||
private final RoomProfileManagerService roomProfileManagerService;
|
||||
private final OnlineRoomCommon onlineRoomCommon;
|
||||
private final UserRegionGateway userRegionGateway;
|
||||
|
||||
@Override
|
||||
public void addOrUpdate(SysHotRoomCmd param) {
|
||||
@ -124,11 +138,74 @@ public class HotRoomClientServiceImpl implements HotRoomClientService {
|
||||
public void addOrUpdateRoomTop(RoomTopFixedCmd param) {
|
||||
RoomProfile roomProfile = roomProfileManagerService.getProfileById(param.getId());
|
||||
ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, roomProfile);
|
||||
roomTopFixedService.add(roomProfileInnerConvertor.toRoomTopFixed(param));
|
||||
RoomTopFixed oldRoomTopFixed = roomTopFixedService.getByRoomId(param.getId());
|
||||
RoomTopFixed newRoomTopFixed = roomProfileInnerConvertor.toRoomTopFixed(param);
|
||||
roomTopFixedService.add(newRoomTopFixed);
|
||||
refreshActiveRoom(param.getId());
|
||||
removeDiscoveryCache(param.getId(), oldRoomTopFixed, newRoomTopFixed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeRoomTop(Long roomId) {
|
||||
RoomTopFixed oldRoomTopFixed = roomTopFixedService.getByRoomId(roomId);
|
||||
roomTopFixedService.removeById(roomId);
|
||||
refreshActiveRoom(roomId);
|
||||
removeDiscoveryCache(roomId, oldRoomTopFixed);
|
||||
}
|
||||
|
||||
private void refreshActiveRoom(Long roomId) {
|
||||
try {
|
||||
onlineRoomCommon.addHeartbeatOnlineRoomProfileById(roomId);
|
||||
} catch (Exception e) {
|
||||
log.warn("刷新置顶房间在线数据失败 roomId={}", roomId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void removeDiscoveryCache(Long roomId, RoomTopFixed... roomTopFixedConfigs) {
|
||||
try {
|
||||
Map<String, Set<String>> regionsBySysOrigin = new HashMap<>();
|
||||
appendTopRoomRegions(regionsBySysOrigin, roomTopFixedConfigs);
|
||||
appendOwnerRegion(regionsBySysOrigin, roomId);
|
||||
|
||||
regionsBySysOrigin.forEach((sysOrigin, regions) -> regions.forEach(regionCode -> {
|
||||
regionRoomCacheService.remove(sysOrigin + regionCode);
|
||||
regionRoomCacheService.remove(sysOrigin + regionCode + ":ALL_REGION");
|
||||
}));
|
||||
} catch (Exception e) {
|
||||
log.warn("清理置顶房间发现缓存失败 roomId={}", roomId, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendTopRoomRegions(Map<String, Set<String>> regionsBySysOrigin,
|
||||
RoomTopFixed... roomTopFixedConfigs) {
|
||||
if (Objects.isNull(roomTopFixedConfigs)) {
|
||||
return;
|
||||
}
|
||||
for (RoomTopFixed roomTopFixed : roomTopFixedConfigs) {
|
||||
if (Objects.isNull(roomTopFixed) || StringUtils.isBlank(roomTopFixed.getSysOrigin())
|
||||
|| StringUtils.isBlank(roomTopFixed.getRegion())) {
|
||||
continue;
|
||||
}
|
||||
SysRegionConfig regionConfig = sysRegionConfigService.getById(roomTopFixed.getRegion());
|
||||
if (Objects.isNull(regionConfig) || StringUtils.isBlank(regionConfig.getRegionCode())) {
|
||||
continue;
|
||||
}
|
||||
regionsBySysOrigin.computeIfAbsent(roomTopFixed.getSysOrigin(), key -> new HashSet<>())
|
||||
.add(regionConfig.getRegionCode());
|
||||
}
|
||||
}
|
||||
|
||||
private void appendOwnerRegion(Map<String, Set<String>> regionsBySysOrigin, Long roomId) {
|
||||
RoomProfileManager roomProfile = roomProfileManagerService.getById(roomId);
|
||||
if (Objects.isNull(roomProfile) || StringUtils.isBlank(roomProfile.getSysOrigin())
|
||||
|| Objects.isNull(roomProfile.getUserId())) {
|
||||
return;
|
||||
}
|
||||
String ownerRegionCode = userRegionGateway.getRegionCode(roomProfile.getUserId());
|
||||
if (StringUtils.isBlank(ownerRegionCode)) {
|
||||
return;
|
||||
}
|
||||
regionsBySysOrigin.computeIfAbsent(roomProfile.getSysOrigin(), key -> new HashSet<>())
|
||||
.add(ownerRegionCode);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user