add: 物料超时提示数据记录
This commit is contained in:
@@ -2,6 +2,9 @@ package org.nl.wms.ext.acs.service;
|
||||
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import org.nl.wms.ext.acs.service.dto.to.BaseResponse;
|
||||
import org.nl.wms.ext.acs.service.dto.to.acs.ApplyTaskResponse;
|
||||
import org.nl.wms.ext.acs.service.dto.to.acs.GetPalletizeResponse;
|
||||
import org.nl.wms.ext.acs.service.dto.to.wms.ApplyTaskRequest;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
@@ -9,5 +12,48 @@ import org.nl.wms.ext.acs.service.dto.to.BaseResponse;
|
||||
* @Date: 2023/6/26
|
||||
*/
|
||||
public interface AcsToWmsService {
|
||||
/** ACS请求接口 */
|
||||
BaseResponse acsApply(JSONObject param);
|
||||
/** 任务:申请补满料盅托盘(叫料) */
|
||||
ApplyTaskResponse applyPutFullVehicle(JSONObject param);
|
||||
/** 任务:申请补空料盅托盘(叫空盘) */
|
||||
ApplyTaskResponse applyPutEmptyVehicle(JSONObject param);
|
||||
/** 任务:申请取走空料盅托盘(送空盘) */
|
||||
ApplyTaskResponse applyTakeEmptyVehicle(JSONObject param);
|
||||
/** 任务:申请取走满料盅托盘(入库) */
|
||||
ApplyTaskResponse applyTakeFullVehicle(JSONObject param);
|
||||
/** 任务:申请强制取走满料盅托盘(强制入库) */
|
||||
ApplyTaskResponse applyForceTakeFullVehicle(JSONObject param);
|
||||
/** 任务:分拣回收剩料 todo: 暂时 */
|
||||
ApplyTaskResponse applyForceTakeFullVehicleInStorage(JSONObject param);
|
||||
/** 强制去包装位(半托) 记录不包装 --- 业务不需要*/
|
||||
String forceNoPackage(JSONObject param);
|
||||
/** 质检记录 */
|
||||
BaseResponse qualityInspection(JSONObject param);
|
||||
/** 分拣 - 记录钢托与木托的绑定 */
|
||||
BaseResponse recordVehicleBiding(JSONObject param);
|
||||
/** 反馈压机残留重量*/
|
||||
BaseResponse applyFeedbackWeight(JSONObject param);
|
||||
/** 申请贴标 */
|
||||
BaseResponse applyLabelling(JSONObject param);
|
||||
/** 单次放置完成 - 每块砖的信息 */
|
||||
BaseResponse applyOneGrab(JSONObject param);
|
||||
/** 人工排产确认 */
|
||||
BaseResponse orderVerify(JSONObject param);
|
||||
/** 工单完成 */
|
||||
BaseResponse orderFinish(JSONObject param);
|
||||
/** 扫码成功申请*/
|
||||
ApplyTaskResponse barcodeSuccessApply(JSONObject param);
|
||||
/** 扫码成功申请 - 判断是否静置完成 */
|
||||
ApplyTaskResponse isStandingFinish(ApplyTaskRequest baseRequest);
|
||||
/** 扫码成功申请 - 入窑记录时间 */
|
||||
ApplyTaskResponse recordKilnTime(ApplyTaskRequest baseRequest);
|
||||
/** 压机叫料 */
|
||||
BaseResponse pressRequestMaterial(JSONObject param);
|
||||
/** 任务反馈 */
|
||||
BaseResponse feedbackTaskStatus(JSONObject param);
|
||||
/** 获取组盘信息 */
|
||||
GetPalletizeResponse getVehicleInfo(JSONObject param);
|
||||
/** 实时修改点位状态 */
|
||||
BaseResponse realTimeSetPoint(JSONObject param);
|
||||
}
|
||||
|
||||
@@ -140,6 +140,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
* @param param: ApplyTaskRequest的json形式
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ApplyTaskResponse applyPutFullVehicle(JSONObject param) {
|
||||
// 找到当前的设备
|
||||
@@ -172,6 +173,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
* @param param: ApplyTaskRequest的json形式
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ApplyTaskResponse applyPutEmptyVehicle(JSONObject param) {
|
||||
// 找到当前的设备
|
||||
@@ -204,6 +206,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
* @param param: ApplyTaskRequest的json形式
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ApplyTaskResponse applyTakeEmptyVehicle(JSONObject param) {
|
||||
// 找到当前的设备
|
||||
@@ -236,6 +239,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
* @param param: ApplyTaskRequest的json形式
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ApplyTaskResponse applyTakeFullVehicle(JSONObject param) {
|
||||
// 找到当前的设备
|
||||
@@ -268,6 +272,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
* @param param: ApplyTaskRequest的json形式
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public ApplyTaskResponse applyForceTakeFullVehicle(JSONObject param) {
|
||||
String deviceCode = param.getString("device_code");
|
||||
@@ -315,6 +320,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 强制去包装位(半托) 记录不包装 --- 业务不需要*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public String forceNoPackage(JSONObject param) {
|
||||
String requestNo = param.getString("requestNo");
|
||||
@@ -322,6 +328,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 质检记录 */
|
||||
@Override
|
||||
public BaseResponse qualityInspection(JSONObject param) {
|
||||
ApplyTaskRequest applyTaskRequest = param.toJavaObject(ApplyTaskRequest.class);
|
||||
// 记录质检信息
|
||||
@@ -330,6 +337,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 分拣 - 记录钢托与木托的绑定 */
|
||||
@Override
|
||||
public BaseResponse recordVehicleBiding(JSONObject param) {
|
||||
FeedBackSplitPalletStationRequest request = param.toJavaObject(FeedBackSplitPalletStationRequest.class);
|
||||
String getStation = request.getGet_station(); // 取货点
|
||||
@@ -362,6 +370,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 反馈压机残留重量*/
|
||||
@Override
|
||||
public BaseResponse applyFeedbackWeight(JSONObject param) {
|
||||
ApplyTaskRequest applyTaskRequest = param.toJavaObject(ApplyTaskRequest.class);
|
||||
materialResidueService.addByApplyTaskRequest(applyTaskRequest);
|
||||
@@ -369,6 +378,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 申请贴标 */
|
||||
@Override
|
||||
public BaseResponse applyLabelling(JSONObject param) {
|
||||
// 木托盘号##物料编码##数量##吨量(单重X数量)##生产日期## todo: 成型工单号(未添加)
|
||||
String requestNo = param.getString("requestNo");
|
||||
@@ -390,6 +400,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 单次放置完成 - 每块砖的信息 */
|
||||
@Override
|
||||
public BaseResponse applyOneGrab(JSONObject param) {
|
||||
String requestNo = param.getString("requestNo");
|
||||
JSONObject brickInfo = param.getJSONObject("brick_info");
|
||||
@@ -399,6 +410,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 人工排产确认 */
|
||||
@Override
|
||||
public BaseResponse orderVerify(JSONObject param) { // 执行中
|
||||
String requestNo = param.getString("requestNo");
|
||||
String workorderCode = param.getString("order_code");
|
||||
@@ -417,6 +429,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 工单完成 */
|
||||
@Override
|
||||
public BaseResponse orderFinish(JSONObject param) { // 完成
|
||||
String requestNo = param.getString("requestNo");
|
||||
String workorderCode = param.getString("order_code");
|
||||
@@ -435,6 +448,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 扫码成功申请 - 判断是否静置完成 */
|
||||
@Override
|
||||
public ApplyTaskResponse barcodeSuccessApply(JSONObject param) {
|
||||
ApplyTaskRequest baseRequest = param.toJavaObject(ApplyTaskRequest.class);
|
||||
ApplyTaskResponse taskResponse = ApplyTaskResponse.responseOk(baseRequest.getRequestNo());
|
||||
@@ -454,6 +468,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 扫码成功申请 - 判断是否静置完成 */
|
||||
@Override
|
||||
public ApplyTaskResponse isStandingFinish(ApplyTaskRequest baseRequest) {
|
||||
String requestNo = baseRequest.getRequestNo();
|
||||
ApplyTaskResponse taskResponse = ApplyTaskResponse.responseOk(requestNo);
|
||||
@@ -514,6 +529,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 扫码成功申请 - 入窑记录时间 */
|
||||
@Override
|
||||
public ApplyTaskResponse recordKilnTime(ApplyTaskRequest baseRequest) {
|
||||
if (ObjectUtil.isEmpty(baseRequest.getVehicle_code())) {
|
||||
throw new BadRequestException("载具编码不能为空");
|
||||
@@ -544,6 +560,21 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
return ApplyTaskResponse.responseOk(baseRequest.getRequestNo());
|
||||
}
|
||||
|
||||
/**
|
||||
* 压机请求要料
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public BaseResponse pressRequestMaterial(JSONObject param) {
|
||||
// todo: 换成acs请求
|
||||
String requestNo = param.getString("requestNo");
|
||||
// todo: 1、校验是否有工单,是否需要叫料
|
||||
// todo: 2、通知混碾机生产泥料
|
||||
// todo: 3、修改设备点位为空位,并且更新时间
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 提前要料
|
||||
* @param param
|
||||
@@ -551,8 +582,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
*/
|
||||
@Deprecated
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public BaseResponse pressRequestMaterial(JSONObject param) { // (公共接口进来)只是给我一个下料位(中间位置)
|
||||
// todo: 换成acs请求,修改设备点位为空位,并且更新时间
|
||||
public BaseResponse pressRequestMaterial2(JSONObject param) { // (公共接口进来)只是给我一个下料位(中间位置)
|
||||
String requestNo = param.getString("requestNo");
|
||||
// 压机、原材料物料(混碾)、压机工单、叫料时间
|
||||
String deviceCode = param.getString("device_code");// 几号压机下料位
|
||||
@@ -581,6 +611,8 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
return BaseResponse.responseOk(requestNo);
|
||||
}
|
||||
|
||||
/** 任务反馈 */
|
||||
@Override
|
||||
public BaseResponse feedbackTaskStatus(JSONObject param) {
|
||||
// todo: action暂未维护
|
||||
String requestNo = param.getString("requestNo");
|
||||
@@ -624,6 +656,8 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
return BaseResponse.responseOk(requestNo, "任务状态反馈成功!");
|
||||
}
|
||||
|
||||
/** 获取组盘信息 */
|
||||
@Override
|
||||
public GetPalletizeResponse getVehicleInfo(JSONObject param) {
|
||||
// 校验组盘信息
|
||||
GetPalletizeRequest palletizeRequest = param.toJavaObject(GetPalletizeRequest.class);
|
||||
@@ -645,6 +679,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
|
||||
}
|
||||
|
||||
/** 实时修改点位状态 */
|
||||
@Override
|
||||
public BaseResponse realTimeSetPoint(JSONObject param) {
|
||||
// todo: 实体错误
|
||||
PutActionRequest actionRequest = param.toJavaObject(PutActionRequest.class);
|
||||
|
||||
@@ -66,4 +66,11 @@ public class ReportController {
|
||||
public ResponseEntity<Object> inKilnReport(Map json, PageQuery page){
|
||||
return new ResponseEntity<>(TableDataInfo.build(reportService.inKilnReport(json,page)), HttpStatus.OK);
|
||||
}
|
||||
|
||||
@GetMapping("/inventoryMaterialTimeoutWarning")
|
||||
@Log("库存物料超时提示")
|
||||
@ApiOperation("库存物料超时提示")
|
||||
public ResponseEntity<Object> inventoryMaterialTimeoutWarning(Map json, PageQuery page){
|
||||
return new ResponseEntity<>(TableDataInfo.build(reportService.inventoryMaterialTimeoutWarning(json,page)), HttpStatus.OK);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.nl.wms.report.service;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.report.service.dao.vo.IOKilnReportVo;
|
||||
import org.nl.wms.report.service.dao.vo.MaterialTimeoutVo;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@@ -18,5 +19,7 @@ public interface ReportService {
|
||||
|
||||
IPage<IOKilnReportVo> inKilnReport(Map json, PageQuery page);
|
||||
|
||||
IPage<MaterialTimeoutVo> inventoryMaterialTimeoutWarning(Map json, PageQuery page);
|
||||
|
||||
// IPage<> mudTransfer(JSONObject json, PageQuery page);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.nl.wms.report.service.dao.mapper;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.nl.wms.report.service.dao.vo.IOKilnReportVo;
|
||||
import org.nl.wms.report.service.dao.vo.MaterialTimeoutVo;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
@@ -15,4 +16,6 @@ public interface ReportMapper {
|
||||
IPage<IOKilnReportVo> outKilnReportByPage(IPage<IOKilnReportVo> pages, JSONObject object);
|
||||
|
||||
IPage<IOKilnReportVo> inKilnReport(IPage<IOKilnReportVo> pages, JSONObject object);
|
||||
|
||||
IPage<MaterialTimeoutVo> inventoryMaterialTimeoutWarning(IPage<MaterialTimeoutVo> pages, JSONObject object);
|
||||
}
|
||||
|
||||
@@ -42,4 +42,23 @@
|
||||
LEFT JOIN md_base_material m ON m.material_id = vg.material_id
|
||||
WHERE vg.into_kiln_time IS NOT NULL AND vg.out_kiln_time IS NULL
|
||||
</select>
|
||||
<select id="inventoryMaterialTimeoutWarning"
|
||||
resultType="org.nl.wms.report.service.dao.vo.MaterialTimeoutVo">
|
||||
SELECT
|
||||
p.point_code,
|
||||
p.point_name,
|
||||
p.region_name,
|
||||
ma.material_code,
|
||||
ma.material_name,
|
||||
vg.instorage_time
|
||||
FROM
|
||||
`sch_base_point` p
|
||||
LEFT JOIN sch_base_vehiclematerialgroup vg ON vg.vehicle_code = p.vehicle_code
|
||||
AND vg.vehicle_type = p.vehicle_type AND vg.group_bind_material_status = '2'
|
||||
LEFT JOIN md_base_material ma ON ma.material_id = vg.material_id
|
||||
WHERE p.region_code = 'GTPHC'
|
||||
AND p.point_type = '2'
|
||||
AND p.point_status = '3'
|
||||
AND vg.instorage_time <![CDATA[<=]]> DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||
</select>
|
||||
</mapper>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.nl.wms.report.service.dao.vo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @Author: lyd
|
||||
* @Description: 入库物料过久没动提示VO
|
||||
* @Date: 2023/8/9
|
||||
*/
|
||||
@Data
|
||||
public class MaterialTimeoutVo {
|
||||
private String point_code;
|
||||
private String point_name;
|
||||
private String region_name;
|
||||
private String material_code;
|
||||
private String material_name;
|
||||
private String instorage_time;
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import org.nl.common.domain.query.PageQuery;
|
||||
import org.nl.wms.report.service.ReportService;
|
||||
import org.nl.wms.report.service.dao.mapper.ReportMapper;
|
||||
import org.nl.wms.report.service.dao.vo.IOKilnReportVo;
|
||||
import org.nl.wms.report.service.dao.vo.MaterialTimeoutVo;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -43,4 +44,11 @@ public class ReportServiceImpl implements ReportService {
|
||||
pages = reportMapper.inKilnReport(pages, new JSONObject(query));
|
||||
return pages;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<MaterialTimeoutVo> inventoryMaterialTimeoutWarning(Map query, PageQuery page) {
|
||||
IPage<MaterialTimeoutVo> pages = new Page<>(page.getPage() + 1, page.getSize());
|
||||
pages = reportMapper.inventoryMaterialTimeoutWarning(pages, new JSONObject(query));
|
||||
return pages;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ import java.util.List;
|
||||
* @author ldjun
|
||||
* @version 1.0
|
||||
* @date 2023年05月16日 16:42
|
||||
* @desc desc
|
||||
* @desc 任务抽象父类,申请任务的相关率先判断以及生成,接着到子类执行任务的创建,最后统一通过定时任务去下发到ACS
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@@ -221,7 +221,8 @@ public abstract class AbstractTask {
|
||||
String apply_point_code = param.getString("device_code"); // 请求点
|
||||
String config_code = param.getString("config_code");
|
||||
String requestNo = param.getString("requestNo");
|
||||
String vehicleType = param.getString("vehicle_type");
|
||||
String vehicleType = TaskUtils.acsVehicleTypeShift(param.getString("vehicle_type"));
|
||||
String vehicleCode = TaskUtils.defaultVehicleCode(param.getString("vehicle_code"));
|
||||
// 1、校验数据
|
||||
SchBaseTaskconfig taskConfig = taskConfigService.getOne(new LambdaQueryWrapper<SchBaseTaskconfig>()
|
||||
.eq(SchBaseTaskconfig::getConfig_code, config_code));
|
||||
@@ -265,7 +266,7 @@ public abstract class AbstractTask {
|
||||
task.setTask_code(IdUtil.getSnowflake(1, 1).nextIdStr());
|
||||
task.setConfig_code(config_code);
|
||||
task.setCreate_mode(GeneralDefinition.ACS_CREATION);
|
||||
task.setVehicle_code(param.getString("vehicle_code"));
|
||||
task.setVehicle_code(vehicleCode);
|
||||
task.setVehicle_qty(param.getInteger("vehicle_qty"));
|
||||
task.setVehicle_type(vehicleType);
|
||||
task.setTask_status(TaskStatus.APPLY.getCode());
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.nl.wms.util;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.nl.common.utils.SecurityUtils;
|
||||
import org.nl.config.SpringContextHolder;
|
||||
import org.nl.wms.pdm.workorder.service.dao.PdmBdWorkorder;
|
||||
@@ -24,6 +25,7 @@ import java.util.function.Consumer;
|
||||
* @Description: 任务修改抽取的公用方法
|
||||
* @Date: 2023/6/13
|
||||
*/
|
||||
@Slf4j
|
||||
public class TaskUtils {
|
||||
|
||||
public static void setCreateByAcs(SchBaseTask taskObj) {
|
||||
@@ -125,4 +127,54 @@ public class TaskUtils {
|
||||
.eq(SchBaseTask::getPoint_code4, code)));
|
||||
return list.size() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACS载具类型:1 2 3 ...
|
||||
* LMS载具类型:3 4 5 ...
|
||||
* @param acsVehicleType
|
||||
* @return
|
||||
*/
|
||||
public static String acsVehicleTypeShift(String acsVehicleType) {
|
||||
if (ObjectUtil.isEmpty(acsVehicleType)) {
|
||||
return null;
|
||||
}
|
||||
String lmsVehicleType = null;
|
||||
try {
|
||||
lmsVehicleType = Integer.parseInt(acsVehicleType) - 2 + "";
|
||||
} catch (Exception e) {
|
||||
log.error("acs载具转换异常: {}", e.getMessage());
|
||||
}
|
||||
return lmsVehicleType;
|
||||
}
|
||||
|
||||
/**
|
||||
* ACS载具类型:1 2 3 ...
|
||||
* LMS载具类型:3 4 5 ...
|
||||
* @param lmsVehicleType
|
||||
* @return
|
||||
*/
|
||||
public static String lmsVehicleTypeShift(String lmsVehicleType) {
|
||||
if (ObjectUtil.isEmpty(lmsVehicleType)) {
|
||||
return null;
|
||||
}
|
||||
String acsVehicleType = null;
|
||||
try {
|
||||
acsVehicleType = Integer.parseInt(lmsVehicleType) + 2 + "";
|
||||
} catch (Exception e) {
|
||||
log.error("acs载具转换异常: {}", e.getMessage());
|
||||
}
|
||||
return acsVehicleType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果传来的载具编码是0,就返回null
|
||||
* @param acsVehicleCode
|
||||
* @return
|
||||
*/
|
||||
public static String defaultVehicleCode(String acsVehicleCode) {
|
||||
if (ObjectUtil.isEmpty(acsVehicleCode) || acsVehicleCode.equals(GeneralDefinition.NO)) {
|
||||
return null;
|
||||
}
|
||||
return acsVehicleCode;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user