diff --git a/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqRMapper.java b/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqRMapper.java index 12f6f401..aa9cb6b2 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqRMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqRMapper.java @@ -25,4 +25,18 @@ public interface SdWqRMapper extends BaseMapper { @Param("fieldName") String fieldName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * 查询水质达标数据(小时级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数 + */ + List> selectComplianceData(@Param("stcdList") List stcdList, + @Param("startTime") String startTime, + @Param("endTime") String endTime); + + /** + * 查询各测站不达标要素(SFDB=0 时的 WQ_SFDBHN_YS) + */ + List> selectPollutants(@Param("stcdList") List stcdList, + @Param("startTime") String startTime, + @Param("endTime") String endTime); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqdaySMapper.java b/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqdaySMapper.java index 2a2dd55e..ea974884 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqdaySMapper.java +++ b/backend/src/main/java/com/yfd/platform/qgc_export/mapper/SdWqdaySMapper.java @@ -25,4 +25,11 @@ public interface SdWqdaySMapper extends BaseMapper { @Param("fieldName") String fieldName, @Param("startTime") String startTime, @Param("endTime") String endTime); + + /** + * 查询水质达标数据(日级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数 + */ + List> selectComplianceData(@Param("stcdList") List stcdList, + @Param("startTime") String startTime, + @Param("endTime") String endTime); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_export/service/impl/QgcExportServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_export/service/impl/QgcExportServiceImpl.java index bb1a2e9f..bffd473d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_export/service/impl/QgcExportServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_export/service/impl/QgcExportServiceImpl.java @@ -180,6 +180,8 @@ public class QgcExportServiceImpl implements IQgcExportService { if (mr == null) continue; List sheets = new ArrayList<>(); + // 判断是否包含水质指标,后续用于追加 WQ 合规 Sheet + boolean hasWqIndicator = false; for (ExportIndicatorProcessor processor : processors) { List> rows; // QEC 自定义三栏达标率格式 @@ -223,6 +225,33 @@ public class QgcExportServiceImpl implements IQgcExportService { )); } sheets.add(sd); + if ("WQ".equals(sttp)) { + hasWqIndicator = true; + } + } + } + + // 若包含水质指标,追加 WQ 合规 Sheet + if (hasWqIndicator) { + List> complianceRows = buildWqComplianceSheet(mr, stationOrder, stationRes); + if (complianceRows != null) { + List complianceHeaders = new ArrayList<>(); + complianceHeaders.add("水质站"); + complianceHeaders.add("小时"); + complianceHeaders.add(""); + complianceHeaders.add(""); + complianceHeaders.add("日均"); + complianceHeaders.add(""); + complianceHeaders.add(""); + complianceHeaders.add("主要污染物"); + ExportZipUtil.SheetData sd = new ExportZipUtil.SheetData("水质达标率", complianceHeaders, complianceRows); + sd.setHeaderRowCount(1); + sd.setMergedRegions(Arrays.asList( + new int[]{0, 1, 0, 0}, // "水质站" 合并 row 0-1 + new int[]{0, 0, 1, 3}, // "小时" 合并 col 1-3 + new int[]{0, 0, 4, 6} // "日均" 合并 col 4-6 + )); + sheets.add(sd); } } @@ -449,6 +478,126 @@ public class QgcExportServiceImpl implements IQgcExportService { try { return Integer.parseInt(v.toString()); } catch (Exception e) { return -1; } } + // ======================== WQ 水质达标率 Sheet(双表头) ======================== + + /** + * 构建水质达标率 Sheet 的数据行(不含标题行,标题由调用方放入 headers)。 + *

+ * 返回的 rows[0] 是子标题行(|达标数|总数|达标率(%)|达标数|总数|达标率(%)|),后续为电站数据行。 + */ + private List> buildWqComplianceSheet( + MonthRange mr, List stationOrder, StationResolution stationRes) { + + String sttp = "WQ"; + Map rstcdToStcd = new LinkedHashMap<>(); + for (String rstcd : stationOrder) { + String stcd = stationRes.getStcd(rstcd, sttp); + if (stcd != null) { + rstcdToStcd.put(rstcd, stcd); + } + } + if (rstcdToStcd.isEmpty()) { + log.warn("水质达标率未找到 STTP=WQ 的测站数据"); + return null; + } + + List uniqueStcds = rstcdToStcd.values().stream().distinct().toList(); + String startStr = SDF.format(mr.getStart()); + String endStr = SDF.format(mr.getEnd()); + + // 查询小时达标数据 + List> hourlyData = sdWqRMapper.selectComplianceData(uniqueStcds, startStr, endStr); + // 查询日均达标数据 + List> dailyData = sdWqdaySMapper.selectComplianceData(uniqueStcds, startStr, endStr); + // 查询主要污染物 + List> pollutantData = sdWqRMapper.selectPollutants(uniqueStcds, startStr, endStr); + + // 按 STCD 索引达标统计 + Map> hourlyMap = new LinkedHashMap<>(); + for (Map m : hourlyData) { + hourlyMap.put((String) m.get("STCD"), m); + } + Map> dailyMap = new LinkedHashMap<>(); + for (Map m : dailyData) { + dailyMap.put((String) m.get("STCD"), m); + } + // 按 STCD 聚合污染物(去重后用逗号分隔) + Map> pollutantSetMap = new LinkedHashMap<>(); + for (Map m : pollutantData) { + String stcd = (String) m.get("STCD"); + String pol = (String) m.get("POLLUTANT"); + if (pol != null && !pol.isEmpty()) { + pollutantSetMap.computeIfAbsent(stcd, k -> new LinkedHashSet<>()).add(pol); + } + } + + // ======== Row 0: 子标题行 ======== + List subRow = new ArrayList<>(); + subRow.add(""); + subRow.add("达标数"); + subRow.add("总数"); + subRow.add("达标率(%)"); + subRow.add("达标数"); + subRow.add("总数"); + subRow.add("达标率(%)"); + subRow.add(""); + + List> rows = new ArrayList<>(); + rows.add(subRow); + + // ======== 数据行 ======== + for (String rstcd : stationOrder) { + String stcd = rstcdToStcd.get(rstcd); + if (stcd == null) continue; + + String displayName = stationRes.getDisplayName(rstcd, sttp); + Map hStat = hourlyMap.get(stcd); + Map dStat = dailyMap.get(stcd); + + List row = new ArrayList<>(); + row.add(displayName != null ? displayName : rstcd); + + // 小时达标 + appendComplianceCell(row, hStat); + // 日均达标 + appendComplianceCell(row, dStat); + + // 主要污染物 + Set pollutants = pollutantSetMap.get(stcd); + row.add(pollutants != null && !pollutants.isEmpty() + ? String.join(",", pollutants) : ""); + + rows.add(row); + } + + return rows; + } + + /** + * 将达标统计 Map 的达标数/总数/达标率追加到 row + */ + private void appendComplianceCell(List row, Map stat) { + if (stat == null) { + row.add(""); + row.add(""); + row.add(""); + return; + } + Object compliantObj = stat.get("COMPLIANT_CNT"); + Object totalObj = stat.get("TOTAL_CNT"); + long compliant = compliantObj instanceof Number ? ((Number) compliantObj).longValue() : 0; + long total = totalObj instanceof Number ? ((Number) totalObj).longValue() : 0; + + row.add(compliant); + row.add(total); + if (total > 0) { + BigDecimal rate = BigDecimal.valueOf(compliant * 100.0 / total); + row.add(rate.setScale(2, RoundingMode.HALF_UP).toPlainString()); + } else { + row.add(""); + } + } + /** 分部达标统计 */ private static class ComplianceStats { String dailyHb, dailySl, dailyDn; diff --git a/backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml b/backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml index 3026c9fb..987b757e 100644 --- a/backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml +++ b/backend/src/main/resources/mapper/qgc_export/SdWqRMapper.xml @@ -24,4 +24,39 @@ AND ${fieldName} IS NOT NULL + + + + + + diff --git a/backend/src/main/resources/mapper/qgc_export/SdWqdaySMapper.xml b/backend/src/main/resources/mapper/qgc_export/SdWqdaySMapper.xml index 4541f84e..3fbd4aa9 100644 --- a/backend/src/main/resources/mapper/qgc_export/SdWqdaySMapper.xml +++ b/backend/src/main/resources/mapper/qgc_export/SdWqdaySMapper.xml @@ -23,4 +23,22 @@ AND ${fieldName} IS NOT NULL + + +