fix: enforce atyou room region country visibility
This commit is contained in:
parent
8c2b965e6d
commit
73adb48c1c
@ -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<CountryCO> execute(Long userId) {
|
||||
List<SysCountryCode> 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<String> visibleCountryCodes = regionScope.getCountryCodes();
|
||||
|
||||
List<CountryCO> current = new ArrayList<>();
|
||||
List<CountryCO> arList = new ArrayList<>();
|
||||
List<CountryCO> otherList = new ArrayList<>();
|
||||
List<CountryCO> 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<CountryCO> 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;
|
||||
}
|
||||
|
||||
|
||||
@ -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<RoomVoiceProfileCO> 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<RoomVoiceProfileCO> roomList = JSON.parseArray(regionsRoom, RoomVoiceProfileCO.class);
|
||||
return roomList;
|
||||
}
|
||||
|
||||
List<ActiveVoiceRoom> activeVoiceRooms = activeVoiceRoomService.listDiscover(cmd.requireReqSysOrigin(), cmd.isAllRegion(), region, 50);
|
||||
String userCountryCode = userProfile == null
|
||||
? ""
|
||||
: roomRegionCountryCommon.normalizeCountryCode(userProfile.getCountryCode());
|
||||
List<ActiveVoiceRoom> activeVoiceRooms = activeVoiceRoomService.listDiscoverByCountryCodes(
|
||||
cmd.requireReqSysOrigin(), region, userCountryCode, regionScope.getCountryCodes(), 50);
|
||||
|
||||
// 查询没人的房间缓存,加入进去
|
||||
List<ActiveVoiceRoom> emptyRooms = getEmptyRoomsFromCache();
|
||||
if (CollectionUtils.isNotEmpty(emptyRooms)) {
|
||||
List<ActiveVoiceRoom> matchedEmptyRooms = filterEmptyRoomsByRegion(emptyRooms, cmd.requireReqSysOrigin(), cmd.isAllRegion(), region);
|
||||
List<ActiveVoiceRoom> matchedEmptyRooms = filterEmptyRoomsByRegion(
|
||||
emptyRooms, cmd.requireReqSysOrigin(), regionScope.getCountryCodes());
|
||||
if (CollectionUtils.isNotEmpty(matchedEmptyRooms)) {
|
||||
List<ActiveVoiceRoom> allRooms = new ArrayList<>(activeVoiceRooms);
|
||||
Set<Long> existingRoomIds = activeVoiceRooms.stream()
|
||||
@ -282,20 +292,13 @@ public class RoomVoiceDiscoverQryExe {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ActiveVoiceRoom> filterEmptyRoomsByRegion(List<ActiveVoiceRoom> emptyRooms, String sysOrigin, boolean isAllRegion, String region) {
|
||||
private List<ActiveVoiceRoom> filterEmptyRoomsByRegion(
|
||||
List<ActiveVoiceRoom> emptyRooms, String sysOrigin, Set<String> 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());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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<RoomVoiceProfileCO> 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<ActiveVoiceRoom> rooms = activeVoiceRoomService.listExplore(
|
||||
cmd.requireReqSysOrigin(), userRegion, cmd.getCountryCode(), EXPLORE_LIMIT);
|
||||
cmd.requireReqSysOrigin(), regionScope.getRegionCode(), countryCode,
|
||||
regionScope.getCountryCodes(), EXPLORE_LIMIT);
|
||||
|
||||
List<RoomVoiceProfileCO> roomList = roomVoiceProfileCommon.toListRoomVoiceProfileCO(rooms);
|
||||
if (CollectionUtils.isEmpty(roomList)) {
|
||||
|
||||
@ -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<String> parseCountryCodes(String countryCodes) {
|
||||
if (StringUtils.isBlank(countryCodes)) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
Set<String> 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<String> countryCodes;
|
||||
|
||||
private RegionCountryScope(String regionId, String regionCode, Set<String> countryCodes) {
|
||||
this.regionId = regionId;
|
||||
this.regionCode = regionCode;
|
||||
this.countryCodes = countryCodes;
|
||||
}
|
||||
|
||||
public String getRegionId() {
|
||||
return regionId;
|
||||
}
|
||||
|
||||
public String getRegionCode() {
|
||||
return regionCode;
|
||||
}
|
||||
|
||||
public Set<String> getCountryCodes() {
|
||||
return countryCodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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<ActiveVoiceRoom> listDiscover(String sysOrigin, boolean isAllRegion, String region, Integer limit);
|
||||
|
||||
/**
|
||||
* 按后台区域配置的国家范围获取发现页数据.
|
||||
*/
|
||||
List<ActiveVoiceRoom> listDiscoverByCountryCodes(
|
||||
String sysOrigin, String region, String countryCode, Set<String> countryCodes, Integer limit);
|
||||
|
||||
/**
|
||||
* 获取区域房间.
|
||||
*/
|
||||
@ -96,4 +103,11 @@ public interface ActiveVoiceRoomService {
|
||||
*/
|
||||
List<ActiveVoiceRoom> listExplore(String sysOrigin, String userRegion, String countryCode, Integer limit);
|
||||
|
||||
/**
|
||||
* explore 页查询.
|
||||
* 按后台区域配置的国家范围过滤,同区域排前.
|
||||
*/
|
||||
List<ActiveVoiceRoom> listExplore(
|
||||
String sysOrigin, String userRegion, String countryCode, Set<String> countryCodes, Integer limit);
|
||||
|
||||
}
|
||||
|
||||
@ -138,6 +138,47 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService {
|
||||
return mongoTemplate.find(query, ActiveVoiceRoom.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActiveVoiceRoom> listDiscoverByCountryCodes(
|
||||
String sysOrigin, String region, String countryCode, Set<String> countryCodes, Integer limit) {
|
||||
Set<String> 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<ActiveVoiceRoom> listSearchCountryRoom(String sysOrigin, String countryCode,
|
||||
@ -234,6 +275,47 @@ public class ActiveVoiceRoomServiceImpl implements ActiveVoiceRoomService {
|
||||
}
|
||||
return criteria;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActiveVoiceRoom> listExplore(
|
||||
String sysOrigin, String userRegion, String countryCode, Set<String> countryCodes, Integer limit) {
|
||||
Set<String> 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<ActiveVoiceRoom> 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<String> safeCountryCodes(Set<String> countryCodes) {
|
||||
return countryCodes == null ? Collections.emptySet() : countryCodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActiveVoiceRoom> listGetActiveRooms(List<Long> roomIds, String sysOrigin,Integer onlineQuantity) {
|
||||
Criteria criteria = Criteria.where("sysOrigin").is(sysOrigin)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user