From d3d41cb3b6af7a9145d28e3fdad8b2a47f1dc6d0 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 1 Jun 2026 19:26:17 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=94=9F=E6=80=81=E6=B5=81=E9=87=8F?= =?UTF-8?q?=E8=BE=BE=E6=A0=87=E7=8E=87=E8=AE=A1=E7=AE=97=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 7 + .../eq/entity/vo/EngEqRateCountVo.java | 50 ++++ .../qgc_eng/eq/service/EngEqDataService.java | 3 + .../eq/service/impl/EngEqDataServiceImpl.java | 237 ++++++++++++++++++ 4 files changed, 297 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRateCountVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java index 87234952..86840056 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/controller/EngEqDataController.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_eng.eq.controller; import com.yfd.platform.common.DataSourceLoadOptionsBase; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.service.EngEqDataService; import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -53,4 +54,10 @@ public class EngEqDataController { public ResponseResult getEvnmAutoMonitorList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(engEqDataService.getEvnmAutoMonitorList(dataSourceRequest)); } + + @PostMapping("/qecRateCount") + @Operation(summary = "生态流量达标率计算(基地维度、不达标原因维度)") + public ResponseResult getQecRateCount(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(engEqDataService.qecRateCount(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRateCountVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRateCountVo.java new file mode 100644 index 00000000..22ba4b74 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRateCountVo.java @@ -0,0 +1,50 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Schema(description = "生态流量达标率统计") +public class EngEqRateCountVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; + + @Schema(description = "行政区编码") + private String addvcd; + + @Schema(description = "行政区名称") + private String addvcdName; + + @Schema(description = "电站编码") + private String stcd; + + @Schema(description = "电站名称") + private String stnm; + + @Schema(description = "工程名称") + private String ennm; + + @Schema(description = "调节性能编码") + private String qecPerformance; + + @Schema(description = "调节性能名称") + private String qecPerformanceName; + + @Schema(description = "生态流量达标率") + private BigDecimal qecRate; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java index 5fe8e83d..b1786af6 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/EngEqDataService.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_eng.eq.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; import com.yfd.platform.qgc_eng.eq.entity.vo.SdEqMonitorCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.WbsbVo; @@ -15,4 +16,6 @@ public interface EngEqDataService { DataSourceResult getWbsbList(DataSourceRequest dataSourceRequest); DataSourceResult getEvnmAutoMonitorList(DataSourceRequest dataSourceRequest); + + DataSourceResult qecRateCount(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java index 7111940a..67d6d7a8 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/service/impl/EngEqDataServiceImpl.java @@ -12,6 +12,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.enums.QecIntervalEnum; import com.yfd.platform.common.enums.ShowEnum; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqStaticIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecVo; @@ -29,6 +30,9 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; +import java.math.RoundingMode; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; @Service public class EngEqDataServiceImpl implements EngEqDataService { @@ -155,6 +159,74 @@ public class EngEqDataServiceImpl implements EngEqDataService { return result; } + @Override + public DataSourceResult qecRateCount(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String baseId = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "baseId"); + String tm = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "tm"); + String[] tmRange = resolveQecRateTimeRange(tm); + + List groups = dataSourceRequest == null ? null : dataSourceRequest.getGroup(); + List selectItems = new ArrayList<>(); + List groupItems = new ArrayList<>(); + if (CollUtil.isNotEmpty(groups)) { + for (DataSourceRequest.GroupDescriptor group : groups) { + if (group == null || StrUtil.isBlank(group.getField())) { + continue; + } + String selectSql = mapQecRateSelect(group.getField()); + String groupSql = mapQecRateGroup(group.getField()); + if (StrUtil.isNotBlank(selectSql) && StrUtil.isNotBlank(groupSql)) { + selectItems.add(selectSql); + groupItems.add(groupSql); + } + } + } + + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + paramMap.put("startTime", tmRange[0]); + paramMap.put("endTime", tmRange[1]); + if (StrUtil.isNotBlank(baseId)) { + paramMap.put("baseId", baseId); + } + + sql.append("SELECT "); + if (!selectItems.isEmpty()) { + sql.append(String.join(", ", selectItems)).append(", "); + } + sql.append(buildQecRateSql()).append(" AS qecRate ") + .append("FROM SD_ENGINFO_B_H eng ") + .append("LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID ") + .append(" AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 ") + .append("LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD ") + .append("LEFT JOIN (") + .append(buildQecRateMetricSourceSql()) + .append(") met ON met.STCD = eng.STCD ") + .append("WHERE NVL(eng.IS_DELETED, 0) = 0 ") + .append(" AND NVL(eng.DTIN_ENV, 0) IN (1, 2) ") + .append(" AND NVL(eng.BLDSTT_CODE, 0) = 2 "); + if (StrUtil.isNotBlank(baseId)) { + sql.append(" AND eng.BASE_ID = #{map.baseId} "); + } + if (!groupItems.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupItems)).append(" "); + sql.append(buildQecRateOrderBy(groups)); + } + + List list = microservicDynamicSQLMapper.getAllListWithResultType( + sql.toString(), paramMap, EngEqRateCountVo.class); + fillQecRateCountNames(list); + list = completeQecPerformanceGroups(list, groups); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(list == null ? 0 : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + private DataSourceResult queryDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -697,6 +769,171 @@ public class EngEqDataServiceImpl implements EngEqDataService { "FROM SD_HBRV_DIC t WHERE NVL(t.IS_DELETED, 0) = 0 AND t.ORDER_INDEX IS NOT NULL"; } + private String buildQecRateMetricSourceSql() { + // 方案一:当前没有新框架业务结果表时,直接使用日统计表 SD_QECDAY_S 参与达标率计算。 + // 方案二:后续如果补齐新框架业务结果表,可仅替换此处为“SELECT * FROM 新业务结果表 WHERE TYPE='DAY' ...”。 + return "SELECT met.STCD, met.QEC, met.QEC_LIMIT, met.MWR_LIMIT, met.AVQ_LIMIT, " + + "met.SFDB, met.MWR_SFDB, met.AVQ_SFDB " + + "FROM SD_QECDAY_S met " + + "WHERE NVL(met.IS_DELETED, 0) = 0 " + + " AND met.DT BETWEEN TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS') " + + " AND TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS')"; + } + + private String buildQecRateSql() { + return "CASE " + + "WHEN COUNT(*) = 0 THEN NULL " + + "WHEN SUM(CASE WHEN met.QEC_LIMIT IS NULL AND met.MWR_LIMIT IS NULL AND met.AVQ_LIMIT IS NULL THEN 0 ELSE 1 END) = 0 THEN NULL " + + "WHEN SUM(CASE WHEN (met.QEC_LIMIT IS NOT NULL OR met.MWR_LIMIT IS NOT NULL OR met.AVQ_LIMIT IS NOT NULL) AND met.QEC IS NULL THEN 0 ELSE 1 END) = 0 THEN NULL " + + "WHEN SUM(CASE " + + "WHEN met.SFDB = 1 OR met.SFDB = 0 THEN 1 " + + "WHEN met.SFDB = 2 AND (met.MWR_SFDB = 1 OR met.MWR_SFDB = 0) THEN 1 " + + "WHEN met.MWR_SFDB = 2 AND (met.AVQ_SFDB = 1 OR met.AVQ_SFDB = 0) THEN 1 " + + "ELSE 0 END) = 0 THEN NULL " + + "ELSE ((SUM(CASE " + + "WHEN met.SFDB = 1 THEN 1 " + + "WHEN met.SFDB = 0 THEN 0 " + + "WHEN met.SFDB = 2 AND met.MWR_SFDB = 1 THEN 1 " + + "WHEN met.SFDB = 2 AND met.MWR_SFDB = 0 THEN 0 " + + "WHEN met.MWR_SFDB = 2 AND met.AVQ_SFDB = 1 THEN 1 " + + "WHEN met.MWR_SFDB = 2 AND met.AVQ_SFDB = 0 THEN 0 " + + "ELSE 0 END) / NULLIF(SUM(CASE " + + "WHEN met.SFDB = 1 OR met.SFDB = 0 THEN 1 " + + "WHEN met.SFDB = 2 AND (met.MWR_SFDB = 1 OR met.MWR_SFDB = 0) THEN 1 " + + "WHEN met.MWR_SFDB = 2 AND (met.AVQ_SFDB = 1 OR met.AVQ_SFDB = 0) THEN 1 " + + "ELSE 0 END), 0)) * 100) END"; + } + + private String[] resolveQecRateTimeRange(String tm) { + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + if (StrUtil.isNotBlank(tm)) { + String[] arr = StrUtil.splitToArray(tm, ','); + if (arr != null && arr.length >= 2) { + return new String[]{arr[0].trim(), arr[1].trim()}; + } + } + LocalDateTime end = LocalDateTime.now().withHour(23).withMinute(59).withSecond(59).withNano(0); + LocalDateTime start = end.minusMonths(3).withHour(0).withMinute(0).withSecond(0).withNano(0); + return new String[]{start.format(formatter), end.format(formatter)}; + } + + private String mapQecRateSelect(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "baseId" -> "eng.BASE_ID AS baseId"; + case "baseName" -> "hb.BASENAME AS baseName"; + case "hbrvcd" -> "eng.HBRVCD AS hbrvcd"; + case "hbrvcdName" -> "hbrv.HBRVNM AS hbrvcdName"; + case "addvcd" -> "eng.ADDVCD AS addvcd"; + case "addvcdName" -> "addv.ADDVNM AS addvcdName"; + case "stcd" -> "eng.STCD AS stcd"; + case "stnm" -> "eng.ENNM AS stnm"; + case "ennm" -> "eng.ENNM AS ennm"; + case "qecPerformance" -> buildQecPerformanceCaseSql() + " AS qecPerformance"; + default -> null; + }; + } + + private String mapQecRateGroup(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "baseId" -> "eng.BASE_ID"; + case "baseName" -> "hb.BASENAME"; + case "hbrvcd" -> "eng.HBRVCD"; + case "hbrvcdName" -> "hbrv.HBRVNM"; + case "addvcd" -> "eng.ADDVCD"; + case "addvcdName" -> "addv.ADDVNM"; + case "stcd" -> "eng.STCD"; + case "stnm", "ennm" -> "eng.ENNM"; + case "qecPerformance" -> buildQecPerformanceCaseSql(); + default -> null; + }; + } + + private String buildQecPerformanceCaseSql() { + return "CASE " + + "WHEN eng.RGCP = '1' THEN '1' " + + "WHEN eng.RGCP = '2' THEN '2' " + + "WHEN eng.RGCP = '5' THEN '5' " + + "WHEN eng.RGCP = '7' THEN '7' " + + "ELSE '9' END"; + } + + private String buildQecRateOrderBy(List groups) { + if (CollUtil.isEmpty(groups)) { + return ""; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor group : groups) { + if (group == null || StrUtil.isBlank(group.getField())) { + continue; + } + String column = mapQecRateGroup(group.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(group.getDir()) || "des".equalsIgnoreCase(group.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + dir); + } + return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); + } + + private void fillQecRateCountNames(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + for (EngEqRateCountVo item : list) { + item.setQecPerformanceName(getQecPerformanceName(item.getQecPerformance())); + if (item.getQecRate() != null) { + item.setQecRate(item.getQecRate().setScale(2, RoundingMode.HALF_UP)); + } + } + } + + private List completeQecPerformanceGroups(List list, + List groups) { + if (CollUtil.isEmpty(groups) || groups.get(0) == null || !"qecPerformance".equals(groups.get(0).getField())) { + return list; + } + Map exists = new LinkedHashMap<>(); + if (CollUtil.isNotEmpty(list)) { + for (EngEqRateCountVo item : list) { + if (item != null && StrUtil.isNotBlank(item.getQecPerformance())) { + exists.put(item.getQecPerformance(), item); + } + } + } + List result = new ArrayList<>(); + for (String code : Arrays.asList("1", "2", "5", "7", "9")) { + EngEqRateCountVo item = exists.get(code); + if (item == null) { + item = new EngEqRateCountVo(); + item.setQecPerformance(code); + item.setQecPerformanceName(getQecPerformanceName(code)); + } + result.add(item); + } + return result; + } + + private String getQecPerformanceName(String code) { + if (StrUtil.isBlank(code)) { + return null; + } + return switch (code) { + case "1" -> "多年调节"; + case "2" -> "年调节"; + case "5" -> "季调节"; + case "7" -> "周调节"; + case "9" -> "其他"; + default -> null; + }; + } + private String buildWbsbDetailSelectSql(List selectFields) { Map columns = wbsbFieldColumns(); List selected = new ArrayList<>();