增加屏蔽门蓝显故障发布任务
This commit is contained in:
parent
dfef6a21e4
commit
5c4cc34acf
@ -4,6 +4,8 @@ import java.time.LocalDateTime;
|
||||
|
||||
public interface AlertDetail {
|
||||
|
||||
AlertType getAlertType();
|
||||
|
||||
LocalDateTime getAlertTime();
|
||||
|
||||
Integer getAlertTipId();
|
||||
|
@ -1,19 +1,27 @@
|
||||
package club.joylink.xiannccda.alert.xian3;
|
||||
package club.joylink.xiannccda.alert;
|
||||
|
||||
import club.joylink.xiannccda.alert.AlertDetail;
|
||||
import club.joylink.xiannccda.alert.AlertType;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Builder;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 西安三号线报警
|
||||
*/
|
||||
@Builder
|
||||
public class Xian3TrainDelayAlert implements AlertDetail {
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class AlertDetailImpl implements AlertDetail {
|
||||
|
||||
private AlertType alertType;
|
||||
private LocalDateTime alertTime;
|
||||
private String info;
|
||||
private Integer alertTipId;
|
||||
private String info;
|
||||
private String deviceInfo;
|
||||
private String reason;
|
||||
|
||||
@Override
|
||||
public AlertType getAlertType() {
|
||||
return alertType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getAlertTime() {
|
||||
@ -27,20 +35,16 @@ public class Xian3TrainDelayAlert implements AlertDetail {
|
||||
|
||||
@Override
|
||||
public String getDeviceInfo() {
|
||||
return "道岔P0110";
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReason() {
|
||||
return "道岔P0110失表";
|
||||
return reason;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getAlertTipId() {
|
||||
return alertTipId;
|
||||
}
|
||||
|
||||
public AlertType getAlertType() {
|
||||
return AlertType.XIAN3_TRAIN_DELAY;
|
||||
}
|
||||
}
|
35
src/main/java/club/joylink/xiannccda/alert/AlertEmitJob.java
Normal file
35
src/main/java/club/joylink/xiannccda/alert/AlertEmitJob.java
Normal file
@ -0,0 +1,35 @@
|
||||
package club.joylink.xiannccda.alert;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Order(1)
|
||||
@Component
|
||||
public class AlertEmitJob implements ApplicationRunner {
|
||||
|
||||
private TrainDelayAlertMonitoringTask trainDelayAlertMonitoringTask;
|
||||
private BlueDisplayAlertMonitoringTask blueDisplayAlertMonitoringTask;
|
||||
private PlatformDoorAlertMonitoringTask platformDoorAlertMonitoringTask;
|
||||
|
||||
public AlertEmitJob(
|
||||
TrainDelayAlertMonitoringTask trainDelayAlertMonitoringTask,
|
||||
BlueDisplayAlertMonitoringTask blueDisplayAlertMonitoringTask,
|
||||
PlatformDoorAlertMonitoringTask platformDoorAlertMonitoringTask) {
|
||||
this.trainDelayAlertMonitoringTask = trainDelayAlertMonitoringTask;
|
||||
this.blueDisplayAlertMonitoringTask = blueDisplayAlertMonitoringTask;
|
||||
this.platformDoorAlertMonitoringTask = platformDoorAlertMonitoringTask;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
//报警源
|
||||
alertManager.addTask(trainDelayAlertMonitoringTask);
|
||||
alertManager.addTask(blueDisplayAlertMonitoringTask);
|
||||
alertManager.addTask(platformDoorAlertMonitoringTask);
|
||||
}
|
||||
}
|
@ -13,10 +13,10 @@ import org.springframework.stereotype.Component;
|
||||
|
||||
@Order
|
||||
@Component
|
||||
public class AlertJob implements ApplicationRunner {
|
||||
public class AlertListenerJob implements ApplicationRunner {
|
||||
private final WsMessageServerManager wsMessageServerManager;
|
||||
|
||||
public AlertJob(WsMessageServerManager wsMessageServerManager) {
|
||||
public AlertListenerJob(WsMessageServerManager wsMessageServerManager) {
|
||||
this.wsMessageServerManager = wsMessageServerManager;
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ public class AlertJob implements ApplicationRunner {
|
||||
//添加报警事件监听器
|
||||
addAlertListeners();
|
||||
//注册西安NCC的报警ws消息发送服务
|
||||
wsMessageServerManager.registerMessageServer(NccAlertMessageServer.getInstance());
|
||||
wsMessageServerManager.registerMessageServer(NccAlertMessageServer.getDefault());
|
||||
//启动报警源事件监测任务
|
||||
AlertManager.getInstance().taskStart();
|
||||
}
|
||||
@ -49,14 +49,15 @@ public class AlertJob implements ApplicationRunner {
|
||||
}
|
||||
|
||||
private void addAlertListeners() {
|
||||
NccAlertMessageServer nccAlertMessageServer = NccAlertMessageServer.getInstance();
|
||||
NccAlertMessageServer nccAlertMessageServer = NccAlertMessageServer.getDefault();
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
//报警监听
|
||||
//添加消息
|
||||
alertManager.on(new Listener<NccAlertInfo>() {
|
||||
@Override
|
||||
public void accept(NccAlertInfo event) {
|
||||
nccAlertMessageServer.addMsg(event);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@ -2,11 +2,17 @@ package club.joylink.xiannccda.alert;
|
||||
|
||||
public enum AlertType {
|
||||
/**
|
||||
* 西安三蓝显
|
||||
* 蓝显
|
||||
*/
|
||||
XIAN3_BLUE_DISPLAY,
|
||||
BLUE_DISPLAY,
|
||||
/**
|
||||
* 西安三列车延误
|
||||
* 列车延误
|
||||
*/
|
||||
XIAN3_TRAIN_DELAY,
|
||||
TRAIN_DELAY,
|
||||
/**
|
||||
* 站台门无关闭锁紧信号
|
||||
*/
|
||||
PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL,
|
||||
PLATFORM_DOOR_CANNOT_OPEN,
|
||||
PLATFORM_DOOR_CANNOT_CLOSE,
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package club.joylink.xiannccda.alert;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||
import club.joylink.xiannccda.entity.AlertTip;
|
||||
import club.joylink.xiannccda.repository.IAlertTipRepository;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class BlueDisplayAlertMonitoringTask implements AlertMonitoringTask {
|
||||
|
||||
private IAlertTipRepository alertTipRepository;
|
||||
private boolean alertTriggered;
|
||||
|
||||
public BlueDisplayAlertMonitoringTask(IAlertTipRepository alertTipRepository) {
|
||||
this.alertTipRepository = alertTipRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "blue_display";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (alertTriggered) {
|
||||
if (now.getSecond() % 30 != 0) {
|
||||
alertTriggered = false;
|
||||
}
|
||||
} else {
|
||||
if (now.getSecond() % 30 == 0) {
|
||||
AlertType alertType = AlertType.BLUE_DISPLAY;
|
||||
LambdaQueryWrapper<AlertTip> queryWrapper = Wrappers.lambdaQuery(AlertTip.class);
|
||||
queryWrapper.eq(AlertTip::getAlertType, alertType)
|
||||
.eq(AlertTip::getLocationType, AlertTipLocationType.QX);
|
||||
AlertTip alertTip = alertTipRepository.getOne(queryWrapper);
|
||||
Integer alertTipId = alertTip == null ? null : alertTip.getId();
|
||||
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
AlertDetailImpl alert = new AlertDetailImpl(alertType, now, alertTipId, "[3号线]全线蓝显",
|
||||
"轨旁设备", "轨旁设备故障");
|
||||
alertManager.emit(alert);
|
||||
alertTriggered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
package club.joylink.xiannccda.alert;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||
import club.joylink.xiannccda.entity.AlertTip;
|
||||
import club.joylink.xiannccda.repository.IAlertTipRepository;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PlatformDoorAlertMonitoringTask implements AlertMonitoringTask {
|
||||
|
||||
private IAlertTipRepository alertTipRepository;
|
||||
private boolean alertTriggered;
|
||||
|
||||
public PlatformDoorAlertMonitoringTask(IAlertTipRepository alertTipRepository) {
|
||||
this.alertTipRepository = alertTipRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "platform_door";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (alertTriggered) {
|
||||
if (now.getSecond() % 30 != 0) {
|
||||
alertTriggered = false;
|
||||
}
|
||||
} else {
|
||||
if (now.getSecond() % 30 == 0) {
|
||||
emitPlatformDoorWithoutLockedSignalAlert(now, alertTipRepository);
|
||||
emitPlatformDoorCannotOpenAlert(now, alertTipRepository);
|
||||
emitPlatformDoorCannotCloseAlert(now, alertTipRepository);
|
||||
alertTriggered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void emitPlatformDoorWithoutLockedSignalAlert(LocalDateTime now,
|
||||
IAlertTipRepository alertTipRepository) {
|
||||
AlertType alertType = AlertType.PLATFORM_DOOR_WITHOUT_LOCKED_SIGNAL;
|
||||
LambdaQueryWrapper<AlertTip> queryWrapper = Wrappers.lambdaQuery(AlertTip.class);
|
||||
queryWrapper.eq(AlertTip::getAlertType, alertType);
|
||||
AlertTip alertTip = alertTipRepository.getOne(queryWrapper);
|
||||
Integer alertTipId = alertTip == null ? null : alertTip.getId();
|
||||
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
AlertDetailImpl alert = new AlertDetailImpl(alertType, now, alertTipId,
|
||||
"[3号线]站台门无关闭锁紧信号", "鱼化寨下行站台", "鱼化寨下行站台无关闭锁紧信号");
|
||||
alertManager.emit(alert);
|
||||
}
|
||||
|
||||
public void emitPlatformDoorCannotOpenAlert(LocalDateTime now,
|
||||
IAlertTipRepository alertTipRepository) {
|
||||
AlertType alertType = AlertType.PLATFORM_DOOR_CANNOT_OPEN;
|
||||
LambdaQueryWrapper<AlertTip> queryWrapper = Wrappers.lambdaQuery(AlertTip.class);
|
||||
queryWrapper.eq(AlertTip::getAlertType, alertType);
|
||||
AlertTip alertTip = alertTipRepository.getOne(queryWrapper);
|
||||
Integer alertTipId = alertTip == null ? null : alertTip.getId();
|
||||
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
AlertDetailImpl alert = new AlertDetailImpl(alertType, now, alertTipId,
|
||||
"[3号线]站台门整侧站台门无法打开", "鱼化寨下行站台", "鱼化寨下行站台整侧站台门无法打开");
|
||||
alertManager.emit(alert);
|
||||
}
|
||||
|
||||
public void emitPlatformDoorCannotCloseAlert(LocalDateTime now,
|
||||
IAlertTipRepository alertTipRepository) {
|
||||
AlertType alertType = AlertType.PLATFORM_DOOR_CANNOT_CLOSE;
|
||||
LambdaQueryWrapper<AlertTip> queryWrapper = Wrappers.lambdaQuery(AlertTip.class);
|
||||
queryWrapper.eq(AlertTip::getAlertType, alertType);
|
||||
AlertTip alertTip = alertTipRepository.getOne(queryWrapper);
|
||||
Integer alertTipId = alertTip == null ? null : alertTip.getId();
|
||||
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
AlertDetailImpl alert = new AlertDetailImpl(alertType, now, alertTipId,
|
||||
"[3号线]站台门整侧站台门无法关闭", "鱼化寨下行站台", "鱼化寨下行站台整侧站台门无法关闭");
|
||||
alertManager.emit(alert);
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package club.joylink.xiannccda.alert;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||
import club.joylink.xiannccda.entity.AlertTip;
|
||||
import club.joylink.xiannccda.repository.IAlertTipRepository;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import java.time.LocalDateTime;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TrainDelayAlertMonitoringTask implements AlertMonitoringTask {
|
||||
|
||||
private IAlertTipRepository alertTipRepository;
|
||||
private boolean alertTriggered;
|
||||
|
||||
public TrainDelayAlertMonitoringTask(IAlertTipRepository alertTipRepository) {
|
||||
this.alertTipRepository = alertTipRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Train_Delay";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (alertTriggered) {
|
||||
if (now.getSecond() % 30 != 0) {
|
||||
alertTriggered = false;
|
||||
}
|
||||
} else {
|
||||
if (now.getSecond() % 30 == 0) {
|
||||
AlertType alertType = AlertType.PLATFORM_DOOR_CANNOT_OPEN;
|
||||
LambdaQueryWrapper<AlertTip> queryWrapper = Wrappers.lambdaQuery(AlertTip.class);
|
||||
queryWrapper.eq(AlertTip::getAlertType, alertType)
|
||||
.eq(AlertTip::getTimeType, AlertTipTimeType.CLOCK_7_9_AND_19_21);
|
||||
AlertTip alertTip = alertTipRepository.getOne(queryWrapper);
|
||||
Integer alertTipId = alertTip == null ? null : alertTip.getId();
|
||||
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
AlertDetailImpl alert = new AlertDetailImpl(alertType, now, alertTipId,
|
||||
String.format("[3号线]列车[01-1001]按计划应于%s抵达[%s],现因[%s]晚点%s分钟",
|
||||
now.minusMinutes(2), "鱼化寨", "道岔P0110失表", "2"), "道岔[P0110]", "道岔[P0110]失表");
|
||||
alertManager.emit(alert);
|
||||
alertTriggered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package club.joylink.xiannccda.alert.xian3;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.repository.IAlertTipRepository;
|
||||
import org.springframework.boot.ApplicationArguments;
|
||||
import org.springframework.boot.ApplicationRunner;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Order(1)
|
||||
@Component
|
||||
public class Xian3AlertJob implements ApplicationRunner {
|
||||
|
||||
private final IAlertTipRepository alertTipRepository;
|
||||
|
||||
public Xian3AlertJob(IAlertTipRepository alertTipRepository) {
|
||||
this.alertTipRepository = alertTipRepository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
//报警源
|
||||
alertManager.addTask(new Xian3TrainDelayAlertMonitoringTask());
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
package club.joylink.xiannccda.alert.xian3;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertInfo;
|
||||
import java.time.LocalDateTime;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 西安3蓝显
|
||||
*/
|
||||
@Data
|
||||
public class Xian3BlueDisplayAlert implements AlertInfo {
|
||||
private String id;
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLevel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getAlertTime() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package club.joylink.xiannccda.alert.xian3;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertInfo;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public class Xian3SupplyShortageAlert implements AlertInfo {
|
||||
private String id;
|
||||
|
||||
public Xian3SupplyShortageAlert(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLevel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LocalDateTime getAlertTime() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInfo() {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
package club.joylink.xiannccda.alert.xian3;
|
||||
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Xian3TrainDelayAlertMonitoringTask implements AlertMonitoringTask {
|
||||
|
||||
private final AtomicInteger id = new AtomicInteger(1);
|
||||
|
||||
private boolean alertTriggered;
|
||||
|
||||
public Xian3TrainDelayAlertMonitoringTask() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Xian3_Train_Delay";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
if (alertTriggered) {
|
||||
if (now.getSecond() % 10 != 0) {
|
||||
alertTriggered = false;
|
||||
}
|
||||
} else {
|
||||
if (now.getSecond() % 10 == 0) {
|
||||
AlertManager alertManager = AlertManager.getInstance();
|
||||
Xian3TrainDelayAlert alert = Xian3TrainDelayAlert.builder()
|
||||
.alertTime(now)
|
||||
.info(String.format("[3号线]列车[01-1001]按计划应于%s抵达[%s],现因[%s]晚点%s分钟",
|
||||
now.minusMinutes(2), "鱼化寨", "道岔P0110失表", "2"))
|
||||
.alertTipId(1)
|
||||
.build();
|
||||
alertManager.emit(alert);
|
||||
alertTriggered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -66,7 +66,7 @@ public class NccAlertMessageServer implements IMessageServer {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public static NccAlertMessageServer getInstance() {
|
||||
public static NccAlertMessageServer getDefault() {
|
||||
return getInstance("default");
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,6 @@ package club.joylink.xiannccda.alert;
|
||||
import club.joylink.xiannccda.alert.core.AlertManager;
|
||||
import club.joylink.xiannccda.alert.core.AlertMonitoringTask;
|
||||
import club.joylink.xiannccda.alert.core.AlertSourceEvent;
|
||||
import club.joylink.xiannccda.alert.xian3.Xian3SupplyShortageAlert;
|
||||
import club.joylink.xiannccda.alert.xian3.Xian3TrainDelayAlert;
|
||||
import club.joylink.xiannccda.event.Listener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@ -23,8 +21,7 @@ public class AlertManagerTest {
|
||||
//可能报警事件监听器
|
||||
manager.on(new SuppliesRemainInsufficientListener(sid));
|
||||
//报警事件监听器
|
||||
manager.on((Listener<Xian3TrainDelayAlert>) event -> System.out.println("列车延误报警"));
|
||||
manager.on((Listener<Xian3SupplyShortageAlert>) event -> System.out.println("物资紧缺报警"));
|
||||
manager.on((Listener<AlertDetailImpl>) event -> System.out.println("列车延误报警"));
|
||||
|
||||
manager.taskStart();
|
||||
manager.emit(new SuppliesCountUpdatedEvent(this, 2));
|
||||
@ -78,9 +75,6 @@ public class AlertManagerTest {
|
||||
|
||||
@Override
|
||||
public void accept(SuppliesCountUpdatedEvent event) {
|
||||
if (event.getRemain() <= SuppliesAlertMin) {
|
||||
AlertManager.getInstance(sId).emit(new Xian3SupplyShortageAlert("2"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 90b6f4600e531c496d849163653acb80c6e933ea
|
||||
Subproject commit eb0ad6e4305642b6619f5e97d1498ad5dc5a6d42
|
Loading…
Reference in New Issue
Block a user