package com.ruoyi.safe.service.impl;
|
|
import com.ruoyi.dto.MapDto;
|
import com.ruoyi.safe.dto.SafeChartItemDto;
|
import com.ruoyi.safe.dto.SafeHiddenTypeStatDto;
|
import com.ruoyi.safe.dto.SafeLatestEventDto;
|
import com.ruoyi.safe.dto.SafeOverviewDto;
|
import com.ruoyi.safe.dto.SafeTrendDto;
|
import com.ruoyi.safe.mapper.SafeDashboardMapper;
|
import com.ruoyi.safe.service.SafeDashboardService;
|
import lombok.RequiredArgsConstructor;
|
import org.springframework.stereotype.Service;
|
|
import java.math.BigDecimal;
|
import java.math.RoundingMode;
|
import java.time.YearMonth;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Arrays;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.function.Function;
|
import java.util.stream.Collectors;
|
|
/**
|
* 安全数据驾驶舱服务实现
|
*/
|
@Service
|
@RequiredArgsConstructor
|
public class SafeDashboardServiceImpl implements SafeDashboardService {
|
|
private static final DateTimeFormatter MONTH_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM");
|
private static final int TREND_MONTHS = 6;
|
private static final int EVENT_DEFAULT_LIMIT = 10;
|
private static final int HAZARD_RANK_DEFAULT_LIMIT = 8;
|
private static final int RECTIFY_RANK_DEFAULT_LIMIT = 5;
|
private static final int LIMIT_MAX = 20;
|
|
private final SafeDashboardMapper safeDashboardMapper;
|
|
@Override
|
public SafeOverviewDto getOverview() {
|
SafeOverviewDto dto = safeDashboardMapper.selectOverview();
|
return dto == null ? new SafeOverviewDto() : dto;
|
}
|
|
@Override
|
public List<SafeLatestEventDto> getLatestEvents(Integer limit) {
|
return safeDashboardMapper.selectLatestEvents(normalizeLimit(limit, EVENT_DEFAULT_LIMIT));
|
}
|
|
@Override
|
public List<SafeChartItemDto> getHiddenTypeDistribution() {
|
List<SafeHiddenTypeStatDto> stats = safeDashboardMapper.selectHiddenTypeDistribution();
|
long grandTotal = stats.stream().mapToLong(s -> nvl(s.getTotalCount())).sum();
|
List<SafeChartItemDto> result = new ArrayList<>();
|
for (SafeHiddenTypeStatDto stat : stats) {
|
int total = nvl(stat.getTotalCount());
|
SafeChartItemDto item = new SafeChartItemDto();
|
item.setName(stat.getName());
|
item.setValue(String.valueOf(total));
|
item.setRate(rate(total, grandTotal));
|
item.setChildren(Arrays.asList(
|
buildChild("已整改", nvl(stat.getRectifiedCount()), total),
|
buildChild("待整改", nvl(stat.getPendingCount()), total)));
|
result.add(item);
|
}
|
return result;
|
}
|
|
@Override
|
public List<SafeTrendDto> getHiddenTrend() {
|
YearMonth endMonth = YearMonth.now();
|
YearMonth startMonth = endMonth.minusMonths(TREND_MONTHS - 1L);
|
List<SafeTrendDto> rows = safeDashboardMapper.selectHiddenTrend(startMonth.atDay(1));
|
Map<String, SafeTrendDto> rowMap = rows.stream()
|
.collect(Collectors.toMap(SafeTrendDto::getMonth, Function.identity(), (a, b) -> a));
|
|
List<SafeTrendDto> result = new ArrayList<>();
|
for (YearMonth month = startMonth; !month.isAfter(endMonth); month = month.plusMonths(1)) {
|
String key = month.format(MONTH_FORMATTER);
|
SafeTrendDto row = rowMap.get(key);
|
if (row == null) {
|
row = new SafeTrendDto();
|
row.setMonth(key);
|
row.setReportedCount(0);
|
row.setCompletedCount(0);
|
} else {
|
row.setReportedCount(nvl(row.getReportedCount()));
|
row.setCompletedCount(nvl(row.getCompletedCount()));
|
}
|
result.add(row);
|
}
|
return result;
|
}
|
|
@Override
|
public List<MapDto> getHazardRiskDistribution() {
|
List<MapDto> rows = safeDashboardMapper.selectHazardRiskDistribution();
|
long total = rows.stream().mapToLong(row -> parseCount(row.getValue())).sum();
|
rows.forEach(row -> row.setRate(rate(parseCount(row.getValue()), total)));
|
return rows;
|
}
|
|
@Override
|
public List<MapDto> getHazardTypeRanking(Integer limit) {
|
List<MapDto> rows = safeDashboardMapper.selectHazardTypeRanking();
|
long total = rows.stream().mapToLong(row -> parseCount(row.getValue())).sum();
|
rows.forEach(row -> row.setRate(rate(parseCount(row.getValue()), total)));
|
return truncate(rows, normalizeLimit(limit, HAZARD_RANK_DEFAULT_LIMIT));
|
}
|
|
@Override
|
public List<MapDto> getHiddenRectifyRanking(Integer limit) {
|
List<MapDto> rows = safeDashboardMapper.selectHiddenRectifyRanking();
|
long total = rows.stream().mapToLong(row -> parseCount(row.getValue())).sum();
|
List<MapDto> result = new ArrayList<>();
|
for (MapDto row : rows) {
|
row.setRate(rate(parseCount(row.getValue()), total));
|
if (!"未指派".equals(row.getName())) {
|
result.add(row);
|
}
|
}
|
return truncate(result, normalizeLimit(limit, RECTIFY_RANK_DEFAULT_LIMIT));
|
}
|
|
private SafeChartItemDto buildChild(String name, int value, int parentTotal) {
|
SafeChartItemDto child = new SafeChartItemDto();
|
child.setName(name);
|
child.setValue(String.valueOf(value));
|
child.setRate(rate(value, parentTotal));
|
return child;
|
}
|
|
private List<MapDto> truncate(List<MapDto> rows, int limit) {
|
return rows.size() > limit ? new ArrayList<>(rows.subList(0, limit)) : rows;
|
}
|
|
private int normalizeLimit(Integer limit, int defaultValue) {
|
if (limit == null || limit < 1) {
|
return defaultValue;
|
}
|
return Math.min(limit, LIMIT_MAX);
|
}
|
|
private int nvl(Integer value) {
|
return value == null ? 0 : value;
|
}
|
|
private long parseCount(String value) {
|
if (value == null || value.isBlank()) {
|
return 0L;
|
}
|
try {
|
return Long.parseLong(value.trim());
|
} catch (NumberFormatException e) {
|
return 0L;
|
}
|
}
|
|
private String rate(long part, long total) {
|
if (total <= 0) {
|
return BigDecimal.ZERO.setScale(2, RoundingMode.HALF_UP).toPlainString();
|
}
|
return BigDecimal.valueOf(part)
|
.multiply(BigDecimal.valueOf(100))
|
.divide(BigDecimal.valueOf(total), 2, RoundingMode.HALF_UP)
|
.toPlainString();
|
}
|
}
|