fix: 新增综合导出水质达标率
This commit is contained in:
parent
2837e9e28d
commit
73ae21a62b
@ -25,4 +25,18 @@ public interface SdWqRMapper extends BaseMapper<SdWqR> {
|
||||
@Param("fieldName") String fieldName,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
|
||||
/**
|
||||
* 查询水质达标数据(小时级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数
|
||||
*/
|
||||
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
|
||||
/**
|
||||
* 查询各测站不达标要素(SFDB=0 时的 WQ_SFDBHN_YS)
|
||||
*/
|
||||
List<Map<String, Object>> selectPollutants(@Param("stcdList") List<String> stcdList,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
}
|
||||
|
||||
@ -25,4 +25,11 @@ public interface SdWqdaySMapper extends BaseMapper<SdWqdayS> {
|
||||
@Param("fieldName") String fieldName,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
|
||||
/**
|
||||
* 查询水质达标数据(日级),按 STCD 聚合 SFDB=1 达标数、SFDB IN (0,1) 总数
|
||||
*/
|
||||
List<Map<String, Object>> selectComplianceData(@Param("stcdList") List<String> stcdList,
|
||||
@Param("startTime") String startTime,
|
||||
@Param("endTime") String endTime);
|
||||
}
|
||||
|
||||
@ -180,6 +180,8 @@ public class QgcExportServiceImpl implements IQgcExportService {
|
||||
if (mr == null) continue;
|
||||
|
||||
List<ExportZipUtil.SheetData> sheets = new ArrayList<>();
|
||||
// 判断是否包含水质指标,后续用于追加 WQ 合规 Sheet
|
||||
boolean hasWqIndicator = false;
|
||||
for (ExportIndicatorProcessor processor : processors) {
|
||||
List<List<Object>> 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<List<Object>> complianceRows = buildWqComplianceSheet(mr, stationOrder, stationRes);
|
||||
if (complianceRows != null) {
|
||||
List<String> 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)。
|
||||
* <p>
|
||||
* 返回的 rows[0] 是子标题行(|达标数|总数|达标率(%)|达标数|总数|达标率(%)|),后续为电站数据行。
|
||||
*/
|
||||
private List<List<Object>> buildWqComplianceSheet(
|
||||
MonthRange mr, List<String> stationOrder, StationResolution stationRes) {
|
||||
|
||||
String sttp = "WQ";
|
||||
Map<String, String> 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<String> uniqueStcds = rstcdToStcd.values().stream().distinct().toList();
|
||||
String startStr = SDF.format(mr.getStart());
|
||||
String endStr = SDF.format(mr.getEnd());
|
||||
|
||||
// 查询小时达标数据
|
||||
List<Map<String, Object>> hourlyData = sdWqRMapper.selectComplianceData(uniqueStcds, startStr, endStr);
|
||||
// 查询日均达标数据
|
||||
List<Map<String, Object>> dailyData = sdWqdaySMapper.selectComplianceData(uniqueStcds, startStr, endStr);
|
||||
// 查询主要污染物
|
||||
List<Map<String, Object>> pollutantData = sdWqRMapper.selectPollutants(uniqueStcds, startStr, endStr);
|
||||
|
||||
// 按 STCD 索引达标统计
|
||||
Map<String, Map<String, Object>> hourlyMap = new LinkedHashMap<>();
|
||||
for (Map<String, Object> m : hourlyData) {
|
||||
hourlyMap.put((String) m.get("STCD"), m);
|
||||
}
|
||||
Map<String, Map<String, Object>> dailyMap = new LinkedHashMap<>();
|
||||
for (Map<String, Object> m : dailyData) {
|
||||
dailyMap.put((String) m.get("STCD"), m);
|
||||
}
|
||||
// 按 STCD 聚合污染物(去重后用逗号分隔)
|
||||
Map<String, Set<String>> pollutantSetMap = new LinkedHashMap<>();
|
||||
for (Map<String, Object> 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<Object> subRow = new ArrayList<>();
|
||||
subRow.add("");
|
||||
subRow.add("达标数");
|
||||
subRow.add("总数");
|
||||
subRow.add("达标率(%)");
|
||||
subRow.add("达标数");
|
||||
subRow.add("总数");
|
||||
subRow.add("达标率(%)");
|
||||
subRow.add("");
|
||||
|
||||
List<List<Object>> 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<String, Object> hStat = hourlyMap.get(stcd);
|
||||
Map<String, Object> dStat = dailyMap.get(stcd);
|
||||
|
||||
List<Object> row = new ArrayList<>();
|
||||
row.add(displayName != null ? displayName : rstcd);
|
||||
|
||||
// 小时达标
|
||||
appendComplianceCell(row, hStat);
|
||||
// 日均达标
|
||||
appendComplianceCell(row, dStat);
|
||||
|
||||
// 主要污染物
|
||||
Set<String> pollutants = pollutantSetMap.get(stcd);
|
||||
row.add(pollutants != null && !pollutants.isEmpty()
|
||||
? String.join(",", pollutants) : "");
|
||||
|
||||
rows.add(row);
|
||||
}
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将达标统计 Map 的达标数/总数/达标率追加到 row
|
||||
*/
|
||||
private void appendComplianceCell(List<Object> row, Map<String, Object> 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;
|
||||
|
||||
@ -24,4 +24,39 @@
|
||||
AND ${fieldName} IS NOT NULL
|
||||
</select>
|
||||
|
||||
<!-- 水质小时达标率统计:按 STCD 聚合 SFDB=1 达标数、总数 -->
|
||||
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
STCD,
|
||||
SUM(CASE WHEN SFDB = 1 THEN 1 ELSE 0 END) AS COMPLIANT_CNT,
|
||||
SUM(CASE WHEN SFDB IN (0, 1) THEN 1 ELSE 0 END) AS TOTAL_CNT
|
||||
FROM SD_WQ_R
|
||||
WHERE IS_DELETED = 0
|
||||
AND STCD IN
|
||||
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||
#{stcd}
|
||||
</foreach>
|
||||
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND SFDB IS NOT NULL
|
||||
GROUP BY STCD
|
||||
</select>
|
||||
|
||||
<!-- 查询各测站主要污染物(SFDB=0 时的 WQ_SFDBHN_YS) -->
|
||||
<select id="selectPollutants" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
STCD,
|
||||
WQ_SFDBHN_YS AS POLLUTANT
|
||||
FROM SD_WQ_R
|
||||
WHERE IS_DELETED = 0
|
||||
AND SFDB = 0
|
||||
AND WQ_SFDBHN_YS IS NOT NULL
|
||||
AND STCD IN
|
||||
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||
#{stcd}
|
||||
</foreach>
|
||||
AND TM >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND TM < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
@ -23,4 +23,22 @@
|
||||
AND ${fieldName} IS NOT NULL
|
||||
</select>
|
||||
|
||||
<!-- 水质日均达标率统计:按 STCD 聚合 SFDB=1 达标数、总数 -->
|
||||
<select id="selectComplianceData" resultType="java.util.HashMap">
|
||||
SELECT
|
||||
STCD,
|
||||
SUM(CASE WHEN SFDB = 1 THEN 1 ELSE 0 END) AS COMPLIANT_CNT,
|
||||
SUM(CASE WHEN SFDB IN (0, 1) THEN 1 ELSE 0 END) AS TOTAL_CNT
|
||||
FROM SD_WQDAY_S
|
||||
WHERE IS_DELETED = 0
|
||||
AND STCD IN
|
||||
<foreach collection="stcdList" item="stcd" open="(" separator="," close=")">
|
||||
#{stcd}
|
||||
</foreach>
|
||||
AND DT >= TO_DATE(#{startTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND DT < TO_DATE(#{endTime}, 'YYYY-MM-DD HH24:MI:SS')
|
||||
AND SFDB IS NOT NULL
|
||||
GROUP BY STCD
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user