微调
This commit is contained in:
@@ -857,7 +857,9 @@ public class DetectionServiceImpl {
|
|||||||
DetectionData data = new DetectionData();
|
DetectionData data = new DetectionData();
|
||||||
data.setIsData(4);
|
data.setIsData(4);
|
||||||
data.setNum(harm);
|
data.setNum(harm);
|
||||||
|
if (CollUtil.isNotEmpty(harmDataList)) {
|
||||||
data.setData(harmDataList.get(0));
|
data.setData(harmDataList.get(0));
|
||||||
|
}
|
||||||
Double v = issueHarmMap.get(harm);
|
Double v = issueHarmMap.get(harm);
|
||||||
data.setResultData(v);
|
data.setResultData(v);
|
||||||
if (ObjectUtil.isNotNull(errSysDtl)) {
|
if (ObjectUtil.isNotNull(errSysDtl)) {
|
||||||
@@ -886,6 +888,7 @@ public class DetectionServiceImpl {
|
|||||||
* @Date: 2024/12/29 18:10
|
* @Date: 2024/12/29 18:10
|
||||||
*/
|
*/
|
||||||
private void setDetection(DictDataEnum dataRule, List<Double> harmDataList, PqErrSysDtls errSysDtl, DetectionData data, Double v) {
|
private void setDetection(DictDataEnum dataRule, List<Double> harmDataList, PqErrSysDtls errSysDtl, DetectionData data, Double v) {
|
||||||
|
if (CollUtil.isNotEmpty(harmDataList)) {
|
||||||
List<Double> qualifiedList = harmDataList.stream()
|
List<Double> qualifiedList = harmDataList.stream()
|
||||||
.filter(x -> v == 0 ? NumberUtil.isIn(devSubtractChannelData(x, v, errSysDtl.getErrorValueType()),
|
.filter(x -> v == 0 ? NumberUtil.isIn(devSubtractChannelData(x, v, errSysDtl.getErrorValueType()),
|
||||||
BigDecimal.valueOf(-errSysDtl.getMaxErrorValue()),
|
BigDecimal.valueOf(-errSysDtl.getMaxErrorValue()),
|
||||||
@@ -901,6 +904,7 @@ public class DetectionServiceImpl {
|
|||||||
}
|
}
|
||||||
isData(dataRule, harmDataList, data, qualifiedList);
|
isData(dataRule, harmDataList, data, qualifiedList);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void isData(DictDataEnum dataRule, List<Double> harmDataList, DetectionData data, List<Double> qualifiedList) {
|
private void isData(DictDataEnum dataRule, List<Double> harmDataList, DetectionData data, List<Double> qualifiedList) {
|
||||||
if (CollUtil.isNotEmpty(qualifiedList)) {
|
if (CollUtil.isNotEmpty(qualifiedList)) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ public class PqScriptParam {
|
|||||||
|
|
||||||
@ApiModelProperty("参照标准名称")
|
@ApiModelProperty("参照标准名称")
|
||||||
@NotBlank(message = DevValidMessage.STANDARD_NAME_NOT_BLANK)
|
@NotBlank(message = DevValidMessage.STANDARD_NAME_NOT_BLANK)
|
||||||
@Pattern(regexp = PatternRegex.ERR_SYS_NAME, message = DevValidMessage.STANDARD_NAME_FORMAT_ERROR)
|
//@Pattern(regexp = PatternRegex.ERR_SYS_NAME, message = DevValidMessage.STANDARD_NAME_FORMAT_ERROR)
|
||||||
private String standardName;
|
private String standardName;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ public class PqScriptServiceImpl extends ServiceImpl<PqScriptMapper, PqScript> i
|
|||||||
public boolean updatePqScript(PqScriptParam.UpdateParam param) {
|
public boolean updatePqScript(PqScriptParam.UpdateParam param) {
|
||||||
PqScript pqScript = new PqScript();
|
PqScript pqScript = new PqScript();
|
||||||
BeanUtils.copyProperties(param, pqScript);
|
BeanUtils.copyProperties(param, pqScript);
|
||||||
|
pqScript.setStandardTime(LocalDate.of(Integer.parseInt(param.getStandardTime()), 1, 1));
|
||||||
pqScript.setState(DataStateEnum.ENABLE.getCode());
|
pqScript.setState(DataStateEnum.ENABLE.getCode());
|
||||||
return this.updateById(pqScript);
|
return this.updateById(pqScript);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,20 +42,20 @@ public class SysTestConfigController extends BaseController {
|
|||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, sysTestConfig, methodDescribe);
|
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, sysTestConfig, methodDescribe);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
// @OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.ADD)
|
||||||
@PostMapping("/add")
|
// @PostMapping("/add")
|
||||||
@ApiOperation("新增检测相关配置信息")
|
// @ApiOperation("新增检测相关配置信息")
|
||||||
@ApiImplicitParam(name = "sysTestConfig", value = "检测相关配置信息", required = true)
|
// @ApiImplicitParam(name = "sysTestConfig", value = "检测相关配置信息", required = true)
|
||||||
public HttpResult<Boolean> add(@RequestBody @Validated SysTestConfigParam param) {
|
// public HttpResult<Boolean> add(@RequestBody @Validated SysTestConfigParam param) {
|
||||||
String methodDescribe = getMethodDescribe("add");
|
// String methodDescribe = getMethodDescribe("add");
|
||||||
LogUtil.njcnDebug(log, "{}", methodDescribe);
|
// LogUtil.njcnDebug(log, "{}", methodDescribe);
|
||||||
boolean result = sysTestConfigService.addTestConfig(param);
|
// boolean result = sysTestConfigService.addTestConfig(param);
|
||||||
if (result) {
|
// if (result) {
|
||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||||
} else {
|
// } else {
|
||||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
|
// return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.FAIL, null, methodDescribe);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.UPDATE)
|
||||||
@PostMapping("/update")
|
@PostMapping("/update")
|
||||||
|
|||||||
@@ -18,10 +18,10 @@ public interface ISysTestConfigService extends IService<SysTestConfig> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加检测配置
|
* 添加检测配置
|
||||||
* @param param 检测配置
|
* @param scene 场景
|
||||||
* @return 是否添加成功
|
* @return 是否添加成功
|
||||||
*/
|
*/
|
||||||
boolean addTestConfig(SysTestConfigParam param);
|
boolean addTestConfig(String scene);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新检测配置
|
* 更新检测配置
|
||||||
|
|||||||
@@ -35,9 +35,12 @@ public class SysTestConfigServiceImpl extends ServiceImpl<SysTestConfigMapper, S
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = {Exception.class})
|
@Transactional(rollbackFor = {Exception.class})
|
||||||
public boolean addTestConfig(SysTestConfigParam param) {
|
public boolean addTestConfig(String scene) {
|
||||||
SysTestConfig sysTestConfig = new SysTestConfig();
|
SysTestConfig sysTestConfig = new SysTestConfig();
|
||||||
BeanUtils.copyProperties(param, sysTestConfig);
|
sysTestConfig.setAutoGenerate(1);
|
||||||
|
sysTestConfig.setMaxTime(3);
|
||||||
|
sysTestConfig.setDataRule("46cf964bd76fb12a19cfb1700442eeeb"); // 任意值
|
||||||
|
sysTestConfig.setScene(scene);
|
||||||
sysTestConfig.setState(DataStateEnum.ENABLE.getCode());
|
sysTestConfig.setState(DataStateEnum.ENABLE.getCode());
|
||||||
return this.save(sysTestConfig);
|
return this.save(sysTestConfig);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ public class DictDataParam {
|
|||||||
|
|
||||||
@ApiModelProperty("名称")
|
@ApiModelProperty("名称")
|
||||||
@NotBlank(message = SystemValidMessage.NAME_NOT_BLANK)
|
@NotBlank(message = SystemValidMessage.NAME_NOT_BLANK)
|
||||||
@Pattern(regexp = PatternRegex.DICT_NAME_REGEX, message = SystemValidMessage.NAME_FORMAT_ERROR)
|
// @Pattern(regexp = PatternRegex.DICT_NAME_REGEX, message = SystemValidMessage.NAME_FORMAT_ERROR)
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
|
|
||||||
@ApiModelProperty("编码")
|
@ApiModelProperty("编码")
|
||||||
@NotBlank(message = SystemValidMessage.CODE_NOT_BLANK)
|
@NotBlank(message = SystemValidMessage.CODE_NOT_BLANK)
|
||||||
@Pattern(regexp = PatternRegex.DICT_CODE_REGEX, message = SystemValidMessage.CODE_FORMAT_ERROR)
|
// @Pattern(regexp = PatternRegex.DICT_CODE_REGEX, message = SystemValidMessage.CODE_FORMAT_ERROR)
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -48,13 +48,23 @@ public class SysLogController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||||
@PostMapping("/export")
|
@PostMapping("/exportCSV")
|
||||||
@ApiOperation("日志导出为csv文件")
|
@ApiOperation("日志导出为csv文件")
|
||||||
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
||||||
public void export(@RequestBody @Validated SysLogParam.QueryParam param) {
|
public void exportCSV(@RequestBody @Validated SysLogParam.QueryParam param) {
|
||||||
String methodDescribe = getMethodDescribe("export");
|
String methodDescribe = getMethodDescribe("export");
|
||||||
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
||||||
sysLogAuditService.exportSysLogAuditData(param);
|
sysLogAuditService.exportCSV(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
@OperateInfo(info = LogEnum.SYSTEM_COMMON, operateType = OperateType.DOWNLOAD)
|
||||||
|
@PostMapping("/analyse")
|
||||||
|
@ApiOperation("日志分析")
|
||||||
|
@ApiImplicitParam(name = "param", value = "查询参数", required = true)
|
||||||
|
public void analyse(@RequestBody @Validated SysLogParam.QueryParam param) {
|
||||||
|
String methodDescribe = getMethodDescribe("analyze");
|
||||||
|
LogUtil.njcnDebug(log, "{},查询数据为:{}", methodDescribe, param);
|
||||||
|
sysLogAuditService.analyse(param);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ public interface ISysLogAuditService extends IService<SysLogAudit> {
|
|||||||
*
|
*
|
||||||
* @param param 查询参数
|
* @param param 查询参数
|
||||||
*/
|
*/
|
||||||
void exportSysLogAuditData(SysLogParam.QueryParam param);
|
void exportCSV(SysLogParam.QueryParam param);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 添加审计日志
|
* 添加审计日志
|
||||||
@@ -56,4 +56,11 @@ public interface ISysLogAuditService extends IService<SysLogAudit> {
|
|||||||
* 按照 一定规则 清除日志
|
* 按照 一定规则 清除日志
|
||||||
*/
|
*/
|
||||||
void scheduleRemoveLog();
|
void scheduleRemoveLog();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 分析日志
|
||||||
|
*
|
||||||
|
* @param param
|
||||||
|
*/
|
||||||
|
void analyse(SysLogParam.QueryParam param);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.njcn.gather.system.log.service.impl;
|
package com.njcn.gather.system.log.service.impl;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
@@ -14,12 +15,18 @@ import com.njcn.gather.system.log.service.ISysLogAuditService;
|
|||||||
import com.njcn.gather.system.log.util.CSVUtil;
|
import com.njcn.gather.system.log.util.CSVUtil;
|
||||||
import com.njcn.gather.user.user.service.ISysUserService;
|
import com.njcn.gather.user.user.service.ISysUserService;
|
||||||
import com.njcn.web.factory.PageFactory;
|
import com.njcn.web.factory.PageFactory;
|
||||||
|
import com.njcn.web.utils.HttpServletUtil;
|
||||||
import com.njcn.web.utils.RequestUtil;
|
import com.njcn.web.utils.RequestUtil;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
@@ -38,8 +45,6 @@ import java.util.stream.Collectors;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SysLogAuditServiceImpl extends ServiceImpl<SysLogAuditMapper, SysLogAudit> implements ISysLogAuditService {
|
public class SysLogAuditServiceImpl extends ServiceImpl<SysLogAuditMapper, SysLogAudit> implements ISysLogAuditService {
|
||||||
|
|
||||||
private final ISysUserService sysUserService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<SysLogAudit> listSysLogAudit(SysLogParam.QueryParam param) {
|
public Page<SysLogAudit> listSysLogAudit(SysLogParam.QueryParam param) {
|
||||||
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||||
@@ -53,7 +58,7 @@ public class SysLogAuditServiceImpl extends ServiceImpl<SysLogAuditMapper, SysLo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exportSysLogAuditData(SysLogParam.QueryParam param) {
|
public void exportCSV(SysLogParam.QueryParam param) {
|
||||||
String[] titles = {"日志类型", "IP", "事件结果", "描述", "日志等级", "告警标准", "操作用户", "记录时间"};
|
String[] titles = {"日志类型", "IP", "事件结果", "描述", "日志等级", "告警标准", "操作用户", "记录时间"};
|
||||||
String[] keys = {"operateType", "ip", "result", "remark", "level", "warn", "createBy", "createTime"};
|
String[] keys = {"operateType", "ip", "result", "remark", "level", "warn", "createBy", "createTime"};
|
||||||
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||||
@@ -127,4 +132,37 @@ public class SysLogAuditServiceImpl extends ServiceImpl<SysLogAuditMapper, SysLo
|
|||||||
}
|
}
|
||||||
this.remove(wrapper);
|
this.remove(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyse(SysLogParam.QueryParam param) {
|
||||||
|
QueryWrapper<SysLogAudit> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (ObjectUtil.isNotNull(param)) {
|
||||||
|
queryWrapper.like(StrUtil.isNotBlank(param.getOperateType()), "sys_log_audit.Operate_Type", param.getOperateType())
|
||||||
|
.like(StrUtil.isNotBlank(param.getCreateBy()), "sys_log_audit.Create_By", param.getCreateBy())
|
||||||
|
.between(StrUtil.isAllNotBlank(param.getSearchBeginTime(), param.getSearchEndTime()), "sys_log_audit.Create_Time", param.getSearchBeginTime(), param.getSearchEndTime());
|
||||||
|
}
|
||||||
|
List<SysLogAudit> list = this.list(queryWrapper);
|
||||||
|
Map<String, List<SysLogAudit>> collect = list.stream().collect(Collectors.groupingBy(SysLogAudit::getCreateBy, Collectors.toList()));
|
||||||
|
|
||||||
|
this.exportAnalyseExcel("分析结果", collect);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void exportAnalyseExcel(String fileName, Map<String, List<SysLogAudit>> collect) {
|
||||||
|
HttpServletResponse response = HttpServletUtil.getResponse();
|
||||||
|
XSSFWorkbook wb = new XSSFWorkbook();
|
||||||
|
|
||||||
|
try (ServletOutputStream outputStream = response.getOutputStream()) {
|
||||||
|
fileName = URLEncoder.encode(fileName, CharsetUtil.UTF_8);
|
||||||
|
response.reset();
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
|
||||||
|
response.setContentType("application/octet-stream;charset=UTF-8");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wb.write(outputStream);
|
||||||
|
wb.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error(">>> 导出数据异常:{}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||||
import com.njcn.common.pojo.exception.BusinessException;
|
import com.njcn.common.pojo.exception.BusinessException;
|
||||||
import com.njcn.common.utils.EncryptionUtil;
|
import com.njcn.common.utils.EncryptionUtil;
|
||||||
|
import com.njcn.gather.system.config.service.ISysTestConfigService;
|
||||||
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
|
import com.njcn.gather.system.dictionary.pojo.enums.DictDataEnum;
|
||||||
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
import com.njcn.gather.system.dictionary.pojo.po.DictData;
|
||||||
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
import com.njcn.gather.system.dictionary.service.IDictDataService;
|
||||||
@@ -49,6 +50,9 @@ import java.util.List;
|
|||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes> implements ISysRegResService {
|
public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes> implements ISysRegResService {
|
||||||
|
|
||||||
|
private final ISysTestConfigService sysTestConfigService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 固定私钥
|
* 固定私钥
|
||||||
*/
|
*/
|
||||||
@@ -111,6 +115,8 @@ public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes
|
|||||||
throw new BusinessException(RegResponseEnum.REGISTRATION_CODE_EXPIRED);
|
throw new BusinessException(RegResponseEnum.REGISTRATION_CODE_EXPIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sysTestConfigService.addTestConfig(regInfoData.getScene());
|
||||||
|
|
||||||
for (int i = 0; i < regInfoData.getTypeList().size(); i++) {
|
for (int i = 0; i < regInfoData.getTypeList().size(); i++) {
|
||||||
// 忽略过期的
|
// 忽略过期的
|
||||||
// if (isExpire(expireDateList.get(i))) {
|
// if (isExpire(expireDateList.get(i))) {
|
||||||
@@ -304,7 +310,7 @@ public class SysRegResServiceImpl extends ServiceImpl<SysRegResMapper, SysRegRes
|
|||||||
|
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
RegInfoData regInfoData = objectMapper.readValue(decodedString, RegInfoData.class);
|
RegInfoData regInfoData = objectMapper.readValue(decodedString, RegInfoData.class);
|
||||||
if (ObjectUtil.isNull(regInfoData) || regInfoData.getTypeList().size() == 0 || regInfoData.getTypeList().size() != regInfoData.getExpireDateList().size()) {
|
if (ObjectUtil.isNull(regInfoData) || ObjectUtil.isNull(regInfoData.getScene()) || regInfoData.getTypeList().size() == 0 || regInfoData.getTypeList().size() != regInfoData.getExpireDateList().size()) {
|
||||||
throw new BusinessException(RegResponseEnum.REGISTRATION_CODE_FORMAT_ERROR);
|
throw new BusinessException(RegResponseEnum.REGISTRATION_CODE_FORMAT_ERROR);
|
||||||
}
|
}
|
||||||
return regInfoData;
|
return regInfoData;
|
||||||
|
|||||||
Reference in New Issue
Block a user