rev:更新
This commit is contained in:
@@ -178,10 +178,10 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
|||||||
if (!ObjectUtil.isEmpty(inst)) {
|
if (!ObjectUtil.isEmpty(inst)) {
|
||||||
instructionService.finish(inst.getInstruction_id());
|
instructionService.finish(inst.getInstruction_id());
|
||||||
} else {
|
} else {
|
||||||
log.warn("指令号:{},未反馈wms任务完成,因为agv上报指令号查询指令为空!", inst.getInstruction_code());
|
log.warn("指令号:{},未反馈wms任务完成,因为agv上报指令号查询指令为空!", ikey);
|
||||||
}
|
}
|
||||||
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
|
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
|
||||||
log.info("指令号:{},已反馈agv任务完成!", inst.getInstruction_code());
|
log.info("指令号:{},已反馈agv任务完成!", ikey);
|
||||||
}
|
}
|
||||||
//进入交通灯区域
|
//进入交通灯区域
|
||||||
else if (phase == 0x50) {
|
else if (phase == 0x50) {
|
||||||
@@ -249,8 +249,13 @@ public class OneNDCSocketConnectionAutoRun extends AbstractAutoRunnable {
|
|||||||
} else {
|
} else {
|
||||||
//上报异常信息
|
//上报异常信息
|
||||||
//(不需要WCS反馈)
|
//(不需要WCS反馈)
|
||||||
if (phase == 0x67) {
|
// if (phase == 0x67) {
|
||||||
device = deviceAppService.findDeviceByCode(Integer.toString(arr[27]));
|
// device = deviceAppService.findDeviceByCode(Integer.toString(arr[27]));
|
||||||
|
// } else {
|
||||||
|
// device = deviceAppService.findDeviceByCode(Integer.toString(arr[20]));
|
||||||
|
// }
|
||||||
|
if (phase == 0x67 || phase == 0x70 || phase == 0x71 || phase == 0x72 || phase == 0x73 || phase == 0x74 ) {
|
||||||
|
device = deviceAppService.findDeviceByCode(Integer.toString(arr[18] * 256 + arr[19]));
|
||||||
} else {
|
} else {
|
||||||
device = deviceAppService.findDeviceByCode(Integer.toString(arr[20]));
|
device = deviceAppService.findDeviceByCode(Integer.toString(arr[20]));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import org.nl.acs.instruction.service.impl.InstructionServiceImpl;
|
|||||||
import org.nl.acs.log.LokiLog;
|
import org.nl.acs.log.LokiLog;
|
||||||
import org.nl.acs.log.LokiLogType;
|
import org.nl.acs.log.LokiLogType;
|
||||||
import org.nl.acs.log.service.DeviceExecuteLogService;
|
import org.nl.acs.log.service.DeviceExecuteLogService;
|
||||||
|
import org.nl.acs.monitor.DeviceStageMonitor;
|
||||||
import org.nl.acs.opc.Device;
|
import org.nl.acs.opc.Device;
|
||||||
import org.nl.acs.opc.DeviceAppService;
|
import org.nl.acs.opc.DeviceAppService;
|
||||||
import org.nl.acs.task.service.TaskService;
|
import org.nl.acs.task.service.TaskService;
|
||||||
@@ -44,7 +45,7 @@ import static org.nl.acs.agv.server.impl.NDCAgvServiceImpl.Bytes2HexString;
|
|||||||
@Slf4j
|
@Slf4j
|
||||||
@Data
|
@Data
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements DeviceDriver {
|
public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements DeviceDriver, DeviceStageMonitor {
|
||||||
|
|
||||||
ParamService paramService = SpringContextHolder.getBean(ParamServiceImpl.class);
|
ParamService paramService = SpringContextHolder.getBean(ParamServiceImpl.class);
|
||||||
InstructionService instructionService = SpringContextHolder.getBean(InstructionServiceImpl.class);
|
InstructionService instructionService = SpringContextHolder.getBean(InstructionServiceImpl.class);
|
||||||
@@ -59,6 +60,7 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
int weight = 0;
|
int weight = 0;
|
||||||
String device_code = "";
|
String device_code = "";
|
||||||
int phase = 0;
|
int phase = 0;
|
||||||
|
private Instruction instruction;
|
||||||
|
|
||||||
int x = 0; //x坐标
|
int x = 0; //x坐标
|
||||||
int y = 0; //y坐标
|
int y = 0; //y坐标
|
||||||
@@ -96,7 +98,10 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
agv_device = deviceAppService.findDeviceByCode(String.valueOf(carno));
|
agv_device = deviceAppService.findDeviceByCode(String.valueOf(carno));
|
||||||
}
|
}
|
||||||
if (ikey != 0) {
|
if (ikey != 0) {
|
||||||
inst = instructionService.findByCodeFromCache(String.valueOf(ikey));
|
if (phase != 0x67 && phase != 0x71 && phase != 0x72 && phase != 0x73 && phase != 0x74 && phase != 0x75) {
|
||||||
|
inst = instructionService.findByCodeFromCache(String.valueOf(ikey));
|
||||||
|
this.instruction = inst;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!ObjectUtil.isEmpty(link_inst)) {
|
if (!ObjectUtil.isEmpty(link_inst)) {
|
||||||
link_flag = true;
|
link_flag = true;
|
||||||
@@ -154,6 +159,10 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
logServer.deviceExecuteLog(this.device_code, "", "", agvaddr + "对应设备号为空");
|
logServer.deviceExecuteLog(this.device_code, "", "", agvaddr + "对应设备号为空");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ObjectUtil.isEmpty(device)){
|
||||||
|
log.info(agvaddr + "对应设备号{},对应的设备信息为空!",device_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//校验agv上报站点编号与指令起始点相同
|
//校验agv上报站点编号与指令起始点相同
|
||||||
if (ObjectUtil.isEmpty(inst)) {
|
if (ObjectUtil.isEmpty(inst)) {
|
||||||
log.info("未找到编号{}对应的指令", ikey);
|
log.info("未找到编号{}对应的指令", ikey);
|
||||||
@@ -218,6 +227,10 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
logServer.deviceExecuteLog(this.device_code, "", "", "对应设备号为空" + device_code);
|
logServer.deviceExecuteLog(this.device_code, "", "", "对应设备号为空" + device_code);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ObjectUtil.isEmpty(device)){
|
||||||
|
log.info(agvaddr + "对应设备号{},对应的设备信息为空!",device_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//校验agv上报站点编号与指令起始点相同
|
//校验agv上报站点编号与指令起始点相同
|
||||||
if (ObjectUtil.isEmpty(inst)) {
|
if (ObjectUtil.isEmpty(inst)) {
|
||||||
log.info("未找到关联编号{}对应的指令", ikey);
|
log.info("未找到关联编号{}对应的指令", ikey);
|
||||||
@@ -281,6 +294,10 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
log.info(agvaddr + "对应设备号为空!");
|
log.info(agvaddr + "对应设备号为空!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ObjectUtil.isEmpty(device)){
|
||||||
|
log.info(agvaddr + "对应设备号{},对应的设备信息为空!",device_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//校验agv上报站点编号与指令起始点相同
|
//校验agv上报站点编号与指令起始点相同
|
||||||
if (ObjectUtil.isEmpty(inst)) {
|
if (ObjectUtil.isEmpty(inst)) {
|
||||||
log.info("未找到关联编号{}对应的指令", ikey);
|
log.info("未找到关联编号{}对应的指令", ikey);
|
||||||
@@ -345,6 +362,10 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
log.info(agvaddr + "对应设备号为空!");
|
log.info(agvaddr + "对应设备号为空!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (ObjectUtil.isEmpty(device)){
|
||||||
|
log.info(agvaddr + "对应设备号{},对应的设备信息为空!",device_code);
|
||||||
|
return;
|
||||||
|
}
|
||||||
//校验agv上报站点编号与指令起始点相同
|
//校验agv上报站点编号与指令起始点相同
|
||||||
if (ObjectUtil.isEmpty(inst)) {
|
if (ObjectUtil.isEmpty(inst)) {
|
||||||
log.info("未找到编号{}对应的指令", ikey);
|
log.info("未找到编号{}对应的指令", ikey);
|
||||||
@@ -388,6 +409,22 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
agvaddr_copy = agvaddr;
|
agvaddr_copy = agvaddr;
|
||||||
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
|
data = NDCAgvService.sendAgvOneModeInst(phase, index, 0);
|
||||||
logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
|
logServer.deviceExecuteLog(this.device_code, "", "", "agvphase:" + phase + "反馈:" + data);
|
||||||
|
} else if (phase == 0x70) {
|
||||||
|
//x坐标
|
||||||
|
x = ikey;
|
||||||
|
} else if (phase == 0x71) {
|
||||||
|
//y坐标
|
||||||
|
y = ikey;
|
||||||
|
} else if (phase == 0x72) {
|
||||||
|
//车辆角度
|
||||||
|
angle = ikey;
|
||||||
|
} else if (phase == 0x73) {
|
||||||
|
//agv电量
|
||||||
|
electric_qty = ikey;
|
||||||
|
} else if (phase == 0x74) {
|
||||||
|
//三色灯状态
|
||||||
|
status = ikey;
|
||||||
|
last_status = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ObjectUtil.isEmpty(data)) {
|
if (!ObjectUtil.isEmpty(data)) {
|
||||||
@@ -399,4 +436,29 @@ public class AgvNdcOneDeviceDriver extends AbstractDeviceDriver implements Devic
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JSONObject getDeviceStatusName() throws Exception {
|
||||||
|
JSONObject jo = new JSONObject();
|
||||||
|
//agv编码
|
||||||
|
jo.put("device_code", this.getDevice().getDevice_code());
|
||||||
|
String status_name = this.status == 1 ? "UNAVAILABLE" : this.status == 2 ? "EXECUTING" : this.status == 4 ? "IDLE" : this.status == 5 ? "CHARGING" : this.status == 6 ? "ERROR" : "UNKNOWN";
|
||||||
|
//agv状态
|
||||||
|
jo.put("device_status", status_name);
|
||||||
|
//电量
|
||||||
|
jo.put("electricity", this.getElectric_qty());
|
||||||
|
//任务号
|
||||||
|
jo.put("transportOrder", ObjectUtil.isEmpty(instruction) ? "0" : instruction.getTask_code());
|
||||||
|
//x坐标
|
||||||
|
jo.put("positionX", this.getX());
|
||||||
|
//y坐标
|
||||||
|
jo.put("positionY", this.getY());
|
||||||
|
//角度
|
||||||
|
jo.put("positionAngle", this.getAngle());
|
||||||
|
return jo;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDeviceStatus(JSONObject data) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ import org.nl.modules.logging.InterfaceLogType;
|
|||||||
import org.nl.modules.logging.annotation.Log;
|
import org.nl.modules.logging.annotation.Log;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -98,4 +95,10 @@ public class WmsToAcsController {
|
|||||||
return new ResponseEntity<>(wmstoacsService.putPlusPullAction(whereJson), HttpStatus.OK);
|
return new ResponseEntity<>(wmstoacsService.putPlusPullAction(whereJson), HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@GetMapping("/test")
|
||||||
|
@SaIgnore
|
||||||
|
public ResponseEntity<Object> test(){
|
||||||
|
return new ResponseEntity<>(wmstoacsService.test(), HttpStatus.OK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,5 +82,7 @@ public interface WmsToAcsService {
|
|||||||
*/
|
*/
|
||||||
Map<String, Object> putPlusPullAction(String whereJson);
|
Map<String, Object> putPlusPullAction(String whereJson);
|
||||||
|
|
||||||
|
Map<String,Object> test();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -450,6 +450,15 @@ public class WmsToAcsServiceImpl implements WmsToAcsService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> test() {
|
||||||
|
System.out.println("进来了......");
|
||||||
|
Map<String,Object> map = new HashMap<>();
|
||||||
|
map.put("a","a");
|
||||||
|
map.put("b","b");
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CreateTaskResponse crateTask(List<CreateTaskRequest> reqs) {
|
public CreateTaskResponse crateTask(List<CreateTaskRequest> reqs) {
|
||||||
|
|||||||
@@ -965,11 +965,13 @@ public class TaskServiceImpl implements TaskService, ApplicationAutoInitial {
|
|||||||
entity.getStart_device_code(),
|
entity.getStart_device_code(),
|
||||||
entity.getNext_device_code(),
|
entity.getNext_device_code(),
|
||||||
entity.getRoute_plan_code());
|
entity.getRoute_plan_code());
|
||||||
String type = shortPathsList.get(0).getType();
|
if (ObjectUtil.isNotEmpty(shortPathsList)){
|
||||||
// != 0 为agv任务
|
String type = shortPathsList.get(0).getType();
|
||||||
if (!StrUtil.equals(type, "0")) {
|
// != 0 为agv任务
|
||||||
if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "3")) {
|
if (!StrUtil.equals(type, "0")) {
|
||||||
agvService.markComplete(entity.getTask_code());
|
if (StrUtil.equals(paramService.findByCode(AcsConfig.AGVTYPE).getValue(), "3")) {
|
||||||
|
agvService.markComplete(entity.getTask_code());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
package org.nl.modules.quartz.task;
|
package org.nl.modules.quartz.task;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.nl.acs.agv.server.AgvService;
|
import org.nl.acs.agv.server.AgvService;
|
||||||
import org.nl.acs.agv.server.dto.AgvDto;
|
|
||||||
import org.nl.acs.ext.wms.service.AcsToWmsService;
|
import org.nl.acs.ext.wms.service.AcsToWmsService;
|
||||||
import org.nl.modules.mnt.websocket.MsgType;
|
import org.nl.acs.monitor.DeviceStageMonitor;
|
||||||
import org.nl.modules.mnt.websocket.SocketMsg;
|
import org.nl.acs.opc.Device;
|
||||||
import org.nl.modules.mnt.websocket.WebSocketServer;
|
import org.nl.acs.opc.DeviceAppService;
|
||||||
|
import org.nl.acs.opc.DeviceType;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询AGV设备状态
|
* 查询AGV设备状态
|
||||||
@@ -25,52 +26,68 @@ public class ToAgvDevice {
|
|||||||
AcsToWmsService acsToWmsService;
|
AcsToWmsService acsToWmsService;
|
||||||
@Autowired
|
@Autowired
|
||||||
AgvService agvService;
|
AgvService agvService;
|
||||||
|
@Autowired
|
||||||
|
DeviceAppService deviceAppService;
|
||||||
|
|
||||||
public void run() throws Exception {
|
public void run() throws Exception {
|
||||||
JSONObject json = new JSONObject();
|
JSONArray list = new JSONArray();
|
||||||
Map<String, AgvDto> agv_map = agvService.findAllAgvFromCache();
|
List<Device> devices = deviceAppService.findDevice(DeviceType.agv);
|
||||||
|
if (ObjectUtil.isNotEmpty(devices)){
|
||||||
JSONArray agv_rows = new JSONArray();
|
for (int i = 0; i < devices.size(); i++) {
|
||||||
JSONObject row = new JSONObject();
|
Device device = devices.get(i);
|
||||||
|
if (device != null && device.getDeviceDriver() instanceof DeviceStageMonitor){
|
||||||
for (AgvDto agvDto : agv_map.values()) {
|
DeviceStageMonitor monitorService = (DeviceStageMonitor) device.getDeviceDriver();
|
||||||
row.put("device_code", agvDto.getName());
|
JSONObject deviceStatusName = monitorService.getDeviceStatusName();
|
||||||
row.put("energyLevel", agvDto.getEnergyLevel());
|
list.add(deviceStatusName);
|
||||||
if (agvDto.getState().equals("UNKNOWN")) {
|
}
|
||||||
row.put("status_name", "有任务");
|
|
||||||
row.put("flag", "1");
|
|
||||||
}
|
}
|
||||||
if (agvDto.getState().equals("UNAVAILABLE")) {
|
|
||||||
row.put("status_name", "网络异常");
|
|
||||||
row.put("flag", "1");
|
|
||||||
}
|
|
||||||
if (agvDto.getState().equals("ERROR")) {
|
|
||||||
row.put("status_name", "机器错误");
|
|
||||||
row.put("flag", "1");
|
|
||||||
}
|
|
||||||
if (agvDto.getState().equals("IDLE")) {
|
|
||||||
row.put("status_name", "空闲");
|
|
||||||
row.put("flag", "0");
|
|
||||||
}
|
|
||||||
if (agvDto.getState().equals("EXECUTING")) {
|
|
||||||
row.put("status_name", "运行中");
|
|
||||||
row.put("flag", "0");
|
|
||||||
}
|
|
||||||
if (agvDto.getState().equals("CHARGING")) {
|
|
||||||
row.put("status_name", "充电中");
|
|
||||||
row.put("flag", "0");
|
|
||||||
}
|
|
||||||
row.put("transportOrder", agvDto.getTransportOrder());
|
|
||||||
row.put("positionX", agvDto.getPositionX());
|
|
||||||
row.put("positionY", agvDto.getPositionY());
|
|
||||||
row.put("positionAngle", agvDto.getPositionAngle());
|
|
||||||
agv_rows.add(row);
|
|
||||||
}
|
}
|
||||||
json.put("agv_rows", agv_rows);
|
acsToWmsService.feedbackAgv(list);
|
||||||
SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO);
|
|
||||||
WebSocketServer.sendInfo(deviceInfo, "toAgvDevice_data");
|
|
||||||
|
// JSONObject json = new JSONObject();
|
||||||
|
// Map<String, AgvDto> agv_map = agvService.findAllAgvFromCache();
|
||||||
|
//
|
||||||
|
// JSONArray agv_rows = new JSONArray();
|
||||||
|
// JSONObject row = new JSONObject();
|
||||||
|
//
|
||||||
|
// for (AgvDto agvDto : agv_map.values()) {
|
||||||
|
// row.put("device_code", agvDto.getName());
|
||||||
|
// row.put("energyLevel", agvDto.getEnergyLevel());
|
||||||
|
// if (agvDto.getState().equals("UNKNOWN")) {
|
||||||
|
// row.put("status_name", "有任务");
|
||||||
|
// row.put("flag", "1");
|
||||||
|
// }
|
||||||
|
// if (agvDto.getState().equals("UNAVAILABLE")) {
|
||||||
|
// row.put("status_name", "网络异常");
|
||||||
|
// row.put("flag", "1");
|
||||||
|
// }
|
||||||
|
// if (agvDto.getState().equals("ERROR")) {
|
||||||
|
// row.put("status_name", "机器错误");
|
||||||
|
// row.put("flag", "1");
|
||||||
|
// }
|
||||||
|
// if (agvDto.getState().equals("IDLE")) {
|
||||||
|
// row.put("status_name", "空闲");
|
||||||
|
// row.put("flag", "0");
|
||||||
|
// }
|
||||||
|
// if (agvDto.getState().equals("EXECUTING")) {
|
||||||
|
// row.put("status_name", "运行中");
|
||||||
|
// row.put("flag", "0");
|
||||||
|
// }
|
||||||
|
// if (agvDto.getState().equals("CHARGING")) {
|
||||||
|
// row.put("status_name", "充电中");
|
||||||
|
// row.put("flag", "0");
|
||||||
|
// }
|
||||||
|
// row.put("transportOrder", agvDto.getTransportOrder());
|
||||||
|
// row.put("positionX", agvDto.getPositionX());
|
||||||
|
// row.put("positionY", agvDto.getPositionY());
|
||||||
|
// row.put("positionAngle", agvDto.getPositionAngle());
|
||||||
|
// agv_rows.add(row);
|
||||||
|
// }
|
||||||
|
// json.put("agv_rows", agv_rows);
|
||||||
|
// SocketMsg deviceInfo = new SocketMsg(json, MsgType.INFO);
|
||||||
|
// WebSocketServer.sendInfo(deviceInfo, "toAgvDevice_data");
|
||||||
|
|
||||||
// acsToWmsService.feedbackAgv(row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user