道岔失表调整
This commit is contained in:
parent
035cc673bf
commit
a211d2e3c0
@ -1,12 +1,7 @@
|
|||||||
package club.joylink.xiannccda.ats.message.collect.convertor;
|
package club.joylink.xiannccda.ats.message.collect.convertor;
|
||||||
|
|
||||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
|
||||||
import club.joylink.xiannccda.ats.message.MessageId;
|
import club.joylink.xiannccda.ats.message.MessageId;
|
||||||
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
||||||
import club.joylink.xiannccda.ats.warn.SwitchLostAlertListener.SwitchLostAlertEvent;
|
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
|
||||||
import com.google.protobuf.GeneratedMessageV3.Builder;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -22,25 +17,14 @@ public class DeviceChangeStatusConvertor extends DefaultConvertor {
|
|||||||
return DataTypeEnum.DEVICE;
|
return DataTypeEnum.DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/*@Override
|
||||||
protected void eventHandle(List<Builder> builders) {
|
protected void eventHandle(List<Builder> builders) {
|
||||||
AlertManager alertManager = AlertManager.getDefault();
|
AlertManager alertManager = AlertManager.getDefault();
|
||||||
for (Builder builder : builders) {
|
for (Builder builder : builders) {
|
||||||
/* if (builder instanceof Rtu.Builder rtuBuild) {
|
|
||||||
alertManager.emit(new BlueDisplayAlertEvent(rtuBuild));
|
|
||||||
} else*/
|
|
||||||
// if (builder instanceof Track.Builder trackBuild) {
|
|
||||||
// alertManager.emit(new SwitchAndTrackLedAlertEvent(trackBuild));
|
|
||||||
// alertManager.emit(new AxleLedAlertEvent(trackBuild));
|
|
||||||
|
|
||||||
// } else
|
|
||||||
if (builder instanceof Switch.Builder switchBuild) {
|
if (builder instanceof Switch.Builder switchBuild) {
|
||||||
alertManager.emit(new SwitchLostAlertEvent(switchBuild));
|
alertManager.emit(new SwitchLostAlertEvent(switchBuild));
|
||||||
// alertManager.emit(new SwitchAndTrackLedAlertEvent(switchBuild));
|
}
|
||||||
// alertManager.emit(new AxleLedAlertEvent(switchBuild));
|
|
||||||
} /*else if (builder instanceof Platform.Builder platformBuild) {
|
|
||||||
alertManager.emit(new PlatformAlertEvent(platformBuild));
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,7 @@
|
|||||||
package club.joylink.xiannccda.ats.message.collect.convertor;
|
package club.joylink.xiannccda.ats.message.collect.convertor;
|
||||||
|
|
||||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
|
||||||
import club.joylink.xiannccda.ats.message.MessageId;
|
import club.joylink.xiannccda.ats.message.MessageId;
|
||||||
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
||||||
import club.joylink.xiannccda.ats.warn.SwitchLostAlertListener.SwitchLostAlertEvent;
|
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
|
||||||
import com.google.protobuf.GeneratedMessageV3.Builder;
|
|
||||||
import java.util.List;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -22,22 +17,15 @@ public class DeviceInitConvertor extends DefaultConvertor {
|
|||||||
return DataTypeEnum.DEVICE;
|
return DataTypeEnum.DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/*@Override
|
||||||
protected void eventHandle(List<Builder> builders) {
|
protected void eventHandle(List<Builder> builders) {
|
||||||
AlertManager alertManager = AlertManager.getDefault();
|
AlertManager alertManager = AlertManager.getDefault();
|
||||||
for (Builder builder : builders) {
|
for (Builder builder : builders) {
|
||||||
/* if (builder instanceof Rtu.Builder rtuBuild) {
|
|
||||||
alertManager.emit(new BlueDisplayAlertEvent(rtuBuild));
|
|
||||||
} else */
|
|
||||||
// if (builder instanceof Track.Builder trackBuild) {
|
|
||||||
// alertManager.emit(new SwitchAndTrackLedAlertEvent(trackBuild));
|
|
||||||
// alertManager.emit(new AxleLedAlertEvent(trackBuild));
|
|
||||||
// } else
|
|
||||||
if (builder instanceof Switch.Builder switchBuild) {
|
if (builder instanceof Switch.Builder switchBuild) {
|
||||||
// alertManager.emit(new SwitchAndTrackLedAlertEvent(switchBuild));
|
|
||||||
// alertManager.emit(new AxleLedAlertEvent(switchBuild));
|
|
||||||
alertManager.emit(new SwitchLostAlertEvent(switchBuild));
|
alertManager.emit(new SwitchLostAlertEvent(switchBuild));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -68,19 +68,6 @@ public class AxleLedMostMonitorListener implements AlertSourceEventListener<LedM
|
|||||||
}
|
}
|
||||||
String ledName = lockSource.alertType == AlertType.AXLE_LED_RED ? "红光带" : "橙光带";
|
String ledName = lockSource.alertType == AlertType.AXLE_LED_RED ? "红光带" : "橙光带";
|
||||||
List<String> warnDeviceList = alertDataSource.findAllWarnDeviceForList(lineIdInt, customName);
|
List<String> warnDeviceList = alertDataSource.findAllWarnDeviceForList(lineIdInt, customName);
|
||||||
/*deviceStatusList.stream().filter(d -> d.saveAlertDataSouce).forEach(d -> {
|
|
||||||
String alertMsg = String.format("出现%s设备[%s]", ledName, d.deviceCode);
|
|
||||||
|
|
||||||
if (Objects.nonNull(areaConfigVO) && warnDeviceList.size() >= ledThreshold) {
|
|
||||||
String warnDevices = String.join(",", warnDeviceList);
|
|
||||||
alertMsg = String.format("%s-出现大面积%s设备[%s]", areaConfigVO.getAreaName(), ledName, warnDevices);
|
|
||||||
}
|
|
||||||
String alertMsg = String.format("出现%s设备[%s]", ledName, d.deviceCode);
|
|
||||||
NccAlertInfo alertInfo = this.alertInfoService.createAlert2(null, lockSource.alertType, lineIdInt, LocalDateTime.now(), alertMsg, String.valueOf(d.layoutId),
|
|
||||||
AlertDeviceType.DEVICE_TYPE_TRACK, false);
|
|
||||||
alertManager.emit(alertInfo);
|
|
||||||
});*/
|
|
||||||
|
|
||||||
if (Objects.nonNull(areaConfigVO) && deviceStatusList.stream().anyMatch(d -> d.saveAlertDataSouce) && warnDeviceList.size() >= ledThreshold) {
|
if (Objects.nonNull(areaConfigVO) && deviceStatusList.stream().anyMatch(d -> d.saveAlertDataSouce) && warnDeviceList.size() >= ledThreshold) {
|
||||||
//发布大面积
|
//发布大面积
|
||||||
String warnDevices = String.join(",", warnDeviceList);
|
String warnDevices = String.join(",", warnDeviceList);
|
||||||
@ -89,7 +76,6 @@ public class AxleLedMostMonitorListener implements AlertSourceEventListener<LedM
|
|||||||
alertManager.emit(alertInfoMost);
|
alertManager.emit(alertInfoMost);
|
||||||
} else {
|
} else {
|
||||||
deviceStatusList.stream().filter(d -> d.saveAlertDataSouce).forEach(d -> {
|
deviceStatusList.stream().filter(d -> d.saveAlertDataSouce).forEach(d -> {
|
||||||
log.error("---------------" + d.deviceCode);
|
|
||||||
String alertMsg = String.format("出现%s设备[%s]", ledName, d.deviceCode);
|
String alertMsg = String.format("出现%s设备[%s]", ledName, d.deviceCode);
|
||||||
NccAlertInfo alertInfo = this.alertInfoService.createAlert2(null, lockSource.alertType, lineIdInt, LocalDateTime.now(), alertMsg, String.valueOf(d.layoutId),
|
NccAlertInfo alertInfo = this.alertInfoService.createAlert2(null, lockSource.alertType, lineIdInt, LocalDateTime.now(), alertMsg, String.valueOf(d.layoutId),
|
||||||
AlertDeviceType.DEVICE_TYPE_TRACK, false);
|
AlertDeviceType.DEVICE_TYPE_TRACK, false);
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package club.joylink.xiannccda.ats.warn;
|
package club.joylink.xiannccda.ats.warn.lost;
|
||||||
|
|
||||||
import club.joylink.xiannccda.alert.core.AlertSourceEventListener;
|
import club.joylink.xiannccda.alert.core.AlertSourceEventListener;
|
||||||
import club.joylink.xiannccda.ats.warn.SwitchLostAlertListener.SwitchLostAlertEvent;
|
import club.joylink.xiannccda.ats.warn.DeviceAlertEvent;
|
||||||
|
import club.joylink.xiannccda.ats.warn.lost.SwitchLostAlertListener.SwitchLostAlertEvent;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
@Component
|
//@Component
|
||||||
|
@Deprecated
|
||||||
public class SwitchLostAlertListener implements AlertSourceEventListener<SwitchLostAlertEvent> {
|
public class SwitchLostAlertListener implements AlertSourceEventListener<SwitchLostAlertEvent> {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@ -27,7 +28,7 @@ public class SwitchLostAlertListener implements AlertSourceEventListener<SwitchL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SwitchLostAlertEvent extends DeviceAlertEvent<Switch.Builder> {
|
public static class SwitchLostAlertEvent extends DeviceAlertEvent<Builder> {
|
||||||
|
|
||||||
public SwitchLostAlertEvent(Builder source) {
|
public SwitchLostAlertEvent(Builder source) {
|
||||||
super(source);
|
super(source);
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.xiannccda.ats.warn;
|
package club.joylink.xiannccda.ats.warn.lost;
|
||||||
|
|
||||||
import club.joylink.xiannccda.alert.NccAlertInfo;
|
import club.joylink.xiannccda.alert.NccAlertInfo;
|
||||||
import club.joylink.xiannccda.alert.core.AlertDataSource;
|
import club.joylink.xiannccda.alert.core.AlertDataSource;
|
||||||
@ -9,7 +9,7 @@ import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository;
|
|||||||
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
|
||||||
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
||||||
import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData;
|
import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData;
|
||||||
import club.joylink.xiannccda.ats.warn.SwitchLostMostAlertListener.SwitchLostMostEvent;
|
import club.joylink.xiannccda.ats.warn.lost.SwitchLostMostAlertListener.SwitchLostMostEvent;
|
||||||
import club.joylink.xiannccda.dto.protos.AlertConstProto.AlertType;
|
import club.joylink.xiannccda.dto.protos.AlertConstProto.AlertType;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
||||||
@ -19,18 +19,15 @@ import club.joylink.xiannccda.service.AlertInfoService;
|
|||||||
import club.joylink.xiannccda.service.config.DeviceGuardConfigService;
|
import club.joylink.xiannccda.service.config.DeviceGuardConfigService;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.google.protobuf.GeneratedMessageV3;
|
import com.google.protobuf.GeneratedMessageV3;
|
||||||
import com.google.protobuf.MessageOrBuilder;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
//@Component
|
||||||
|
@Deprecated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SwitchLostAlertMonitoringTask2 implements AlertMonitoringTask {
|
public class SwitchLostAlertMonitoringTask2 implements AlertMonitoringTask {
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
package club.joylink.xiannccda.ats.warn;
|
package club.joylink.xiannccda.ats.warn.lost;
|
||||||
|
|
||||||
import club.joylink.xiannccda.alert.NccAlertInfo;
|
import club.joylink.xiannccda.alert.NccAlertInfo;
|
||||||
import club.joylink.xiannccda.alert.core.AlertDataSource;
|
import club.joylink.xiannccda.alert.core.AlertDataSource;
|
||||||
@ -6,7 +6,8 @@ import club.joylink.xiannccda.alert.core.AlertDeviceType;
|
|||||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||||
import club.joylink.xiannccda.alert.core.AlertSourceEventListener;
|
import club.joylink.xiannccda.alert.core.AlertSourceEventListener;
|
||||||
import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository;
|
import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository;
|
||||||
import club.joylink.xiannccda.ats.warn.SwitchLostMostAlertListener.SwitchLostMostEvent;
|
import club.joylink.xiannccda.ats.warn.DeviceAlertEvent;
|
||||||
|
import club.joylink.xiannccda.ats.warn.lost.SwitchLostMostAlertListener.SwitchLostMostEvent;
|
||||||
import club.joylink.xiannccda.dto.protos.AlertConstProto.AlertType;
|
import club.joylink.xiannccda.dto.protos.AlertConstProto.AlertType;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
||||||
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch.Builder;
|
||||||
@ -20,10 +21,10 @@ import java.util.List;
|
|||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
|
|
||||||
@Component
|
//@Component
|
||||||
|
@Deprecated
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class SwitchLostMostAlertListener implements AlertSourceEventListener<SwitchLostMostEvent> {
|
public class SwitchLostMostAlertListener implements AlertSourceEventListener<SwitchLostMostEvent> {
|
||||||
|
|
||||||
@ -79,7 +80,7 @@ public class SwitchLostMostAlertListener implements AlertSourceEventListener<Swi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SwitchLostMostEvent extends DeviceAlertEvent<Switch.Builder> {
|
public static class SwitchLostMostEvent extends DeviceAlertEvent<Builder> {
|
||||||
|
|
||||||
private boolean alert;
|
private boolean alert;
|
||||||
|
|
@ -0,0 +1,82 @@
|
|||||||
|
package club.joylink.xiannccda.ats.warn.lost;
|
||||||
|
|
||||||
|
import club.joylink.xiannccda.alert.NccAlertInfo;
|
||||||
|
import club.joylink.xiannccda.alert.core.AlertDataSource;
|
||||||
|
import club.joylink.xiannccda.alert.core.AlertDeviceType;
|
||||||
|
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||||
|
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||||
|
import club.joylink.xiannccda.ats.cache.LineGraphicDataRepository;
|
||||||
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository;
|
||||||
|
import club.joylink.xiannccda.ats.message.collect.DeviceDataRepository.DataTypeEnum;
|
||||||
|
import club.joylink.xiannccda.ats.message.collect.datasource.DeviceStatusData;
|
||||||
|
import club.joylink.xiannccda.dto.protos.AlertConstProto.AlertType;
|
||||||
|
import club.joylink.xiannccda.dto.protos.DeviceStatusProto.Switch;
|
||||||
|
import club.joylink.xiannccda.dto.protos.GuardConfigProto.GuardConfig;
|
||||||
|
import club.joylink.xiannccda.dto.protos.LayoutGraphicsProto.Turnout;
|
||||||
|
import club.joylink.xiannccda.service.AlertInfoService;
|
||||||
|
import club.joylink.xiannccda.service.config.DeviceGuardConfigService;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
|
import com.google.protobuf.GeneratedMessageV3.Builder;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Slf4j
|
||||||
|
public class SwitchLostTask implements AlertMonitoringTask {
|
||||||
|
|
||||||
|
private DeviceGuardConfigService configService;
|
||||||
|
private AlertInfoService alertInfoService;
|
||||||
|
|
||||||
|
public SwitchLostTask(DeviceGuardConfigService configService, AlertInfoService alertInfoService) {
|
||||||
|
this.configService = configService;
|
||||||
|
this.alertInfoService = alertInfoService;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final AlertManager alertManager = AlertManager.getDefault();
|
||||||
|
private final AlertDataSource alertDataSource = AlertDataSource.getInstance();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "SWITCH_LOST_ALTER";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Set<String> lineCollSet = DeviceDataRepository.getAllLines();
|
||||||
|
if (CollectionUtils.isEmpty(lineCollSet)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (String lineId : lineCollSet) {
|
||||||
|
DeviceStatusData deviceStatusData = DeviceDataRepository.findDataSouce(lineId, DataTypeEnum.DEVICE);
|
||||||
|
Map<String, Builder> deviceBuildMap = deviceStatusData.getAllDeviceMap().get(Switch.getDescriptor().getName());
|
||||||
|
for (Builder deviceBuild : deviceBuildMap.values()) {
|
||||||
|
this.handle(deviceBuild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handle(Builder deviceBuild) {
|
||||||
|
if (deviceBuild instanceof Switch.Builder switchBuild) {
|
||||||
|
GuardConfig guardConfig = this.configService.getGuardConfig(switchBuild.getLineId());
|
||||||
|
boolean isLost = switchBuild.getIpSingleSwitchStusLostIndication();
|
||||||
|
if (isLost && this.timeOver(switchBuild.getReceiveTime(), guardConfig.getSwitchLostTimes())) {
|
||||||
|
Optional<Turnout> turnoutOpt = LineGraphicDataRepository.getDeviceOptByCode(switchBuild.getLineId(), switchBuild.getId(), Turnout.class);
|
||||||
|
String layoutId = turnoutOpt.map(d -> String.valueOf(d.getCommon().getId())).orElse("");
|
||||||
|
if (alertDataSource.putAlterDevice(switchBuild.getLineId(), this.getName(), switchBuild.getId())) {
|
||||||
|
log.info("道岔失表超时,准备报警 线路[{}] 设备[{}] 接受时间[{}] 发送时间[{}] 对应地图设备id[{}]"
|
||||||
|
, switchBuild.getLineId(), switchBuild.getId(), switchBuild.getReceiveTime(), switchBuild.getTimestamp(), layoutId);
|
||||||
|
String alertMsg = String.format("设备[%s]失表", switchBuild.getId());
|
||||||
|
NccAlertInfo alertInfo = this.alertInfoService.createAlert2(Optional.empty(), AlertType.SWITCH_LOST, switchBuild, alertMsg, layoutId,
|
||||||
|
AlertDeviceType.DEVICE_TYPE_SWITCH, false);
|
||||||
|
alertManager.emit(alertInfo);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
alertDataSource.removeAlterDevice(switchBuild.getLineId(), this.getName(), switchBuild.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user