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 6398dbc..8256fe6 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 @@ -154,6 +154,12 @@ public class SdWTMonitorController { return ResponseResult.successData(this.alongListService.getYearList(dataSourceRequest)); } + @PostMapping("/yearDetail/GetKendoListCust") + @Operation(summary = "水温年内分布二级列表") + public ResponseResult getYearDetailList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(sdWtMonitorService.getYearDetailList(dataSourceRequest)); + } + @PostMapping("/evnmAutoMonitor/GetKendoListCust") @Operation(summary = "查询水温监测数量") diff --git a/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdYearDetailVO.java b/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdYearDetailVO.java new file mode 100644 index 0000000..1ba9314 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/wt/entity/vo/SdYearDetailVO.java @@ -0,0 +1,50 @@ +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 SdYearDetailVO { + + @Schema(description = "站码") + private String stcd; + + @Schema(description = "站名") + private String stnm; + + @Schema(description = "时间") + private Date dt; + + @Schema(description = "月份排序值") + private Integer monthInt; + + @Schema(description = "月份") + private String month; + + @Schema(description = "实测值水温") + private BigDecimal actualTemp; + + @Schema(description = "水温") + private BigDecimal wt; + + @Schema(description = "天然水温") + private BigDecimal naturalTemp; + + @Schema(description = "天然水温累计值") + private BigDecimal sumVal; + + @Schema(description = "天然水温累计条数") + private Integer sumCount; + + @Schema(description = "类型") + private String sttp; + + @Schema(description = "去年同期") + private BigDecimal beforeWt; +} 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 f4b2059..e1f417b 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,6 +3,7 @@ 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.RstcdTreeInfoVo; +import com.yfd.platform.env.wt.entity.vo.SdYearDetailVO; import com.yfd.platform.env.wt.entity.vo.WbsbVo; import com.yfd.platform.env.wt.entity.vo.WtrvVo; @@ -22,5 +23,7 @@ public interface SdWtMonitorService { DataSourceResult getWbsbList(DataSourceRequest dataSourceRequest); + DataSourceResult getYearDetailList(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 2588eeb..468b4b5 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 @@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.yfd.platform.common.*; 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.SdYearDetailVO; import com.yfd.platform.env.wt.entity.vo.SdWtBaseInfoVO; import com.yfd.platform.env.wt.entity.vo.SdWtMonitorCountVO; import com.yfd.platform.env.wt.entity.vo.WbsbVo; @@ -125,6 +126,48 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { return result; } + @Override + public DataSourceResult getYearDetailList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String dt = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "dt"); + Integer month = extractMonth(dt); + + Map paramMap = new HashMap<>(); + if (month != null) { + paramMap.put("month", month); + } + + StringBuilder sql = new StringBuilder(buildYearDetailBaseSql(month != null)); + String filterSql = buildYearDetailFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildYearDetailOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + Page page = buildPage(loadOptions); + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, SdYearDetailVO.class); + for (SdYearDetailVO vo : list) { + vo.setActualTemp(vo.getWt()); + if (vo.getDt() != null) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(vo.getDt()); + int monthInt = calendar.get(Calendar.MONTH) + 1; + vo.setMonthInt(monthInt); + vo.setMonth(monthInt + "月"); + } + } + + 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, " + @@ -871,6 +914,228 @@ public class SdWtMonitorServiceImpl implements SdWtMonitorService { } } + private Integer extractMonth(String dt) { + if (StrUtil.isBlank(dt) || dt.length() < 7) { + return null; + } + try { + return Integer.parseInt(dt.substring(5, 7)); + } catch (Exception ignored) { + return null; + } + } + + private String buildYearDetailBaseSql(boolean hasMonth) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT t.STCD AS stcd, ") + .append("t.STNM AS stnm, ") + .append("t.DT AS dt, ") + .append("t.WT AS wt, ") + .append("t.STTP AS sttp, ") + .append("t.SUMVAL AS sumVal, ") + .append("t.SUMCOUNT AS sumCount, ") + .append("t.BEFOREWT AS beforeWt, ") + .append("t.NATURALTEMP AS naturalTemp ") + .append("FROM (") + .append(" SELECT dayData.STCD, ") + .append(" wt.STNM, ") + .append(" wt.RSTCD, ") + .append(" dayData.DT, ") + .append(" dayData.WT, ") + .append(" np.WT AS naturalTemp, ") + .append(" 'WT' AS sttp, ") + .append(" (SELECT SUM(np2.WT) FROM SD_WTNP_B np2 ") + .append(" WHERE NVL(np2.IS_DELETED, 0) = 0 ") + .append(" AND np2.STCD = dayData.STCD) AS sumVal, ") + .append(" (SELECT COUNT(1) FROM SD_WTNP_B np2 ") + .append(" WHERE NVL(np2.IS_DELETED, 0) = 0 ") + .append(" AND np2.STCD = dayData.STCD) AS sumCount, ") + .append(" (SELECT prev.WT FROM SD_WTRVDAY_S prev ") + .append(" WHERE NVL(prev.IS_DELETED, 0) = 0 ") + .append(" AND prev.STCD = dayData.STCD ") + .append(" AND prev.DT = ADD_MONTHS(dayData.DT, -12)) AS beforeWt ") + .append(" FROM SD_WTRVDAY_S dayData ") + .append(" INNER JOIN SD_WT_B_H wt ON wt.STCD = dayData.STCD ") + .append(" AND wt.STTP = 'WTRV' ") + .append(" AND NVL(wt.IS_DELETED, 0) = 0 ") + .append(" LEFT JOIN ("); + if (hasMonth) { + sql.append("SELECT STCD, WT FROM SD_WTNP_B ") + .append("WHERE NVL(IS_DELETED, 0) = 0 ") + .append(" AND WTTP = 1 ") + .append(" AND MNTH = #{map.month}"); + } else { + sql.append("SELECT CAST(NULL AS VARCHAR2(36)) AS STCD, CAST(NULL AS NUMBER(15,2)) AS WT FROM DUAL WHERE 1 = 2"); + } + sql.append(") np ON wt.RSTCD = np.STCD ") + .append(" WHERE NVL(dayData.IS_DELETED, 0) = 0 ") + .append(") t WHERE 1 = 1 "); + return sql.toString(); + } + + private String buildYearDetailFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (filter.getFilters() == null || filter.getFilters().isEmpty()) { + return buildYearDetailLeafCondition(filter, paramMap, indexHolder); + } + List parts = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildYearDetailFilterCondition(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 buildYearDetailLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapYearDetailColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + String paramKey = "yearDetailParam" + indexHolder[0]++; + Object value = filter.getValue(); + if ("contains".equals(operator) || "startswith".equals(operator) || "endswith".equals(operator)) { + if (value == null) { + return ""; + } + String text = String.valueOf(value); + if ("contains".equals(operator)) { + paramMap.put(paramKey, "%" + text + "%"); + } else if ("startswith".equals(operator)) { + paramMap.put(paramKey, text + "%"); + } else { + paramMap.put(paramKey, "%" + text); + } + return column + " LIKE #{map." + paramKey + "}"; + } + if ("in".equals(operator)) { + List values = splitFilterValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (String item : values) { + String itemKey = paramKey + "_" + placeholders.size(); + paramMap.put(itemKey, item); + placeholders.add("#{map." + itemKey + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + + paramMap.put(paramKey, value); + boolean dateField = "dt".equalsIgnoreCase(filter.getField()); + if ("eq".equals(operator)) { + return dateField + ? "TRUNC(" + column + ") = TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " = #{map." + paramKey + "}"; + } + if ("neq".equals(operator)) { + return dateField + ? "TRUNC(" + column + ") <> TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " <> #{map." + paramKey + "}"; + } + if ("gt".equals(operator)) { + return dateField + ? column + " > TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " > #{map." + paramKey + "}"; + } + if ("gte".equals(operator)) { + return dateField + ? column + " >= TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " >= #{map." + paramKey + "}"; + } + if ("lt".equals(operator)) { + return dateField + ? column + " < TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " < #{map." + paramKey + "}"; + } + if ("lte".equals(operator)) { + return dateField + ? column + " <= TO_DATE(SUBSTR(#{map." + paramKey + "}, 1, 10), 'YYYY-MM-DD')" + : column + " <= #{map." + paramKey + "}"; + } + return ""; + } + + private List splitFilterValues(Object value) { + if (value == null) { + return Collections.emptyList(); + } + if (value instanceof List listValue) { + List result = new ArrayList<>(); + for (Object item : listValue) { + if (item != null && StrUtil.isNotBlank(String.valueOf(item))) { + result.add(String.valueOf(item)); + } + } + return result; + } + String text = String.valueOf(value).trim(); + if (StrUtil.isBlank(text)) { + return Collections.emptyList(); + } + if (text.startsWith("[") && text.endsWith("]")) { + text = text.substring(1, text.length() - 1); + } + List result = new ArrayList<>(); + for (String item : text.split(",")) { + String trimmed = item == null ? null : item.trim(); + if (StrUtil.isNotBlank(trimmed)) { + result.add(trimmed.replace("'", "")); + } + } + return result; + } + + private String mapYearDetailColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "t.STCD"; + case "stnm" -> "t.STNM"; + case "dt" -> "t.DT"; + case "wt", "actualTemp" -> "t.WT"; + case "sttp" -> "t.STTP"; + case "sumVal" -> "t.SUMVAL"; + case "sumCount" -> "t.SUMCOUNT"; + case "beforeWt" -> "t.BEFOREWT"; + case "naturalTemp" -> "t.NATURALTEMP"; + case "rstcd" -> "t.RSTCD"; + default -> null; + }; + } + + private String buildYearDetailOrderBySql(List sortList) { + List orderColumns = new ArrayList<>(); + if (sortList != null) { + for (DataSourceRequest.SortDescriptor sortDescriptor : sortList) { + String column = mapYearDetailColumn(sortDescriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sortDescriptor.getDir()) ? "DESC" : "ASC"; + orderColumns.add(column + " " + dir); + } + } + if (orderColumns.isEmpty()) { + return " ORDER BY t.DT DESC"; + } + return " ORDER BY " + String.join(", ", orderColumns); + } + private Page buildPage(DataSourceLoadOptionsBase loadOptions) { PageInfo pageInfo = QgcQueryWrapperUtil.getPageInfo(loadOptions); if (Boolean.TRUE.equals(pageInfo.getHasPageInfo())) {