|
|
@@ -0,0 +1,232 @@
|
|
|
+package com.zksy.base.warning.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.zksy.base.warning.domain.EarlyWarning;
|
|
|
+import com.zksy.base.warning.domain.WarningTodo;
|
|
|
+import com.zksy.base.warning.mapper.EarlyWarningMapper;
|
|
|
+import com.zksy.base.warning.mapper.WarningTodoMapper;
|
|
|
+import com.zksy.base.warning.service.WarningDashboardService;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 预警仪表盘服务实现
|
|
|
+ * <p>
|
|
|
+ * 从 early_warning(预警主表)、warning_todo(预警待办表)、warning_archive(预警归档表)
|
|
|
+ * 中提取数据,提供大屏可视化所需的统计指标。
|
|
|
+ *
|
|
|
+ * @author zksy
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class WarningDashboardServiceImpl implements WarningDashboardService {
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private EarlyWarningMapper earlyWarningMapper;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private WarningTodoMapper warningTodoMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 已解除/已关闭的状态值集合
|
|
|
+ */
|
|
|
+ private static final Set<String> RESOLVED_STATUSES = new HashSet<>(Arrays.asList("CLOSED", "RESOLVED"));
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getTodayOverview() {
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ LocalDateTime todayStart = today.atStartOfDay();
|
|
|
+ LocalDateTime todayEnd = today.atTime(23, 59, 59);
|
|
|
+
|
|
|
+ // 1. 查询今日所有预警
|
|
|
+ LambdaQueryWrapper<EarlyWarning> todayWrapper = new LambdaQueryWrapper<>();
|
|
|
+ todayWrapper.between(EarlyWarning::getCreateTime, todayStart, todayEnd);
|
|
|
+ List<EarlyWarning> todayWarnings = earlyWarningMapper.selectList(todayWrapper);
|
|
|
+
|
|
|
+ // 2. 分类:未解除 vs 已解除
|
|
|
+ List<EarlyWarning> unresolvedList = todayWarnings.stream()
|
|
|
+ .filter(w -> w.getStatus() == null || !RESOLVED_STATUSES.contains(w.getStatus()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ List<EarlyWarning> resolvedList = todayWarnings.stream()
|
|
|
+ .filter(w -> w.getStatus() != null && RESOLVED_STATUSES.contains(w.getStatus()))
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ result.put("unresolvedCount", unresolvedList.size());
|
|
|
+ result.put("resolvedCount", resolvedList.size());
|
|
|
+ result.put("unresolvedList", buildWarningDetailList(unresolvedList));
|
|
|
+ result.put("resolvedList", buildWarningDetailList(resolvedList));
|
|
|
+
|
|
|
+ log.info("今日预警概况: 未解除={}, 已解除={}", unresolvedList.size(), resolvedList.size());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getHistoryOverview() {
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ // 1. 查询所有预警(含归档表中的历史数据)
|
|
|
+ List<EarlyWarning> allWarnings = earlyWarningMapper.selectList(null);
|
|
|
+ long totalCount = allWarnings.size();
|
|
|
+
|
|
|
+ // 2. 按预警专项分组统计
|
|
|
+ Map<String, Long> specialCountMap = allWarnings.stream()
|
|
|
+ .filter(w -> w.getWarningSpecial() != null && !w.getWarningSpecial().isEmpty())
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ w -> w.getWarningSpecial() != null ? w.getWarningSpecial() : "未分类",
|
|
|
+ Collectors.counting()));
|
|
|
+
|
|
|
+ // 未分类的
|
|
|
+ long unclassified = allWarnings.stream()
|
|
|
+ .filter(w -> w.getWarningSpecial() == null || w.getWarningSpecial().isEmpty())
|
|
|
+ .count();
|
|
|
+ if (unclassified > 0) {
|
|
|
+ specialCountMap.put("未分类", unclassified);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 构建专项统计列表(按数量降序)
|
|
|
+ List<Map<String, Object>> specialStats = specialCountMap.entrySet().stream()
|
|
|
+ .sorted(Map.Entry.<String, Long>comparingByValue().reversed())
|
|
|
+ .map(entry -> {
|
|
|
+ Map<String, Object> item = new LinkedHashMap<>();
|
|
|
+ item.put("specialName", entry.getKey());
|
|
|
+ item.put("count", entry.getValue());
|
|
|
+ item.put("percentage", totalCount > 0
|
|
|
+ ? Math.round(entry.getValue() * 10000.0 / totalCount) / 100.0
|
|
|
+ : 0.0);
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ result.put("totalCount", totalCount);
|
|
|
+ result.put("specialStats", specialStats);
|
|
|
+
|
|
|
+ // 4. 各专项的预警详情列表(前 20 条,按时间倒序)
|
|
|
+ List<Map<String, Object>> detailList = allWarnings.stream()
|
|
|
+ .sorted(Comparator.comparing(EarlyWarning::getCreateTime,
|
|
|
+ Comparator.nullsLast(Comparator.reverseOrder())))
|
|
|
+ .limit(20)
|
|
|
+ .map(this::buildSingleWarningDetail)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ result.put("detailList", detailList);
|
|
|
+
|
|
|
+ log.info("历史预警概况: 总数={}, 专项数={}", totalCount, specialStats.size());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Map<String, Object> getTodayUnprocessed() {
|
|
|
+ Map<String, Object> result = new LinkedHashMap<>();
|
|
|
+
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ LocalDateTime todayStart = today.atStartOfDay();
|
|
|
+ LocalDateTime todayEnd = today.atTime(23, 59, 59);
|
|
|
+
|
|
|
+ // 1. 查询今日创建的待办(未完成)
|
|
|
+ LambdaQueryWrapper<WarningTodo> todoWrapper = new LambdaQueryWrapper<>();
|
|
|
+ todoWrapper.between(WarningTodo::getCreateTime, todayStart, todayEnd);
|
|
|
+ todoWrapper.isNull(WarningTodo::getCompleteTime);
|
|
|
+ List<WarningTodo> unprocessedTodos = warningTodoMapper.selectList(todoWrapper);
|
|
|
+
|
|
|
+ // 2. 提取 warningId 集合,批量查询关联预警
|
|
|
+ Set<String> warningIds = unprocessedTodos.stream()
|
|
|
+ .map(WarningTodo::getWarningId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ Map<String, EarlyWarning> warningMap;
|
|
|
+ if (!warningIds.isEmpty()) {
|
|
|
+ LambdaQueryWrapper<EarlyWarning> warningWrapper = new LambdaQueryWrapper<>();
|
|
|
+ warningWrapper.in(EarlyWarning::getWarningId, warningIds);
|
|
|
+ warningMap = earlyWarningMapper.selectList(warningWrapper).stream()
|
|
|
+ .collect(Collectors.toMap(EarlyWarning::getWarningId, w -> w, (a, b) -> a));
|
|
|
+ } else {
|
|
|
+ warningMap = Collections.emptyMap();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 构建未处置预警列表
|
|
|
+ List<Map<String, Object>> list = unprocessedTodos.stream()
|
|
|
+ .filter(todo -> todo.getWarningId() != null)
|
|
|
+ .map(todo -> {
|
|
|
+ Map<String, Object> item = new LinkedHashMap<>();
|
|
|
+ EarlyWarning warning = warningMap.get(todo.getWarningId());
|
|
|
+
|
|
|
+ if (warning != null) {
|
|
|
+ item.put("warningId", warning.getWarningId());
|
|
|
+ item.put("warningName", warning.getWarningName());
|
|
|
+ item.put("warningType", warning.getWarningType());
|
|
|
+ item.put("warningLevel", warning.getWarningLevel());
|
|
|
+ item.put("warningSpecial", warning.getWarningSpecial());
|
|
|
+ item.put("location", warning.getLocation());
|
|
|
+ item.put("ownershipUnit", warning.getOwnershipUnit());
|
|
|
+ item.put("publisher", warning.getPublisher());
|
|
|
+ item.put("publishTime", warning.getPublishTime() != null
|
|
|
+ ? warning.getPublishTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ : null);
|
|
|
+ item.put("status", warning.getStatus());
|
|
|
+ item.put("warningContent", warning.getWarningContent());
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<String, Object> todoInfo = new LinkedHashMap<>();
|
|
|
+ todoInfo.put("todoId", todo.getTodoId());
|
|
|
+ todoInfo.put("userName", todo.getUserName());
|
|
|
+ todoInfo.put("taskName", todo.getTaskName());
|
|
|
+ todoInfo.put("todoType", todo.getTodoType());
|
|
|
+ todoInfo.put("createTime", todo.getCreateTime() != null
|
|
|
+ ? todo.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ : null);
|
|
|
+ item.put("todoInfo", todoInfo);
|
|
|
+
|
|
|
+ return item;
|
|
|
+ })
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ result.put("total", list.size());
|
|
|
+ result.put("list", list);
|
|
|
+
|
|
|
+ log.info("今日未处置预警: 总数={}", list.size());
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将预警列表转换为详情 Map 列表
|
|
|
+ */
|
|
|
+ private List<Map<String, Object>> buildWarningDetailList(List<EarlyWarning> warnings) {
|
|
|
+ return warnings.stream()
|
|
|
+ .map(this::buildSingleWarningDetail)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将单个预警转换为详情 Map
|
|
|
+ */
|
|
|
+ private Map<String, Object> buildSingleWarningDetail(EarlyWarning w) {
|
|
|
+ Map<String, Object> item = new LinkedHashMap<>();
|
|
|
+ item.put("warningId", w.getWarningId());
|
|
|
+ item.put("warningName", w.getWarningName());
|
|
|
+ item.put("warningType", w.getWarningType());
|
|
|
+ item.put("warningLevel", w.getWarningLevel());
|
|
|
+ item.put("warningSpecial", w.getWarningSpecial());
|
|
|
+ item.put("location", w.getLocation());
|
|
|
+ item.put("ownershipUnit", w.getOwnershipUnit());
|
|
|
+ item.put("publisher", w.getPublisher());
|
|
|
+ item.put("publishTime", w.getPublishTime() != null
|
|
|
+ ? w.getPublishTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ : null);
|
|
|
+ item.put("status", w.getStatus());
|
|
|
+ item.put("warningContent", w.getWarningContent());
|
|
|
+ item.put("createTime", w.getCreateTime() != null
|
|
|
+ ? w.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))
|
|
|
+ : null);
|
|
|
+ return item;
|
|
|
+ }
|
|
|
+}
|