fix(prison): 修复评估报告日期和映射构建问题
This commit is contained in:
parent
9ceed8408a
commit
0825da5f7f
2
.gitignore
vendored
2
.gitignore
vendored
@ -55,3 +55,5 @@ application-my.yaml
|
|||||||
|
|
||||||
# Generated codegen files
|
# Generated codegen files
|
||||||
/codegen/
|
/codegen/
|
||||||
|
|
||||||
|
.omc/
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 评估报告分页 Request VO")
|
@Schema(description = "管理后台 - 评估报告分页 Request VO")
|
||||||
@ -45,8 +47,8 @@ public class EvaluationReportPageReqVO extends PageParam {
|
|||||||
private Long areaId;
|
private Long areaId;
|
||||||
|
|
||||||
@Schema(description = "评估日期")
|
@Schema(description = "评估日期")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
|
||||||
private LocalDateTime[] evaluationDate;
|
private LocalDate[] evaluationDate;
|
||||||
|
|
||||||
@Schema(description = "创建时间")
|
@Schema(description = "创建时间")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import lombok.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import cn.idev.excel.annotation.*;
|
import cn.idev.excel.annotation.*;
|
||||||
|
|
||||||
@ -52,8 +53,8 @@ public class EvaluationReportRespVO {
|
|||||||
|
|
||||||
@Schema(description = "评估日期")
|
@Schema(description = "评估日期")
|
||||||
@ExcelProperty("评估日期")
|
@ExcelProperty("评估日期")
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||||
private LocalDateTime evaluationDate;
|
private LocalDate evaluationDate;
|
||||||
|
|
||||||
@Schema(description = "评估人员ID")
|
@Schema(description = "评估人员ID")
|
||||||
private Long evaluatorId;
|
private Long evaluatorId;
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import lombok.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import jakarta.validation.constraints.*;
|
import jakarta.validation.constraints.*;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDate;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 评估报告新增/修改 Request VO")
|
@Schema(description = "管理后台 - 评估报告新增/修改 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@ -41,7 +41,7 @@ public class EvaluationReportSaveReqVO {
|
|||||||
|
|
||||||
@Schema(description = "评估日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
@Schema(description = "评估日期", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
@NotNull(message = "评估日期不能为空")
|
@NotNull(message = "评估日期不能为空")
|
||||||
private LocalDateTime evaluationDate;
|
private LocalDate evaluationDate;
|
||||||
|
|
||||||
@Schema(description = "评估人员ID")
|
@Schema(description = "评估人员ID")
|
||||||
private Long evaluatorId;
|
private Long evaluatorId;
|
||||||
|
|||||||
@ -104,10 +104,12 @@ public class PrisonQuestionnaireRecordController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 收集所有 taskId
|
// 收集所有 taskId
|
||||||
Set<Long> taskIds = records.stream()
|
Set<Long> taskIds = new HashSet<>();
|
||||||
.map(QuestionnaireRecordRespVO::getTaskId)
|
for (QuestionnaireRecordRespVO record : records) {
|
||||||
.filter(Objects::nonNull)
|
if (record != null && record.getTaskId() != null) {
|
||||||
.collect(Collectors.toSet());
|
taskIds.add(record.getTaskId());
|
||||||
|
}
|
||||||
|
}
|
||||||
if (cn.hutool.core.collection.CollUtil.isEmpty(taskIds)) {
|
if (cn.hutool.core.collection.CollUtil.isEmpty(taskIds)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -115,12 +117,14 @@ public class PrisonQuestionnaireRecordController {
|
|||||||
List<cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO> tasks = questionnaireTaskMapper.selectList(
|
List<cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO> tasks = questionnaireTaskMapper.selectList(
|
||||||
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO>()
|
new com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper<cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO>()
|
||||||
.in(cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO::getId, taskIds));
|
.in(cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO::getId, taskIds));
|
||||||
// 构建 taskId -> remark 映射
|
// 构建 taskId -> remark 映射,避免 Collectors.toMap 在脏数据场景下抛出 NPE
|
||||||
Map<Long, String> taskRemarkMap = tasks.stream()
|
Map<Long, String> taskRemarkMap = new HashMap<>();
|
||||||
.collect(Collectors.toMap(
|
for (cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO task : tasks) {
|
||||||
cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO::getId,
|
if (task == null || task.getId() == null) {
|
||||||
cn.iocoder.yudao.module.prison.dal.dataobject.questionnaire_task.QuestionnaireTaskDO::getRemark,
|
continue;
|
||||||
(v1, v2) -> v1));
|
}
|
||||||
|
taskRemarkMap.putIfAbsent(task.getId(), task.getRemark() == null ? "" : task.getRemark());
|
||||||
|
}
|
||||||
// 填充备注到 VO
|
// 填充备注到 VO
|
||||||
for (QuestionnaireRecordRespVO record : records) {
|
for (QuestionnaireRecordRespVO record : records) {
|
||||||
String remark = taskRemarkMap.get(record.getTaskId());
|
String remark = taskRemarkMap.get(record.getTaskId());
|
||||||
|
|||||||
@ -29,6 +29,10 @@ public class QuestionnaireRecordRespVO {
|
|||||||
@ExcelProperty("问卷ID")
|
@ExcelProperty("问卷ID")
|
||||||
private Long questionnaireId;
|
private Long questionnaireId;
|
||||||
|
|
||||||
|
@Schema(description = "任务ID", example = "1001")
|
||||||
|
@ExcelProperty("任务ID")
|
||||||
|
private Long taskId;
|
||||||
|
|
||||||
@Schema(description = "问卷名称")
|
@Schema(description = "问卷名称")
|
||||||
@ExcelProperty("问卷名称")
|
@ExcelProperty("问卷名称")
|
||||||
private String questionnaireName;
|
private String questionnaireName;
|
||||||
|
|||||||
@ -110,8 +110,12 @@ public class QuickCommentController {
|
|||||||
new LambdaQueryWrapper<CommentCategoryDO>()
|
new LambdaQueryWrapper<CommentCategoryDO>()
|
||||||
.in(CommentCategoryDO::getId, categoryIds)
|
.in(CommentCategoryDO::getId, categoryIds)
|
||||||
);
|
);
|
||||||
categoryNameMap = categories.stream()
|
for (CommentCategoryDO category : categories) {
|
||||||
.collect(Collectors.toMap(CommentCategoryDO::getId, CommentCategoryDO::getName));
|
if (category == null || category.getId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
categoryNameMap.putIfAbsent(category.getId(), category.getName() == null ? "" : category.getName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 填充分类名称
|
// 填充分类名称
|
||||||
|
|||||||
@ -108,8 +108,14 @@ public class CellServiceImpl implements CellService {
|
|||||||
if (CollUtil.isNotEmpty(areaIds)) {
|
if (CollUtil.isNotEmpty(areaIds)) {
|
||||||
List<AreaDO> areas = areaMapper.selectList(new LambdaQueryWrapperX<AreaDO>()
|
List<AreaDO> areas = areaMapper.selectList(new LambdaQueryWrapperX<AreaDO>()
|
||||||
.inIfPresent(AreaDO::getId, new ArrayList<>(areaIds)));
|
.inIfPresent(AreaDO::getId, new ArrayList<>(areaIds)));
|
||||||
areaMap = areas.stream()
|
Map<Long, AreaDO> tempAreaMap = new HashMap<>();
|
||||||
.collect(Collectors.toMap(AreaDO::getId, Function.identity()));
|
for (AreaDO area : areas) {
|
||||||
|
if (area == null || area.getId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempAreaMap.putIfAbsent(area.getId(), area);
|
||||||
|
}
|
||||||
|
areaMap = tempAreaMap;
|
||||||
} else {
|
} else {
|
||||||
areaMap = new HashMap<>();
|
areaMap = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,8 +33,10 @@ import java.time.Period;
|
|||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.time.temporal.ChronoUnit;
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -627,12 +629,13 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
.orderByDesc(EvaluationReportDO::getEvaluationDate));
|
.orderByDesc(EvaluationReportDO::getEvaluationDate));
|
||||||
|
|
||||||
// 按罪犯ID分组,取最新的评估记录
|
// 按罪犯ID分组,取最新的评估记录
|
||||||
Map<Long, EvaluationReportDO> latestReportMap = allReports.stream()
|
Map<Long, EvaluationReportDO> latestReportMap = new HashMap<>();
|
||||||
.collect(Collectors.toMap(
|
for (EvaluationReportDO report : allReports) {
|
||||||
EvaluationReportDO::getPrisonerId,
|
if (report == null || report.getPrisonerId() == null) {
|
||||||
r -> r,
|
continue;
|
||||||
(existing, replacement) -> existing // 保留第一个(最新的)
|
}
|
||||||
));
|
latestReportMap.putIfAbsent(report.getPrisonerId(), report); // 保留第一条(最新的)
|
||||||
|
}
|
||||||
List<EvaluationReportDO> latestReports = new ArrayList<>(latestReportMap.values());
|
List<EvaluationReportDO> latestReports = new ArrayList<>(latestReportMap.values());
|
||||||
|
|
||||||
// 统计各风险等级人数
|
// 统计各风险等级人数
|
||||||
@ -662,14 +665,21 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
// 按罪犯ID分组,取本月第一次评估
|
// 按罪犯ID分组,取本月第一次评估
|
||||||
Map<Long, EvaluationReportDO> thisMonthNewMap = thisMonthReports.stream()
|
Map<Long, EvaluationReportDO> thisMonthNewMap = new HashMap<>();
|
||||||
.filter(r -> !latestReportMap.containsKey(r.getPrisonerId()) ||
|
for (EvaluationReportDO report : thisMonthReports) {
|
||||||
latestReportMap.get(r.getPrisonerId()).getEvaluationDate().toLocalDate().isAfter(firstDayOfMonth.minusDays(1)))
|
if (report == null || report.getPrisonerId() == null) {
|
||||||
.collect(Collectors.toMap(
|
continue;
|
||||||
EvaluationReportDO::getPrisonerId,
|
}
|
||||||
r -> r,
|
EvaluationReportDO latestReport = latestReportMap.get(report.getPrisonerId());
|
||||||
(existing, replacement) -> existing
|
if (latestReport == null) {
|
||||||
));
|
thisMonthNewMap.putIfAbsent(report.getPrisonerId(), report);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (latestReport.getEvaluationDate() != null
|
||||||
|
&& latestReport.getEvaluationDate().toLocalDate().isAfter(firstDayOfMonth.minusDays(1))) {
|
||||||
|
thisMonthNewMap.putIfAbsent(report.getPrisonerId(), report);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int monthlyNewHighRisk = 0, monthlyNewWarning = 0, monthlyNewNormal = 0;
|
int monthlyNewHighRisk = 0, monthlyNewWarning = 0, monthlyNewNormal = 0;
|
||||||
for (EvaluationReportDO report : thisMonthNewMap.values()) {
|
for (EvaluationReportDO report : thisMonthNewMap.values()) {
|
||||||
@ -717,12 +727,13 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
!r.getEvaluationDate().toLocalDate().isAfter(monthEnd))
|
!r.getEvaluationDate().toLocalDate().isAfter(monthEnd))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
Map<Long, EvaluationReportDO> monthEndLatestMap = monthEndReports.stream()
|
Map<Long, EvaluationReportDO> monthEndLatestMap = new HashMap<>();
|
||||||
.collect(Collectors.toMap(
|
for (EvaluationReportDO report : monthEndReports) {
|
||||||
EvaluationReportDO::getPrisonerId,
|
if (report == null || report.getPrisonerId() == null) {
|
||||||
r -> r,
|
continue;
|
||||||
(existing, replacement) -> existing
|
}
|
||||||
));
|
monthEndLatestMap.putIfAbsent(report.getPrisonerId(), report);
|
||||||
|
}
|
||||||
|
|
||||||
int monthHigh = 0, monthWarning = 0, monthNormal = 0;
|
int monthHigh = 0, monthWarning = 0, monthNormal = 0;
|
||||||
for (EvaluationReportDO report : monthEndLatestMap.values()) {
|
for (EvaluationReportDO report : monthEndLatestMap.values()) {
|
||||||
@ -778,12 +789,13 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
List<EvaluationReportDO> allReports = evaluationReportMapper.selectList(wrapper);
|
List<EvaluationReportDO> allReports = evaluationReportMapper.selectList(wrapper);
|
||||||
|
|
||||||
// 按罪犯ID去重,保留最新的评估记录
|
// 按罪犯ID去重,保留最新的评估记录
|
||||||
Map<Long, EvaluationReportDO> latestReportMap = allReports.stream()
|
Map<Long, EvaluationReportDO> latestReportMap = new HashMap<>();
|
||||||
.collect(Collectors.toMap(
|
for (EvaluationReportDO report : allReports) {
|
||||||
EvaluationReportDO::getPrisonerId,
|
if (report == null || report.getPrisonerId() == null) {
|
||||||
r -> r,
|
continue;
|
||||||
(existing, replacement) -> existing
|
}
|
||||||
));
|
latestReportMap.putIfAbsent(report.getPrisonerId(), report);
|
||||||
|
}
|
||||||
List<EvaluationReportDO> uniqueReports = new ArrayList<>(latestReportMap.values());
|
List<EvaluationReportDO> uniqueReports = new ArrayList<>(latestReportMap.values());
|
||||||
|
|
||||||
// 手动分页
|
// 手动分页
|
||||||
@ -795,10 +807,22 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
// 获取罪犯详细信息
|
// 获取罪犯详细信息
|
||||||
List<Long> prisonerIds = pagedReports.stream()
|
List<Long> prisonerIds = pagedReports.stream()
|
||||||
.map(EvaluationReportDO::getPrisonerId)
|
.map(EvaluationReportDO::getPrisonerId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.distinct()
|
||||||
.toList();
|
.toList();
|
||||||
Map<Long, PrisonerDO> prisonerMap = prisonerIds.isEmpty() ? Map.of() :
|
Map<Long, PrisonerDO> prisonerMap;
|
||||||
prisonerMapper.selectBatchIds(prisonerIds).stream()
|
if (prisonerIds.isEmpty()) {
|
||||||
.collect(Collectors.toMap(PrisonerDO::getId, p -> p));
|
prisonerMap = Map.of();
|
||||||
|
} else {
|
||||||
|
Map<Long, PrisonerDO> tempPrisonerMap = new HashMap<>();
|
||||||
|
for (PrisonerDO prisoner : prisonerMapper.selectBatchIds(prisonerIds)) {
|
||||||
|
if (prisoner == null || prisoner.getId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempPrisonerMap.putIfAbsent(prisoner.getId(), prisoner);
|
||||||
|
}
|
||||||
|
prisonerMap = tempPrisonerMap;
|
||||||
|
}
|
||||||
|
|
||||||
// 获取监区信息
|
// 获取监区信息
|
||||||
List<Long> areaIds = pagedReports.stream()
|
List<Long> areaIds = pagedReports.stream()
|
||||||
@ -806,9 +830,19 @@ public class PrisonDashboardServiceImpl implements PrisonDashboardService {
|
|||||||
.filter(id -> id != null)
|
.filter(id -> id != null)
|
||||||
.distinct()
|
.distinct()
|
||||||
.toList();
|
.toList();
|
||||||
Map<Long, AreaDO> areaMap = areaIds.isEmpty() ? Map.of() :
|
Map<Long, AreaDO> areaMap;
|
||||||
areaMapper.selectBatchIds(areaIds).stream()
|
if (areaIds.isEmpty()) {
|
||||||
.collect(Collectors.toMap(AreaDO::getId, a -> a));
|
areaMap = Map.of();
|
||||||
|
} else {
|
||||||
|
Map<Long, AreaDO> tempAreaMap = new HashMap<>();
|
||||||
|
for (AreaDO area : areaMapper.selectBatchIds(areaIds)) {
|
||||||
|
if (area == null || area.getId() == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
tempAreaMap.putIfAbsent(area.getId(), area);
|
||||||
|
}
|
||||||
|
areaMap = tempAreaMap;
|
||||||
|
}
|
||||||
|
|
||||||
// 判断本月新增
|
// 判断本月新增
|
||||||
LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
|
LocalDate firstDayOfMonth = LocalDate.now().withDayOfMonth(1);
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import org.springframework.transaction.annotation.Transactional;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.LocalTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -417,6 +418,9 @@ public class EvaluationReportServiceImpl implements EvaluationReportService {
|
|||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Long createReport(EvaluationReportSaveReqVO createReqVO) {
|
public Long createReport(EvaluationReportSaveReqVO createReqVO) {
|
||||||
EvaluationReportDO report = BeanUtils.toBean(createReqVO, EvaluationReportDO.class);
|
EvaluationReportDO report = BeanUtils.toBean(createReqVO, EvaluationReportDO.class);
|
||||||
|
if (createReqVO.getEvaluationDate() != null) {
|
||||||
|
report.setEvaluationDate(createReqVO.getEvaluationDate().atStartOfDay());
|
||||||
|
}
|
||||||
// 生成报告编号
|
// 生成报告编号
|
||||||
report.setReportNo(generateReportNo());
|
report.setReportNo(generateReportNo());
|
||||||
// 初始状态为草稿
|
// 初始状态为草稿
|
||||||
@ -436,6 +440,9 @@ public class EvaluationReportServiceImpl implements EvaluationReportService {
|
|||||||
public void updateReport(EvaluationReportSaveReqVO updateReqVO) {
|
public void updateReport(EvaluationReportSaveReqVO updateReqVO) {
|
||||||
validateReportExists(updateReqVO.getId());
|
validateReportExists(updateReqVO.getId());
|
||||||
EvaluationReportDO updateObj = BeanUtils.toBean(updateReqVO, EvaluationReportDO.class);
|
EvaluationReportDO updateObj = BeanUtils.toBean(updateReqVO, EvaluationReportDO.class);
|
||||||
|
if (updateReqVO.getEvaluationDate() != null) {
|
||||||
|
updateObj.setEvaluationDate(updateReqVO.getEvaluationDate().atStartOfDay());
|
||||||
|
}
|
||||||
evaluationReportMapper.updateById(updateObj);
|
evaluationReportMapper.updateById(updateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user