From b1a7dea09ce9b1fdf58504b404ba8ba63873e205 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 3 Jun 2026 18:58:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A0=B9=E6=8D=AE=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E6=9F=A5=E8=AF=A2=E7=94=B5=E7=AB=99=E7=94=9F?= =?UTF-8?q?=E6=80=81=E6=B5=81=E9=87=8F=E9=99=90=E5=80=BC=E5=8F=8A=E6=9D=A5?= =?UTF-8?q?=E6=BA=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 8 + .../qgc_eng/eq/entity/vo/EngEqRuleVo.java | 35 +++++ .../qgc_eng/eq/service/EngEqDataService.java | 3 + .../eq/service/impl/EngEqDataServiceImpl.java | 143 ++++++++++++++++++ 4 files changed, 189 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRuleVo.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 0de58b54..c1b58dfd 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 @@ -4,6 +4,7 @@ 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.EngEqIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRuleVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.service.EngEqDataService; @@ -57,6 +58,13 @@ public class EngEqDataController { return ResponseResult.successData(engEqDataService.getQgcHourVAlongKendoListCust(dataSourceRequest)); } + @PostMapping("/data/getEngLimit") + @Operation(summary = "根据时间范围查询电站生态流量限值及来源") + public ResponseResult getEngLimit(@RequestBody DataSourceRequest dataSourceRequest) { + EngEqRuleVo result = engEqDataService.getEngLimit(dataSourceRequest); + return result == null ? ResponseResult.success() : ResponseResult.successData(result); + } + @PostMapping("/interval/qgc/getQgcStaticData") @Operation(summary = "生态流量达标率区间范围统计(一级页面)") public ResponseResult getQgcStaticData(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRuleVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRuleVo.java new file mode 100644 index 00000000..48c85326 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqRuleVo.java @@ -0,0 +1,35 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(description = "电站生态流量限值及来源") +public class EngEqRuleVo { + + @Schema(description = "电站编码") + private String stcd; + + @Schema(description = "电站名称") + private String stnm; + + @Schema(description = "环保部生态流量限值") + private String eqmnStr; + + @Schema(description = "环保部生态流量限值来源") + private String vlsr; + + @Schema(description = "水利部生态流量限值") + private String eqmnmwrStr; + + @Schema(description = "水利部生态流量限值来源") + private String mwrVlsr; + + @Schema(description = "多年平均流量值") + private String avqStr; + + @Schema(description = "多年平均流量值来源") + private String avqVlsr; +} 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 ae4673b1..d4063239 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 @@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqHourIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRuleVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngQecAlongVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; @@ -24,6 +25,8 @@ public interface EngEqDataService { DataSourceResult getQgcHourVAlongKendoListCust(DataSourceRequest dataSourceRequest); + EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest); + QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type); DataSourceResult getWbsbList(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 74b88fa6..8201f678 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 @@ -15,6 +15,7 @@ import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDataVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqDayIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqHourIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRuleVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngQecAlongVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqStaticIntervalVo; @@ -36,6 +37,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Date; +import java.math.BigDecimal; import java.math.RoundingMode; import java.time.LocalDate; import java.time.LocalDateTime; @@ -129,6 +131,52 @@ public class EngEqDataServiceImpl implements EngEqDataService { return result; } + @Override + public EngEqRuleVo getEngLimit(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + if (StrUtil.isBlank(stcd)) { + throw new IllegalArgumentException("电站编码不能为空."); + } + String[] timeRange = resolveEngLimitTimeRange(dataSourceRequest, loadOptions); + if (timeRange == null) { + throw new IllegalArgumentException("开始时间不能为空."); + } + + Map stationParamMap = new HashMap<>(); + stationParamMap.put("stcd", stcd); + List> stationList = microservicDynamicSQLMapper.pageAllList( + null, + "SELECT STCD, ENNM AS STNM, AVQ, AVQ_SRC FROM SD_ENGINFO_B_H " + + "WHERE STCD = #{map.stcd} AND NVL(IS_DELETED, 0) = 0", + stationParamMap + ); + + EngEqRuleVo vo = new EngEqRuleVo().setStcd(stcd); + if (CollUtil.isNotEmpty(stationList)) { + Map station = stationList.get(0); + vo.setStnm(asString(station.get("STNM"))); + BigDecimal avq = toBigDecimal(station.get("AVQ")); + if (avq != null) { + vo.setAvqStr("(多年平均)(m³/s):" + stripTrailingZeros(avq)); + } else { + vo.setAvqStr("(多年平均)(m³/s):无数据"); + } + String avqSrc = asString(station.get("AVQ_SRC")); + if (StrUtil.isNotBlank(avqSrc)) { + vo.setAvqVlsr(avqSrc); + } + } else { + vo.setAvqStr("(多年平均)(m³/s):无数据"); + } + + List> eqmnList = queryEngLimitRuleDetails(stcd, timeRange[0], timeRange[1], "EQMN"); + List> eqmnMwrList = queryEngLimitRuleDetails(stcd, timeRange[0], timeRange[1], "EQMNMWR"); + vo.setEqmnStr(buildEngLimitDisplay("(生态环境部)(m³/s):", eqmnList)); + vo.setEqmnmwrStr(buildEngLimitDisplay("(水利部)(m³/s):", eqmnMwrList)); + return vo; + } + @Override public QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type) { List intervalList = queryStaticIntervals(dataSourceRequest, type); @@ -775,6 +823,66 @@ public class EngEqDataServiceImpl implements EngEqDataService { return sql.toString(); } + private List> queryEngLimitRuleDetails(String stcd, + String startTime, + String endTime, + String ruleType) { + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + paramMap.put("startTime", startTime); + paramMap.put("endTime", endTime); + paramMap.put("ruleType", ruleType); + + String sql = "SELECT det.TM, det.BEGIN_TIME, det.END_TIME, det.MIN_VAL, det.VLSR, det.VLSR_TM " + + "FROM MS_WARN_RULE_DETAIL_B det " + + "INNER JOIN MS_WARN_RULE_STBPRP_B rel ON rel.RULE_ID = det.RULE_ID AND rel.STCD = #{map.stcd} " + + " AND NVL(rel.IS_DELETED, 0) = 0 " + + "INNER JOIN MS_WARN_RULE_B rule ON rule.ID = det.RULE_ID AND rule.RULE_TYPE = #{map.ruleType} " + + " AND NVL(rule.IS_DELETED, 0) = 0 " + + "INNER JOIN (SELECT TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS') AS StartDate, " + + " TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS') AS EndDate FROM DUAL) g ON g.EndDate >= det.TM " + + "INNER JOIN (SELECT EXTRACT(YEAR FROM x.StartDate) + LEVEL - 1 AS Year " + + " FROM (SELECT TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS') AS StartDate, " + + " TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS') AS EndDate FROM DUAL) x " + + " CONNECT BY EXTRACT(YEAR FROM x.StartDate) + LEVEL - 1 <= EXTRACT(YEAR FROM x.EndDate)) y ON " + + " (TO_DATE(TO_CHAR(y.Year) || LPAD(det.BEGIN_TIME, 4, '0'), 'YYYYMMDD') <= g.EndDate AND " + + " TO_DATE(TO_CHAR(y.Year) || LPAD(det.END_TIME, 4, '0'), 'YYYYMMDD') >= g.StartDate) " + + " AND TO_DATE(TO_CHAR(y.Year) || LPAD(det.END_TIME, 4, '0'), 'YYYYMMDD') >= det.TM " + + "WHERE NVL(det.IS_DELETED, 0) = 0 " + + " AND det.BEGIN_TIME IS NOT NULL " + + " AND det.END_TIME IS NOT NULL " + + " AND det.MIN_VAL IS NOT NULL " + + "GROUP BY det.TM, det.BEGIN_TIME, det.END_TIME, det.MIN_VAL, det.VLSR, det.VLSR_TM " + + "ORDER BY det.TM DESC, SUBSTR(det.BEGIN_TIME, 1, 2) ASC, SUBSTR(det.BEGIN_TIME, 3, 2) ASC, " + + " SUBSTR(det.END_TIME, 1, 2) ASC, SUBSTR(det.END_TIME, 3, 2) ASC"; + return microservicDynamicSQLMapper.pageAllList(null, sql, paramMap); + } + + private String buildEngLimitDisplay(String prefix, List> detailList) { + if (CollUtil.isEmpty(detailList)) { + return prefix + "无限值要求"; + } + List parts = new ArrayList<>(); + for (Map row : detailList) { + String beginTime = asString(row.get("BEGIN_TIME")); + String endTime = asString(row.get("END_TIME")); + BigDecimal minVal = toBigDecimal(row.get("MIN_VAL")); + if (StrUtil.length(beginTime) != 4 || StrUtil.length(endTime) != 4 || minVal == null) { + continue; + } + parts.add(String.format("%s月%s日~%s月%s日限值为:%s", + beginTime.substring(0, 2), + beginTime.substring(2, 4), + endTime.substring(0, 2), + endTime.substring(2, 4), + stripTrailingZeros(minVal))); + } + if (parts.isEmpty()) { + return prefix + "无限值要求"; + } + return prefix + String.join(";", parts); + } + private String buildHourIntervalViewSql(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -2970,6 +3078,20 @@ public class EngEqDataServiceImpl implements EngEqDataService { return null; } + private String[] resolveEngLimitTimeRange(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { + String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime"); + String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime"); + if (StrUtil.isNotBlank(startTime) && StrUtil.isNotBlank(endTime)) { + return new String[]{startTime, endTime}; + } + String[] range = new String[2]; + collectAlongTmRange(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), range); + if (StrUtil.isNotBlank(range[0]) && StrUtil.isNotBlank(range[1])) { + return range; + } + return null; + } + private void collectAlongTmRange(DataSourceRequest.FilterDescriptor filter, String[] range) { if (filter == null || range == null) { return; @@ -3022,6 +3144,27 @@ public class EngEqDataServiceImpl implements EngEqDataService { } } + private String asString(Object value) { + return value == null ? null : String.valueOf(value); + } + + private BigDecimal toBigDecimal(Object value) { + if (value == null) { + return null; + } + if (value instanceof BigDecimal bigDecimal) { + return bigDecimal; + } + return new BigDecimal(String.valueOf(value)); + } + + private String stripTrailingZeros(BigDecimal value) { + if (value == null) { + return null; + } + return value.stripTrailingZeros().toPlainString(); + } + private String mapStaticStationColumn(String field) { if (StrUtil.isBlank(field)) { return null;