diff --git a/backend/src/main/java/com/yfd/platform/env/wt/controller/SdWTMonitorController.java b/backend/src/main/java/com/yfd/platform/env/wt/controller/SdWTMonitorController.java index fde5676..df94029 100644 --- a/backend/src/main/java/com/yfd/platform/env/wt/controller/SdWTMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/env/wt/controller/SdWTMonitorController.java @@ -142,6 +142,12 @@ public class SdWTMonitorController { return ResponseResult.successData(this.alongListService.getMonthKendoListCust(dataSourceRequest)); } + @PostMapping("/monthDetail/Det/GetKendoListCust") + @Operation(summary = "全过程月平均水温历史对比二级数据接口") + public ResponseResult getMonthDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(sdWtMonitorService.getMonthDetailList(dataSourceRequest)); + } + @PostMapping("/yearList/default/stcd") @Operation(summary = "获取水温年内分布默认有数据的电站") public ResponseResult getYearDefaultStcd(@RequestBody DataSourceRequest dataSourceRequest) { @@ -215,6 +221,12 @@ public class SdWTMonitorController { return ResponseResult.successData(sdWtMonitorService.getWtFishAnalysis(dataSourceRequest)); } + @PostMapping("/wtrv/fish/info/GetKendoListCust") + @Operation(summary = "鱼类产卵月份和适宜水温") + public ResponseResult getWtFishInfo(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(sdWtMonitorService.getWtFishInfo(dataSourceRequest)); + } + @GetMapping("/wtrv/getIoWtrvFlag") @Operation(summary = "根据站点编码判断是否出入水温站且关联的电站是否有垂向水温站") public ResponseResult getFlagByStcd(@RequestParam String stcd) { diff --git a/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdMonthDetailVO.java b/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdMonthDetailVO.java new file mode 100644 index 0000000..bd26e14 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdMonthDetailVO.java @@ -0,0 +1,38 @@ +package com.yfd.platform.env.wt.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; + +import java.math.BigDecimal; +import java.util.Date; + +@Getter +@Setter +@Schema(description = "月平均水温历史对比二级列表") +public class SdMonthDetailVO { + + @Schema(description = "站码") + private String stcd; + + @Schema(description = "日期") + private Date dt; + + @Schema(description = "日均水温实测值") + private BigDecimal wt; + + @Schema(description = "日均水温去年同期") + private BigDecimal beforeWt; + + @Schema(description = "天然值") + private BigDecimal actualTemp; + + @Schema(description = "站点类型") + private String sttp; + + @Schema(description = "站点类型编码") + private String sttpCode; + + @Schema(description = "站名") + private String stnm; +} diff --git a/backend/src/main/java/com/yfd/platform/env/wt/service/SdWtMonitorService.java b/backend/src/main/java/com/yfd/platform/env/wt/service/SdWtMonitorService.java index d93d0aa..7f6c164 100644 --- a/backend/src/main/java/com/yfd/platform/env/wt/service/SdWtMonitorService.java +++ b/backend/src/main/java/com/yfd/platform/env/wt/service/SdWtMonitorService.java @@ -3,7 +3,9 @@ package com.yfd.platform.env.wt.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.env.wt.entity.vo.DfltkwFacilityCountVo; +import com.yfd.platform.env.wt.entity.vo.FishSpawnVo; import com.yfd.platform.env.wt.entity.vo.RstcdTreeInfoVo; +import com.yfd.platform.env.wt.entity.vo.SdMonthDetailVO; import com.yfd.platform.env.wt.entity.vo.SdYearDetailVO; import com.yfd.platform.env.wt.entity.vo.SttpInfoVo; import com.yfd.platform.env.wt.entity.vo.WbsbVo; @@ -21,6 +23,8 @@ public interface SdWtMonitorService { DataSourceResult getWtFishAnalysis(DataSourceRequest dataSourceRequest); + DataSourceResult getWtFishInfo(DataSourceRequest dataSourceRequest); + WtrvVo getFlagByStcd(String stcd); DataSourceResult getWbsbList(DataSourceRequest dataSourceRequest); @@ -31,5 +35,7 @@ public interface SdWtMonitorService { DataSourceResult getYearDetailList(DataSourceRequest dataSourceRequest); + DataSourceResult getMonthDetailList(DataSourceRequest dataSourceRequest); + List getWtvtDefaultTreeStcd(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/env/wt/service/impl/SdWtMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/wt/service/impl/SdWtMonitorServiceImpl.java index 9061096..c4d43c1 100644 --- a/backend/src/main/java/com/yfd/platform/env/wt/service/impl/SdWtMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/wt/service/impl/SdWtMonitorServiceImpl.java @@ -6,6 +6,7 @@ import com.yfd.platform.common.*; import com.yfd.platform.env.wt.entity.vo.DfltkwFacilityCountVo; import com.yfd.platform.env.wt.entity.vo.FishSpawnVo; import com.yfd.platform.env.wt.entity.vo.RstcdTreeInfoVo; +import com.yfd.platform.env.wt.entity.vo.SdMonthDetailVO; import com.yfd.platform.env.wt.entity.vo.SdYearDetailVO; import com.yfd.platform.env.wt.entity.vo.SdWtBaseInfoVO; import com.yfd.platform.env.wt.entity.vo.SdWtMonitorCountVO; @@ -323,6 +324,40 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { return result; } + @Override + public DataSourceResult getMonthDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime"); + String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime"); + String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + Integer month = extractMonth(startTime); + + StringBuilder sql = new StringBuilder(buildMonthDetailBaseSql()); + Map paramMap = new HashMap<>(); + paramMap.put("startTime", startTime); + paramMap.put("endTime", endTime); + paramMap.put("stcd", stcd); + paramMap.put("month", month); + + String filterSql = buildMonthDetailFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildMonthDetailOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = buildPage(loadOptions); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, SdMonthDetailVO.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public WtrvVo getFlagByStcd(String stcd) { String sql = "SELECT wt.STCD AS stcd, " + @@ -423,6 +458,43 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { return result; } + @Override + public DataSourceResult getWtFishInfo(DataSourceRequest dataSourceRequest) { + DataSourceResult result = new DataSourceResult<>(); + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + if (StrUtil.isBlank(stcd)) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + String sql = "SELECT " + + "t2.ID AS id, " + + "t2.NAME AS name, " + + "t2.PRETEMP AS pretempStr, " + + "t2.SPAWN_MONTH AS spawnMonthStr " + + "FROM SD_WT_B_H t1 " + + "INNER JOIN SD_ENGINFO_B_H eng ON eng.STCD = t1.RSTCD " + + "INNER JOIN SD_FISHDICTORY_RLTN_B t3 ON eng.HBRVCD = t3.RVCD AND NVL(t3.IS_DELETED, 0) = 0 " + + "INNER JOIN SD_FISHDICTORY_B t2 ON t2.ID = t3.ZY_FISH_ID AND NVL(t2.IS_DELETED, 0) = 0 " + + "WHERE NVL(t1.IS_DELETED, 0) = 0 " + + " AND t1.STCD = #{map.stcd} " + + " AND t1.STTP = 'WTRV' " + + " AND t2.PRETEMP IS NOT NULL " + + " AND t2.SPAWN_MONTH IS NOT NULL " + + "ORDER BY NVL(t3.ORDER_INDEX, 999999), NVL(t2.ORDER_INDEX, 999999), t2.NAME"; + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + List list = microservicDynamicSQLMapper.getAllListWithResultType(sql, paramMap, FishSpawnVo.class); + fillFishSpawnInfo(list); + result.setData(list); + result.setTotal((long) list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); @@ -1082,6 +1154,56 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { } } + private String buildMonthDetailBaseSql() { + return "SELECT t.STCD AS stcd, " + + "t.STNM AS stnm, " + + "t.DT AS dt, " + + "t.WT AS wt, " + + "t.STTP AS sttp, " + + "t.STTPCODE AS sttpCode, " + + "t.BEFOREWT AS beforeWt, " + + "t.ACTUALTEMP AS actualTemp " + + "FROM ( " + + " SELECT t1.DT, " + + " t2.WT AS wt, " + + " 'WT' AS sttp, " + + " wt.STTP AS sttpCode, " + + " wt.STCD AS stcd, " + + " wt.STNM AS stnm, " + + " t3.WT AS beforeWt, " + + " np.WT AS actualTemp " + + " FROM (SELECT TRUNC(TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS')) + LEVEL - 1 AS DT " + + " FROM DUAL " + + " CONNECT BY TRUNC(TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS')) + LEVEL - 1 <= TRUNC(TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS'))) t1 " + + " LEFT JOIN (SELECT STCD, WT, DT " + + " FROM SD_WTRVDAY_S " + + " WHERE NVL(IS_DELETED, 0) = 0 " + + " AND STCD = #{map.stcd} " + + " AND DT >= TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS') " + + " AND DT <= TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS')) t2 " + + " ON t1.DT = t2.DT " + + " LEFT JOIN (SELECT STCD, WT, DT " + + " FROM SD_WTRVDAY_S " + + " WHERE NVL(IS_DELETED, 0) = 0 " + + " AND STCD = #{map.stcd} " + + " AND DT >= ADD_MONTHS(TO_DATE(#{map.startTime}, 'YYYY-MM-DD HH24:MI:SS'), -12) " + + " AND DT <= ADD_MONTHS(TO_DATE(#{map.endTime}, 'YYYY-MM-DD HH24:MI:SS'), -12)) t3 " + + " ON t1.DT = ADD_MONTHS(t3.DT, 12) " + + " LEFT JOIN SD_WT_B_H wt " + + " ON wt.STCD = #{map.stcd} " + + " AND wt.STTP = 'WTRV' " + + " AND NVL(wt.IS_DELETED, 0) = 0 " + + " LEFT JOIN (SELECT STCD, WT " + + " FROM SD_WTNP_B " + + " WHERE NVL(IS_DELETED, 0) = 0 " + + " AND WTTP = 1 " + + " AND MNTH = #{map.month}) np " + + " ON np.STCD = wt.RSTCD " + + " WHERE t1.DT <= SYSDATE " + + " AND (t2.WT IS NOT NULL OR t3.WT IS NOT NULL) " + + ") t WHERE 1 = 1 "; + } + private String buildYearDetailBaseSql(boolean hasMonth) { StringBuilder sql = new StringBuilder(); sql.append("SELECT t.STCD AS stcd, ") @@ -1293,6 +1415,110 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { return " ORDER BY " + String.join(", ", orderColumns); } + private String buildMonthDetailFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (filter.getFilters() == null || filter.getFilters().isEmpty()) { + return buildMonthDetailLeafCondition(filter, paramMap, indexHolder); + } + List parts = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildMonthDetailFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + parts.add("(" + childSql + ")"); + } + } + if (parts.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, parts); + } + + private String buildMonthDetailLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + if (StrUtil.isBlank(field) || "startTime".equals(field) || "endTime".equals(field) || "stcd".equals(field)) { + return ""; + } + String column = mapMonthDetailColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + String paramKey = "monthDetailP" + indexHolder[0]++; + switch (operator) { + case "eq": + paramMap.put(paramKey, value); + return column + " = #{map." + paramKey + "}"; + case "neq": + paramMap.put(paramKey, value); + return column + " <> #{map." + paramKey + "}"; + case "contains": + paramMap.put(paramKey, "%" + value + "%"); + return column + " LIKE #{map." + paramKey + "}"; + case "gt": + paramMap.put(paramKey, value); + return column + " > #{map." + paramKey + "}"; + case "gte": + paramMap.put(paramKey, value); + return column + " >= #{map." + paramKey + "}"; + case "lt": + paramMap.put(paramKey, value); + return column + " < #{map." + paramKey + "}"; + case "lte": + paramMap.put(paramKey, value); + return column + " <= #{map." + paramKey + "}"; + default: + return ""; + } + } + + private String mapMonthDetailColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "dt" -> "t.DT"; + case "wt" -> "t.WT"; + case "beforeWt" -> "t.BEFOREWT"; + case "actualTemp" -> "t.ACTUALTEMP"; + case "sttp" -> "t.STTP"; + case "sttpCode" -> "t.STTPCODE"; + case "stnm" -> "t.STNM"; + default -> null; + }; + } + + private String buildMonthDetailOrderBySql(List sortList) { + List orderColumns = new ArrayList<>(); + if (sortList != null) { + for (DataSourceRequest.SortDescriptor sortDescriptor : sortList) { + String column = mapMonthDetailColumn(sortDescriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sortDescriptor.getDir()) ? "DESC" : "ASC"; + orderColumns.add(column + " " + dir); + } + } + if (orderColumns.isEmpty()) { + return ""; + } + return " ORDER BY " + String.join(", ", orderColumns); + } + private String buildSttpInfoFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -1594,6 +1820,22 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { } } + private void fillFishSpawnInfo(List fishSpawnVoList) { + if (fishSpawnVoList == null || fishSpawnVoList.isEmpty()) { + return; + } + for (FishSpawnVo fishSpawnVo : fishSpawnVoList) { + BigDecimal[] range = parsePretempRange(fishSpawnVo.getPretempStr()); + if (range != null) { + List pretemp = new ArrayList<>(); + pretemp.add(range[0].stripTrailingZeros().toPlainString()); + pretemp.add(range[1].stripTrailingZeros().toPlainString()); + fishSpawnVo.setPretemp(pretemp); + } + fishSpawnVo.setSpawnMonth(parseSpawnMonthList(fishSpawnVo.getSpawnMonthStr())); + } + } + private boolean matchSpawnMonth(String spawnMonthStr, int month) { if (StrUtil.isBlank(spawnMonthStr)) { return false; @@ -1612,6 +1854,23 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { return false; } + private List parseSpawnMonthList(String spawnMonthStr) { + List result = new ArrayList<>(); + if (StrUtil.isBlank(spawnMonthStr)) { + return result; + } + for (String monthStr : spawnMonthStr.split(",")) { + if (StrUtil.isBlank(monthStr)) { + continue; + } + try { + result.add(String.format("%02d", Integer.parseInt(monthStr.trim()))); + } catch (NumberFormatException ignored) { + } + } + return result; + } + private BigDecimal[] parsePretempRange(String pretempStr) { if (StrUtil.isBlank(pretempStr)) { return null;