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 d5486ca4..2ff956d5 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 @@ -1,8 +1,11 @@ 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.service.EngEqDataService; +import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; +import com.yfd.platform.utils.QgcQueryWrapperUtil; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -13,7 +16,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController -@RequestMapping("/eq/data") +@RequestMapping("/eq") @Tag(name = "电站实时数据查询") @Validated public class EngEqDataController { @@ -21,9 +24,21 @@ public class EngEqDataController { @Resource private EngEqDataService engEqDataService; - @PostMapping("/GetKendoListCust") + @PostMapping("/data/GetKendoListCust") @Operation(summary = "生态流量沿程变化-小时") public ResponseResult getKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(engEqDataService.getKendoListCust(dataSourceRequest)); } + + @PostMapping("/interval/qgc/getQgcStaticData") + @Operation(summary = "生态流量达标率区间范围统计(一级页面)") + public ResponseResult getQgcStaticData(@RequestBody DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String type = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "type"); + if (!"hour".equals(type) && !"day".equals(type)) { + return ResponseResult.error("请选择生态流量达标率统计类型(小时还是天统计)"); + } + QgcQecStaticVo result = engEqDataService.getQgcStaticData(dataSourceRequest, type); + return result == null ? ResponseResult.success() : ResponseResult.successData(result); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqStaticIntervalVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqStaticIntervalVo.java new file mode 100644 index 00000000..8c66b62f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/EngEqStaticIntervalVo.java @@ -0,0 +1,21 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "生态流量区间统计中间结果") +public class EngEqStaticIntervalVo { + + @Schema(description = "电站编码") + private String stcd; + + @Schema(description = "环保部区间") + private String qecInterval; + + @Schema(description = "水利部区间") + private String mwrInterval; + + @Schema(description = "多年平均区间") + private String avqInterval; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecStaticVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecStaticVo.java new file mode 100644 index 00000000..971349d2 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecStaticVo.java @@ -0,0 +1,19 @@ +package com.yfd.platform.qgc_eng.eq.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +import java.util.List; + +@Data +@Accessors(chain = true) +@Schema(description = "生态流量达标率统计结果") +public class QgcQecStaticVo { + + @Schema(description = "参与统计电站总数") + private Integer engCnt; + + @Schema(description = "统计明细") + private List list; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecVo.java b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecVo.java new file mode 100644 index 00000000..0ef8d66b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_eng/eq/entity/vo/QgcQecVo.java @@ -0,0 +1,29 @@ +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 QgcQecVo { + + @Schema(description = "统计类型") + private Integer type; + + @Schema(description = "区间数量") + private Integer qecCnt; + + @Schema(description = "有要求的电站总数") + private Integer qecTCnt; + + @Schema(description = "区间编码") + private String code; + + @Schema(description = "区间描述") + private String desc; + + @Schema(description = "统计类型名称") + private String typeName; +} 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 58dcf45f..efa88546 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,8 +2,11 @@ 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.QgcQecStaticVo; public interface EngEqDataService { DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest); + + QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type); } 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 5bc426e8..bcc872ac 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 @@ -9,7 +9,12 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.common.GroupHelper; import com.yfd.platform.common.GroupingInfo; 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.EngEqStaticIntervalVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecStaticVo; +import com.yfd.platform.qgc_eng.eq.entity.vo.QgcQecVo; import com.yfd.platform.qgc_eng.eq.service.EngEqDataService; import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; @@ -21,6 +26,7 @@ import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Objects; @Service public class EngEqDataServiceImpl implements EngEqDataService { @@ -37,6 +43,71 @@ public class EngEqDataServiceImpl implements EngEqDataService { return queryGroupList(dataSourceRequest, loadOptions); } + @Override + public QgcQecStaticVo getQgcStaticData(DataSourceRequest dataSourceRequest, String type) { + List intervalList = queryStaticIntervals(dataSourceRequest, type); + if (CollUtil.isEmpty(intervalList)) { + return null; + } + long qecCnt = intervalList.stream() + .filter(it -> Objects.equals(it.getQecInterval(), QecIntervalEnum.QEC_STLL_1_DY95.getCode())) + .count(); + long qecTCnt = intervalList.stream() + .filter(it -> !Objects.equals(it.getQecInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode())) + .count(); + long mwrCnt = intervalList.stream() + .filter(it -> Objects.equals(it.getMwrInterval(), QecIntervalEnum.QEC_STLL_1_DY95.getCode())) + .count(); + long mwrTCnt = intervalList.stream() + .filter(it -> !Objects.equals(it.getMwrInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode())) + .count(); + long avqCnt = intervalList.stream() + .filter(it -> Objects.equals(it.getAvqInterval(), QecIntervalEnum.QEC_STLL_1_DY95.getCode())) + .count(); + long avqTCnt = intervalList.stream() + .filter(it -> !Objects.equals(it.getAvqInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode())) + .count(); + long noCnt = intervalList.stream() + .filter(it -> Objects.equals(it.getQecInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode()) + && Objects.equals(it.getMwrInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode()) + && Objects.equals(it.getAvqInterval(), QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode())) + .count(); + + List list = new ArrayList<>(); + list.add(new QgcQecVo() + .setType(ShowEnum.Q.getCode()) + .setTypeName(ShowEnum.Q.getDesc()) + .setQecCnt(Math.toIntExact(qecCnt)) + .setQecTCnt(Math.toIntExact(qecTCnt)) + .setCode(QecIntervalEnum.QEC_STLL_1_DY95.getCode()) + .setDesc(ShowEnum.Q.getDesc() + "_" + QecIntervalEnum.QEC_STLL_1_DY95.getDesc())); + list.add(new QgcQecVo() + .setType(ShowEnum.M.getCode()) + .setTypeName(ShowEnum.M.getDesc()) + .setQecCnt(Math.toIntExact(mwrCnt)) + .setQecTCnt(Math.toIntExact(mwrTCnt)) + .setCode(QecIntervalEnum.QEC_STLL_1_DY95.getCode()) + .setDesc(ShowEnum.M.getDesc() + "_" + QecIntervalEnum.QEC_STLL_1_DY95.getDesc())); + list.add(new QgcQecVo() + .setType(ShowEnum.A.getCode()) + .setTypeName(ShowEnum.A.getDesc()) + .setQecCnt(Math.toIntExact(avqCnt)) + .setQecTCnt(Math.toIntExact(avqTCnt)) + .setCode(QecIntervalEnum.QEC_STLL_1_DY95.getCode()) + .setDesc(ShowEnum.A.getDesc() + "_" + QecIntervalEnum.QEC_STLL_1_DY95.getDesc())); + list.add(new QgcQecVo() + .setType(ShowEnum.N.getCode()) + .setTypeName(ShowEnum.N.getDesc()) + .setQecCnt(Math.toIntExact(noCnt)) + .setQecTCnt(Math.toIntExact(noCnt)) + .setCode(QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode()) + .setDesc(QecIntervalEnum.QEC_STLL_6_NOEQMN.getDesc())); + + return new QgcQecStaticVo() + .setEngCnt(intervalList.size()) + .setList(list); + } + private DataSourceResult queryDetailList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -63,6 +134,44 @@ public class EngEqDataServiceImpl implements EngEqDataService { return result; } + private List queryStaticIntervals(DataSourceRequest dataSourceRequest, String type) { + StringBuilder sql = new StringBuilder(); + Map paramMap = new HashMap<>(); + sql.append("SELECT ") + .append("eng.STCD AS stcd, ") + .append(buildStaticIntervalSql("agg.QEC_RATE", "agg.QR", "qecNoRule.STCD", false)) + .append(" AS qecInterval, ") + .append(buildStaticIntervalSql("agg.MWR_RATE", "agg.MQR", "mwrNoRule.STCD", false)) + .append(" AS mwrInterval, ") + .append(buildStaticIntervalSql("agg.AVQ_RATE", "agg.AQR", "eng.AVQ", true)) + .append(" AS avqInterval ") + .append("FROM SD_ENGINFO_B_H eng ") + .append("LEFT JOIN (") + .append(buildStaticAggregateSql(type, dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0})) + .append(") agg ON agg.STCD = eng.STCD ") + .append("LEFT JOIN (") + .append(buildStaticRuleSql("EQMN")) + .append(") qecNoRule ON qecNoRule.STCD = eng.STCD ") + .append("LEFT JOIN (") + .append(buildStaticRuleSql("EQMNMWR")) + .append(") mwrNoRule ON mwrNoRule.STCD = eng.STCD ") + .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_RVCD_DIC rv ON rv.RVCD = eng.RVCD ") + .append("LEFT JOIN SD_ADDVCD_DIC addv ON addv.ADDVCD = eng.ADDVCD ") + .append("WHERE NVL(eng.IS_DELETED, 0) = 0 ") + .append(" AND NVL(eng.DTIN, 0) = 1 ") + .append(" AND NVL(eng.BLDSTT_CODE, 0) = 2 ") + .append(" AND EXISTS (SELECT 1 FROM SD_QEC_R valid WHERE valid.STCD = eng.STCD AND NVL(valid.IS_DELETED, 0) = 0) "); + + String stationFilter = buildStaticStationFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(stationFilter)) { + sql.append(" AND ").append(stationFilter).append(" "); + } + return microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, EngEqStaticIntervalVo.class); + } + private DataSourceResult queryGroupList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { StringBuilder sql = new StringBuilder(); @@ -271,6 +380,85 @@ public class EngEqDataServiceImpl implements EngEqDataService { }; } + private String buildStaticAggregateSql(String type, + DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String tableName = "day".equalsIgnoreCase(type) ? "SD_QECDAY_S" : "SD_QEC_R"; + String timeFilter = buildStaticTimeFilterCondition(filter, paramMap, indexHolder); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT data.STCD, ") + .append("(CASE WHEN SUM(CASE WHEN data.SFDB IN (0, 1) THEN 1 ELSE 0 END) = 0 THEN NULL ") + .append("ELSE (SUM(CASE WHEN data.SFDB = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN data.SFDB IN (0, 1) THEN 1 ELSE 0 END)) * 100 END) AS QEC_RATE, ") + .append("(CASE WHEN SUM(CASE WHEN data.MWR_SFDB IN (0, 1) THEN 1 ELSE 0 END) = 0 THEN NULL ") + .append("ELSE (SUM(CASE WHEN data.MWR_SFDB = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN data.MWR_SFDB IN (0, 1) THEN 1 ELSE 0 END)) * 100 END) AS MWR_RATE, ") + .append("(CASE WHEN SUM(CASE WHEN data.AVQ_SFDB IN (0, 1) THEN 1 ELSE 0 END) = 0 THEN NULL ") + .append("ELSE (SUM(CASE WHEN data.AVQ_SFDB = 1 THEN 1 ELSE 0 END) / SUM(CASE WHEN data.AVQ_SFDB IN (0, 1) THEN 1 ELSE 0 END)) * 100 END) AS AVQ_RATE, ") + .append("CASE ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.SFDB = 2 THEN 1 ELSE 0 END) THEN -1 ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.SFDB = 3 THEN 1 ELSE 0 END) THEN -2 ") + .append("WHEN SUM(CASE WHEN data.SFDB = 2 THEN 1 ELSE 0 END) > 0 ") + .append(" AND COUNT(1) = SUM(CASE WHEN data.SFDB = 2 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.SFDB = 3 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.SFDB IS NULL THEN 1 ELSE 0 END) THEN -1 ") + .append("WHEN SUM(CASE WHEN data.SFDB = 2 THEN 1 ELSE 0 END) = 0 ") + .append(" AND COUNT(1) = SUM(CASE WHEN data.SFDB = 2 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.SFDB = 3 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.SFDB IS NULL THEN 1 ELSE 0 END) THEN -2 ") + .append("END AS QR, ") + .append("CASE ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.MWR_SFDB = 2 THEN 1 ELSE 0 END) THEN -1 ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.MWR_SFDB = 3 THEN 1 ELSE 0 END) THEN -2 ") + .append("WHEN SUM(CASE WHEN data.MWR_SFDB = 2 THEN 1 ELSE 0 END) > 0 ") + .append(" AND COUNT(1) = SUM(CASE WHEN data.MWR_SFDB = 2 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.MWR_SFDB = 3 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.MWR_SFDB IS NULL THEN 1 ELSE 0 END) THEN -1 ") + .append("WHEN SUM(CASE WHEN data.MWR_SFDB = 2 THEN 1 ELSE 0 END) = 0 ") + .append(" AND COUNT(1) = SUM(CASE WHEN data.MWR_SFDB = 2 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.MWR_SFDB = 3 THEN 1 ELSE 0 END) + SUM(CASE WHEN data.MWR_SFDB IS NULL THEN 1 ELSE 0 END) THEN -2 ") + .append("END AS MQR, ") + .append("CASE ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.AVQ_SFDB = 2 THEN 1 ELSE 0 END) THEN -1 ") + .append("WHEN COUNT(1) = SUM(CASE WHEN data.AVQ_SFDB = 3 THEN 1 ELSE 0 END) THEN -2 ") + .append("END AS AQR ") + .append("FROM ").append(tableName).append(" data WHERE NVL(data.IS_DELETED, 0) = 0 "); + if (StrUtil.isNotBlank(timeFilter)) { + sql.append(" AND ").append(timeFilter).append(" "); + } + sql.append("GROUP BY data.STCD"); + return sql.toString(); + } + + private String buildStaticRuleSql(String ruleType) { + return "SELECT DISTINCT engRule.STCD " + + "FROM SD_ENGINFO_B_H engRule " + + "WHERE NVL(engRule.IS_DELETED, 0) = 0 " + + " AND NOT EXISTS ( " + + " SELECT 1 FROM MS_WARN_RULE_B rule " + + " INNER JOIN MS_WARN_RULE_DETAIL_B detail ON detail.RULE_ID = rule.ID AND NVL(detail.IS_DELETED, 0) = 0 " + + " WHERE NVL(rule.IS_DELETED, 0) = 0 AND rule.RULE_TYPE = '" + ruleType + "' AND rule.STCD = engRule.STCD " + + " )"; + } + + private String buildStaticIntervalSql(String rateColumn, + String qrColumn, + String ruleColumn, + boolean avqMode) { + if (avqMode) { + return "CASE " + + "WHEN " + ruleColumn + " IS NOT NULL AND " + rateColumn + " IS NULL THEN '" + QecIntervalEnum.QEC_STLL_5_EMPTY.getCode() + "' " + + "WHEN " + ruleColumn + " IS NULL THEN '" + QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode() + "' " + + "WHEN " + rateColumn + " >= 95 THEN '" + QecIntervalEnum.QEC_STLL_1_DY95.getCode() + "' " + + "WHEN " + rateColumn + " >= 90 AND 95 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_2_90AND95.getCode() + "' " + + "WHEN " + rateColumn + " >= 80 AND 90 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_3_80AND90.getCode() + "' " + + "WHEN 80 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_4_XY80.getCode() + "' " + + "END"; + } + return "CASE " + + "WHEN " + rateColumn + " IS NULL AND " + ruleColumn + " IS NULL THEN '" + QecIntervalEnum.QEC_STLL_5_EMPTY.getCode() + "' " + + "WHEN " + rateColumn + " IS NULL AND " + ruleColumn + " IS NOT NULL THEN '" + QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode() + "' " + + "WHEN " + qrColumn + " = -2 THEN '" + QecIntervalEnum.QEC_STLL_6_NOEQMN.getCode() + "' " + + "WHEN " + qrColumn + " = -1 THEN '" + QecIntervalEnum.QEC_STLL_5_EMPTY.getCode() + "' " + + "WHEN " + rateColumn + " >= 95 THEN '" + QecIntervalEnum.QEC_STLL_1_DY95.getCode() + "' " + + "WHEN " + rateColumn + " >= 90 AND 95 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_2_90AND95.getCode() + "' " + + "WHEN " + rateColumn + " >= 80 AND 90 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_3_80AND90.getCode() + "' " + + "WHEN 80 > " + rateColumn + " THEN '" + QecIntervalEnum.QEC_STLL_4_XY80.getCode() + "' " + + "END"; + } + private String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -376,6 +564,126 @@ public class EngEqDataServiceImpl implements EngEqDataService { }; } + private String buildStaticStationFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildStaticStationLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildStaticStationFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildStaticStationLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapStaticStationColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + return buildGenericCondition(column, filter, paramMap, indexHolder, false); + } + + private String buildStaticTimeFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + if (!"tm".equalsIgnoreCase(filter.getField())) { + return ""; + } + return buildGenericCondition("data.TM", filter, paramMap, indexHolder, true); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildStaticTimeFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildGenericCondition(String column, + DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder, + boolean dateField) { + 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"; + } + if ("in".equals(operator)) { + List values = normalizeValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "staticParam" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add(buildEqValueExpr(key, dateField, item)); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "staticParam" + indexHolder[0]++; + paramMap.put(key, value); + String valueExpr = buildEqValueExpr(key, dateField, value); + return switch (operator) { + case "eq" -> column + " = " + valueExpr; + case "neq" -> column + " <> " + valueExpr; + case "contains" -> { + paramMap.put(key, "%" + value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, value + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + value); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> column + " > " + valueExpr; + case "gte" -> column + " >= " + valueExpr; + case "lt" -> column + " < " + valueExpr; + case "lte" -> column + " <= " + valueExpr; + default -> ""; + }; + } + private boolean isEqDateField(String field) { return "tm".equalsIgnoreCase(field); } @@ -418,6 +726,27 @@ public class EngEqDataServiceImpl implements EngEqDataService { return values; } + private String mapStaticStationColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "type", "tm" -> null; + case "baseName" -> "hb.BASENAME"; + case "stnm", "ennm" -> "eng.ENNM"; + case "baseId" -> "eng.BASE_ID"; + case "rvcdName" -> "rv.RVNM"; + case "addvcdName" -> "addv.ADDVNM"; + case "stcd" -> "eng.STCD"; + case "hbrvcd" -> "eng.HBRVCD"; + case "hbrvcdName" -> "hbrv.HBRVNM"; + case "hycd" -> "eng.HYCD"; + case "rvcd" -> "eng.RVCD"; + case "bldsttCcode" -> "eng.BLDSTT_CODE"; + default -> null; + }; + } + private String mapEqColumn(String field) { if (StrUtil.isBlank(field)) { return null;