From ac21220e8f42c5dffc9752e0ccd0b3a5a60eff5a Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 3 Jun 2026 18:03:52 +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=E6=97=A5=E7=BB=9F=E8=AE=A1(?= =?UTF-8?q?=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eq/controller/EngEqDataController.java | 7 +- .../eq/entity/vo/EngEqDayIntervalVo.java | 140 +++++++++ .../qgc_eng/eq/service/EngEqDataService.java | 3 + .../eq/service/impl/EngEqDataServiceImpl.java | 269 ++++++++++++++++++ 4 files changed, 418 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqDayIntervalVo.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 092e4be2..840d1d97 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,7 +3,6 @@ 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.EngEqHourIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqIntervalVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqVmsstbprptVo; import com.yfd.platform.qgc_eng.eq.entity.vo.EngEqRateCountVo; @@ -46,6 +45,12 @@ public class EngEqDataController { return ResponseResult.successData(engEqDataService.getQgcHourKendoListCust(dataSourceRequest)); } + @PostMapping("/interval/qgc/day/GetKendoListCust") + @Operation(summary = "生态流量达标率日统计(二级页面)") + public ResponseResult getQgcDayKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(engEqDataService.getQgcDayKendoListCust(dataSourceRequest)); + } + @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/EngEqDayIntervalVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqDayIntervalVo.java new file mode 100644 index 00000000..a40b7442 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqDayIntervalVo.java @@ -0,0 +1,140 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; + +@Data +@Schema(description = "生态流量达标率日统计") +public class EngEqDayIntervalVo { + + @Schema(description = "电站编码") + private String stcd; + + @Schema(description = "电站名称") + private String stnm; + + @Schema(description = "工程名称") + private String ennm; + + @Schema(description = "站类") + private String sttp; + + @Schema(description = "站类编码") + private String sttpCode; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; + + @Schema(description = "行政区名称") + private String addvcdName; + + @Schema(description = "经度") + private BigDecimal lgtd; + + @Schema(description = "纬度") + private BigDecimal lttd; + + @Schema(description = "高程") + private BigDecimal dtmel; + + @Schema(description = "装机容量") + private BigDecimal ttpwr; + + @Schema(description = "正常蓄水位") + private BigDecimal normz; + + @Schema(description = "多年平均流量") + private BigDecimal avq; + + @Schema(description = "是否接入") + private Integer dtin; + + @Schema(description = "环保数据接入状态") + private Integer dtinEnv; + + @Schema(description = "工程规模") + private Integer prsc; + + @Schema(description = "建设状态分类") + private Integer bldsttCcode; + + @Schema(description = "入库流量") + private BigDecimal qi; + + @Schema(description = "出库流量") + private BigDecimal qo; + + @Schema(description = "生态流量") + private BigDecimal qec; + + @Schema(description = "坝上水位") + private BigDecimal rz; + + @Schema(description = "生态流量达标率") + private BigDecimal qecRate; + + @Schema(description = "水利部生态流量达标率") + private BigDecimal mwrRate; + + @Schema(description = "多年平均生态流量达标率") + private BigDecimal avqRate; + + @Schema(description = "环保部区间") + private String qecInterval; + + @Schema(description = "水利部区间") + private String mwrInterval; + + @Schema(description = "多年平均区间") + private String avqInterval; + + @Schema(description = "环保部锚点状态") + private String anchoPointState; + + @Schema(description = "水利部锚点状态") + private String mwrPointState; + + @Schema(description = "多年平均锚点状态") + private String avqPointState; + + @Schema(description = "入库流量合计") + private BigDecimal qiSum; + + @Schema(description = "出库流量合计") + private BigDecimal qoSum; + + @Schema(description = "补水总量") + private BigDecimal fillWater; + + @Schema(description = "标题名称") + private String titleName; + + @Schema(description = "生态类型") + private String eqtp; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "站点排序") + private Integer siteStepSort; + + @Schema(description = "最新时间的一条数据") + private LastTmEngEqDataVo lastTmEngEqDataVo; +} 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 9e3e7031..a3d3944f 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.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.EngEqRateCountVo; @@ -18,6 +19,8 @@ public interface EngEqDataService { DataSourceResult getQgcHourKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcDayKendoListCust(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 6507c786..259c55c0 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.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.EngEqRateCountVo; @@ -71,6 +72,15 @@ public class EngEqDataServiceImpl implements EngEqDataService { return queryHourIntervalGroupList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult getQgcDayKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryDayIntervalDetailList(dataSourceRequest, loadOptions); + } + return queryDayIntervalGroupList(dataSourceRequest, loadOptions); + } + @Override public QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type) { List intervalList = queryStaticIntervals(dataSourceRequest, type); @@ -413,6 +423,265 @@ public class EngEqDataServiceImpl implements EngEqDataService { } } + private DataSourceResult queryDayIntervalDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + Map paramMap = new HashMap<>(); + int[] indexHolder = new int[]{0}; + String viewSql = buildDayIntervalViewSql(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder); + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildHourDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(viewSql) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildHourFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + if (CollUtil.isNotEmpty(dataSourceRequest == null ? null : dataSourceRequest.getAggregate()) + && "average".equalsIgnoreCase(dataSourceRequest.getAggregate().get(0).getAggregate())) { + return buildDayIntervalAggregateResult(dataSourceRequest, sql.toString(), paramMap); + } + + sql.append(buildHourDetailOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, EngEqDayIntervalVo.class); + postProcessDayIntervalList(list); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryDayIntervalGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + List groups = dataSourceRequest.getGroup(); + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + Map paramMap = new HashMap<>(); + int[] indexHolder = new int[]{0}; + String viewSql = buildDayIntervalViewSql(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder); + + List selectItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapHourColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField().toUpperCase()); + selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase()); + if (CollUtil.isNotEmpty(descriptor.getAggregates())) { + for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) { + String aggregateColumn = mapHourColumn(aggregate.getField()); + if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) { + continue; + } + selectItems.add(buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField())); + } + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + } + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(String.join(", ", selectItems)) + .append(" FROM (") + .append(viewSql) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildHourFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, indexHolder); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + List groupByColumns = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapHourColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildHourGroupOrderBySql(groups)); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData((List) (List) new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult buildDayIntervalAggregateResult(DataSourceRequest dataSourceRequest, + String sourceSql, + Map paramMap) { + List aggregateItems = new ArrayList<>(); + for (DataSourceRequest.AggregateDescriptor item : dataSourceRequest.getAggregate()) { + if (item == null || !"average".equalsIgnoreCase(item.getAggregate())) { + continue; + } + String column = mapHourColumn(item.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + aggregateItems.add("AVG(" + column + ") AS " + item.getField()); + } + if (aggregateItems.isEmpty()) { + DataSourceResult emptyResult = new DataSourceResult<>(); + emptyResult.setData(new ArrayList<>()); + emptyResult.setTotal(0L); + emptyResult.setAggregates(new HashMap<>()); + return emptyResult; + } + + String sql = "SELECT " + String.join(", ", aggregateItems) + " FROM (" + sourceSql + ")"; + List> list = microservicDynamicSQLMapper.pageAllList(null, sql, paramMap); + DataSourceResult result = new DataSourceResult<>(); + result.setData((List) (List) list); + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + private void postProcessDayIntervalList(List list) { + if (CollUtil.isEmpty(list)) { + return; + } + for (EngEqDayIntervalVo item : list) { + if (item == null) { + continue; + } + if (item.getQiSum() != null && item.getQoSum() != null) { + item.setFillWater(item.getQoSum().subtract(item.getQiSum())); + } + item.setTitleName(item.getEnnm()); + item.setEqtp("QEC"); + } + } + + private String buildDayIntervalViewSql(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + boolean hasDtinFilter = CollUtil.isNotEmpty(findFilterValues(filter, "dtin")); + return "SELECT " + + "eng.STCD AS stcd, " + + "eng.ENNM AS stnm, " + + "eng.ENNM AS ennm, " + + "'ENG' AS sttp, " + + "'ENG' AS sttpCode, " + + "eng.BASE_ID AS baseId, " + + "hb.BASENAME AS baseName, " + + "eng.HBRVCD AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName, " + + "addv.ADDVNM AS addvcdName, " + + "eng.LGTD AS lgtd, " + + "eng.LTTD AS lttd, " + + "eng.ELEV AS dtmel, " + + "CAST(NULL AS NUMBER(18,6)) AS ttpwr, " + + "CAST(NULL AS NUMBER(18,6)) AS normz, " + + "eng.AVQ AS avq, " + + "eng.DTIN AS dtin, " + + "eng.DTIN_ENV AS dtinEnv, " + + "eng.PRSC AS prsc, " + + "eng.BLDSTT_CODE AS bldsttCcode, " + + "runAgg.QI AS qi, " + + "runAgg.QO AS qo, " + + "runAgg.QEC AS qec, " + + "runAgg.RZ AS rz, " + + buildIntervalRateDisplaySql("met.QEC_RATE") + " AS qecRate, " + + buildIntervalRateDisplaySql("met.MWR_RATE") + " AS mwrRate, " + + buildIntervalRateDisplaySql("met.AVQ_RATE") + " AS avqRate, " + + buildStaticIntervalSql("met.STCD", "met.QEC_RATE", "met.QR", "qecNoRule.STCD", false) + " AS qecInterval, " + + buildStaticIntervalSql("met.STCD", "met.MWR_RATE", "met.MQR", "mwrNoRule.STCD", false) + " AS mwrInterval, " + + buildStaticIntervalSql("met.STCD", "met.AVQ_RATE", "met.AQR", "eng.AVQ", true) + " AS avqInterval, " + + buildHourPointStateSql("met.QEC_RATE") + " AS anchoPointState, " + + buildHourPointStateSql("met.MWR_RATE") + " AS mwrPointState, " + + buildHourPointStateSql("met.AVQ_RATE") + " AS avqPointState, " + + "runAgg.QI_SUM AS qiSum, " + + "runAgg.QO_SUM AS qoSum, " + + "CAST(NULL AS NUMBER(18,6)) AS fillWater, " + + "CAST(NULL AS VARCHAR2(255)) AS titleName, " + + "CAST(NULL AS VARCHAR2(20)) AS eqtp, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(along.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(rstSort.SORT, 999999) AS rstcdStepSort, " + + "NVL(siteSort.SORT, 999999) AS siteStepSort " + + "FROM SD_ENGINFO_B_H eng " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = eng.HBRVCD AND hbrv.BASEID = eng.BASE_ID " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD " + + "LEFT JOIN MS_ALONG_B along ON along.RVCD = eng.HBRVCD AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " + + "LEFT JOIN ( " + + " SELECT det.SORT, cfg.RVCD, det.STCD " + + " FROM MS_ALONGDET_B det " + + " INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " + + " WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " + + ") rstSort ON rstSort.RVCD = eng.HBRVCD AND rstSort.STCD = eng.STCD " + + "LEFT JOIN ( " + + " SELECT det.SORT, cfg.RVCD, det.STCD " + + " FROM MS_ALONGDET_B det " + + " INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID " + + " WHERE NVL(det.IS_DELETED, 0) = 0 AND NVL(cfg.IS_DELETED, 0) = 0 AND cfg.CODE = 'common' " + + ") siteSort ON siteSort.RVCD = eng.HBRVCD AND siteSort.STCD = eng.STCD " + + "LEFT JOIN (" + buildDayMetricSourceSql(filter, paramMap, indexHolder, 0) + ") met ON met.STCD = eng.STCD " + + "LEFT JOIN (" + buildDayRunSourceSql(filter, paramMap, indexHolder, 0) + ") runAgg ON runAgg.STCD = eng.STCD " + + "LEFT JOIN (" + buildStaticRuleSql("EQMN") + ") qecNoRule ON qecNoRule.STCD = eng.STCD " + + "LEFT JOIN (" + buildStaticRuleSql("EQMNMWR") + ") mwrNoRule ON mwrNoRule.STCD = eng.STCD " + + "WHERE NVL(eng.IS_DELETED, 0) = 0 " + + " AND NVL(eng.BLDSTT_CODE, 0) = 2 " + + (hasDtinFilter ? "" : " AND NVL(eng.DTIN, 0) = 1 ") + + " AND NVL(eng.RUN_STATE, 0) = 4"; + } + + private String buildDayMetricSourceSql(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + int yearOffset) { + return buildStaticAggregateSql("day", filter, paramMap, indexHolder, yearOffset); + } + + private String buildDayRunSourceSql(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + int yearOffset) { + String timeFilter = buildIntervalTmFilterCondition(filter, "run.TM", paramMap, indexHolder, yearOffset); + return "SELECT dayRun.STCD, " + + "AVG(dayRun.QI) AS QI, " + + "AVG(dayRun.QO) AS QO, " + + "AVG(dayRun.QEC) AS QEC, " + + "AVG(dayRun.RZ) AS RZ, " + + "SUM(dayRun.QI_SUM_DAY) AS QI_SUM, " + + "SUM(dayRun.QO_SUM_DAY) AS QO_SUM " + + "FROM (SELECT run.STCD, TRUNC(run.TM) AS DT, " + + "AVG(run.QI) AS QI, AVG(run.QO) AS QO, AVG(run.QEC) AS QEC, AVG(run.RZ) AS RZ, " + + "SUM(run.QI) AS QI_SUM_DAY, SUM(run.QO) AS QO_SUM_DAY " + + "FROM SD_HYDROPW_R run " + + "WHERE NVL(run.IS_DELETED, 0) = 0 " + + (StrUtil.isNotBlank(timeFilter) ? " AND " + timeFilter : "") + + " GROUP BY run.STCD, TRUNC(run.TM)) dayRun " + + "GROUP BY dayRun.STCD"; + } + private String buildHourIntervalViewSql(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) {