diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index 283b05d..453c5b0 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -79,7 +79,7 @@ public class SwaggerConfig { @Bean public GroupedOpenApi groupEnvFPApi() { return GroupedOpenApi.builder() - .group("3.2 全过程-生态环保数据服务-过鱼设施") + .group("3.3 全过程-生态环保数据服务-过鱼设施") .packagesToScan("com.yfd.platform.env.fp.controller") .build(); } @@ -87,7 +87,7 @@ public class SwaggerConfig { @Bean public GroupedOpenApi groupEnvFHApi() { return GroupedOpenApi.builder() - .group("3.2 全过程-生态环保数据服务-栖息地") + .group("3.4 全过程-生态环保数据服务-栖息地") .packagesToScan("com.yfd.platform.env.fh.controller") .build(); } diff --git a/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java b/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java index e881489..e33b271 100644 --- a/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java +++ b/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java @@ -1,5 +1,6 @@ package com.yfd.platform.env.fh.controller; +import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.config.ResponseResult; import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; import com.yfd.platform.env.fh.service.FhHabitatService; @@ -21,6 +22,18 @@ public class FhHabitatController { @Resource private FhHabitatService fhHabitatService; + @PostMapping("/GetKendoListCust") + @Operation(summary = "栖息地主列表") + public ResponseResult getKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fhHabitatService.getKendoListCust(dataSourceRequest)); + } + + @PostMapping("/GetKendoListCustom") + @Operation(summary = "栖息地河段自动监测情况统计和二级页") + public ResponseResult getKendoListCustom(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fhHabitatService.getKendoListCustom(dataSourceRequest)); + } + @PostMapping("/default/getFhList") @Operation(summary = "获取默认有数据的栖息地站点信息") public ResponseResult getDefaultFhList(@RequestBody FhDefaultAo fhDefaultAo) { diff --git a/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/HabitatVo.java b/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/HabitatVo.java new file mode 100644 index 0000000..876b478 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/HabitatVo.java @@ -0,0 +1,114 @@ +package com.yfd.platform.env.fh.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +@Data +@Schema(description = "栖息地河段自动监测情况") +public class HabitatVo { + + @Schema(description = "栖息地编码") + private String fhstcd; + + @Schema(description = "基地ID") + private String baseId; + + @Schema(description = "类型编码") + private String sttpCode; + + @Schema(description = "栖息地名称") + private String fhstnm; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "水电站名称") + private String ennm; + + @Schema(description = "基础对象编码") + private String stcd; + + @Schema(description = "电站编码") + private String rstcd; + + @Schema(description = "基础对象名称") + private String stnm; + + @Schema(description = "是否开展监测") + private Integer fhmonitor; + + @Schema(description = "建设阶段") + private Integer bldstt; + + @Schema(description = "保护对象") + private String qxdbhdx; + + @Schema(description = "保护范围") + private String qxdbhfw; + + @Schema(description = "保护长度") + private BigDecimal qxdbhcd; + + @Schema(description = "保护面积") + private BigDecimal qxdbhmj; + + @Schema(description = "保护河流") + private String bhhl; + + @Schema(description = "保护河段") + private String bhhd; + + @Schema(description = "保护措施") + private String bhcs; + + @Schema(description = "保护方式") + private String qxdbhfs; + + @Schema(description = "开工日期") + private Date ststdt; + + @Schema(description = "建成日期") + private Date esstdt; + + @Schema(description = "监测方式") + private Integer mway; + + @Schema(description = "是否接入") + private Integer dtin; + + @Schema(description = "数据来源") + private String vlsr; + + @Schema(description = "数据接入类型") + private Integer dtinType; + + @Schema(description = "是否启用") + private Integer enable; + + @Schema(description = "保护核心长度") + private BigDecimal qxdbhhxcd; + + @Schema(description = "保护外围长度") + private BigDecimal qxdbhwwcd; + + @Schema(description = "数据监测频次") + private Integer dtfrqcy; + + @Schema(description = "投资") + private BigDecimal qxdinv; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "站点排序") + private Integer siteStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; +} diff --git a/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java b/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java index f4c287f..2b6206c 100644 --- a/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java +++ b/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java @@ -1,9 +1,16 @@ package com.yfd.platform.env.fh.service; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; import com.yfd.platform.env.fh.entity.vo.FhDefaultVo; +import com.yfd.platform.env.fh.entity.vo.HabitatVo; public interface FhHabitatService { + DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest); + + DataSourceResult getKendoListCustom(DataSourceRequest dataSourceRequest); + FhDefaultVo getDefaultFhList(FhDefaultAo fhDefaultAo); } diff --git a/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java index 1d6e819..9d49a57 100644 --- a/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java @@ -2,18 +2,31 @@ package com.yfd.platform.env.fh.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; +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.PageInfo; import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; import com.yfd.platform.env.fh.entity.vo.FhDefaultVo; +import com.yfd.platform.env.fh.entity.vo.HabitatVo; import com.yfd.platform.env.fh.service.FhHabitatService; +import com.yfd.platform.utils.QgcQueryWrapperUtil; import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; @Service public class FhHabitatServiceImpl implements FhHabitatService { @@ -21,6 +34,76 @@ public class FhHabitatServiceImpl implements FhHabitatService { @Resource private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + @Override + public DataSourceResult getKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + StringBuilder sql = new StringBuilder(buildCustBaseSql()); + Map paramMap = new HashMap<>(); + appendCustFilterSql(sql, dataSourceRequest.getFilter(), paramMap); + + GroupingInfo[] groups = loadOptions.getGroup(); + if (groups != null && groups.length > 0) { + String groupSql = buildGroupSql(sql.toString(), groups); + List> groupRows = microservicDynamicSQLMapper.pageAllList(null, groupSql, paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(groupRows, Arrays.asList(groups))); + } else { + result.setData((List) (List) new GroupHelper().group(groupRows, Arrays.asList(groups))); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + sql.append(buildCustOrderBySql(dataSourceRequest.getSort())); + PageInfo pageInfo = QgcQueryWrapperUtil.getPageInfo(loadOptions); + Page page = pageInfo.getHasPageInfo() ? pageInfo.getPage() : null; + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, HabitatVo.class); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + @Override + public DataSourceResult getKendoListCustom(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + StringBuilder sql = new StringBuilder(buildCustomBaseSql()); + Map paramMap = new HashMap<>(); + appendFilterSql(sql, dataSourceRequest.getFilter(), paramMap); + + GroupingInfo[] groups = loadOptions.getGroup(); + if (groups != null && groups.length > 0) { + String groupSql = buildGroupSql(sql.toString(), groups); + List> groupRows = microservicDynamicSQLMapper.pageAllList(null, groupSql, paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData((List) (List) new GroupHelper().faltGroup(groupRows, Arrays.asList(groups))); + } else { + result.setData((List) (List) new GroupHelper().group(groupRows, Arrays.asList(groups))); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + sql.append(buildOrderBySql(dataSourceRequest.getSort())); + Page page = null; + if (QgcQueryWrapperUtil.getPageInfo(loadOptions).getHasPageInfo()) { + page = QgcQueryWrapperUtil.getPageInfo(loadOptions).getPage(); + } + + List list = microservicDynamicSQLMapper.pageAllListWithResultType(page, sql.toString(), paramMap, HabitatVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public FhDefaultVo getDefaultFhList(FhDefaultAo fhDefaultAo) { Map paramMap = new LinkedHashMap<>(); @@ -146,4 +229,668 @@ public class FhHabitatServiceImpl implements FhHabitatService { sql.append("ORDER BY t.fhstcd, t.sttpCode, t.dataStatus DESC"); return sql.toString(); } + + private String buildCustomBaseSql() { + return "SELECT fh.STCD AS fhstcd, " + + " NVL(fh.BASE_ID, eng.BASE_ID) AS baseId, " + + " 'FH' AS sttpCode, " + + " fh.STNM AS fhstnm, " + + " hb.BASENAME AS baseName, " + + " eng.ENNM AS ennm, " + + " fh.STCD AS stcd, " + + " fh.RSTCD AS rstcd, " + + " fh.STNM AS stnm, " + + " CASE WHEN monitor.FHSTCD IS NULL THEN 0 ELSE 1 END AS fhmonitor, " + + " fh.BLPRD AS bldstt, " + + " fh.BHDX AS qxdbhdx, " + + " fh.BHFW AS qxdbhfw, " + + " fh.BHCD AS qxdbhcd, " + + " fh.BHMJ AS qxdbhmj, " + + " fh.BHHL AS bhhl, " + + " fh.BHHD AS bhhd, " + + " fh.BHCS AS bhcs, " + + " fh.BHFS AS qxdbhfs, " + + " fh.ATTM AS ststdt, " + + " fh.ATTM AS esstdt, " + + " CAST(NULL AS NUMBER(10)) AS mway, " + + " fh.DTIN AS dtin, " + + " fh.VLSR AS vlsr, " + + " CAST(NULL AS NUMBER(10)) AS dtinType, " + + " fh.USFL AS enable, " + + " fh.BHHXCD AS qxdbhhxcd, " + + " fh.BHWWCD AS qxdbhwwcd, " + + " fh.DTFRQCY AS dtfrqcy, " + + " fh.INV AS qxdinv, " + + " hb.ORDER_INDEX AS baseStepSort, " + + " rstAlong.SORT AS rstcdStepSort, " + + " fh.ORDER_INDEX AS siteStepSort, " + + " along.ORDER_INDEX AS rvcdStepSort " + + "FROM SD_FHBT_B_H fh " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fh.RSTCD " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) " + + "LEFT JOIN MS_ALONG_B along ON along.RVCD = NVL(fh.HBRVCD, eng.HBRVCD) AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 " + + "LEFT JOIN ( " + + " SELECT det.SORT, a.RVCD, det.STCD " + + " FROM MS_ALONGDET_B det " + + " INNER JOIN MS_ALONG_B a ON a.ID = det.ALONG_ID " + + " WHERE NVL(det.IS_DELETED, 0) = 0 " + + " AND NVL(a.IS_DELETED, 0) = 0 " + + " AND a.CODE = 'common' " + + ") rstAlong ON rstAlong.RVCD = NVL(fh.HBRVCD, eng.HBRVCD) AND rstAlong.STCD = fh.RSTCD " + + "LEFT JOIN ( " + + " SELECT DISTINCT FHSTCD " + + " FROM ( " + + " SELECT FHSTCD FROM SD_RIVER_B_H WHERE STTP = 'ZQ' AND NVL(IS_DELETED, 0) = 0 AND FHSTCD IS NOT NULL " + + " UNION ALL " + + " SELECT FHSTCD FROM SD_WT_B_H WHERE STTP = 'WTRV' AND NVL(IS_DELETED, 0) = 0 AND FHSTCD IS NOT NULL " + + " UNION ALL " + + " SELECT FHSTCD FROM SD_WQ_B_H WHERE NVL(IS_DELETED, 0) = 0 AND FHSTCD IS NOT NULL " + + " ) t " + + ") monitor ON monitor.FHSTCD = fh.STCD " + + "WHERE NVL(fh.IS_DELETED, 0) = 0 "; + } + + private String buildCustBaseSql() { + String monitorSql = buildCustMonitorSql(); + return "SELECT t.FHSTCD AS fhstcd, " + + " t.BASE_ID AS baseId, " + + " t.STTP_CODE AS sttpCode, " + + " t.FHSTNM AS fhstnm, " + + " t.BASE_NAME AS baseName, " + + " t.ENNM AS ennm, " + + " t.STCD AS stcd, " + + " t.RSTCD AS rstcd, " + + " t.STNM AS stnm, " + + " t.FHMONITOR AS fhmonitor, " + + " t.BLDSTT AS bldstt, " + + " t.QXDBHDX AS qxdbhdx, " + + " t.QXDBHFW AS qxdbhfw, " + + " t.QXDBHCD AS qxdbhcd, " + + " t.QXDBHMJ AS qxdbhmj, " + + " t.BHHL AS bhhl, " + + " t.BHHD AS bhhd, " + + " t.BHCS AS bhcs, " + + " t.QXDBHFS AS qxdbhfs, " + + " t.STSTDT AS ststdt, " + + " t.ESSTDT AS esstdt, " + + " t.MWAY AS mway, " + + " t.DTIN AS dtin, " + + " t.VLSR AS vlsr, " + + " t.DTIN_TYPE AS dtinType, " + + " t.ENABLE AS enable, " + + " t.QXDBHHXCD AS qxdbhhxcd, " + + " t.QXDBHWWCD AS qxdbhwwcd, " + + " t.DTFRQCY AS dtfrqcy, " + + " t.QXDINV AS qxdinv, " + + " t.BASESTEPSORT AS baseStepSort, " + + " t.RSTCDSTEPSORT AS rstcdStepSort, " + + " t.SITESTEPSORT AS siteStepSort, " + + " t.RVCDSTEPSORT AS rvcdStepSort " + + "FROM ( " + + " SELECT child.STCD AS STCD, " + + " child.STNM AS STNM, " + + " fh.STNM AS FHSTNM, " + + " child.RSTCD AS RSTCD, " + + " fh.STCD AS FHSTCD, " + + " NVL(child.BASE_ID, fh.BASE_ID) AS BASE_ID, " + + " NVL(child.BASE_NAME, fhBase.BASENAME) AS BASE_NAME, " + + " NVL(child.BASESTEPSORT, fhBase.ORDER_INDEX) AS BASESTEPSORT, " + + " child.ENNM AS ENNM, " + + " child.BLDSTT AS BLDSTT, " + + " child.ESSTDT AS ESSTDT, " + + " fh.BHDX AS QXDBHDX, " + + " fh.BHFW AS QXDBHFW, " + + " fh.BHCD AS QXDBHCD, " + + " fh.BHMJ AS QXDBHMJ, " + + " fh.BHHL AS BHHL, " + + " fh.BHHD AS BHHD, " + + " fh.BHCS AS BHCS, " + + " fh.BHFS AS QXDBHFS, " + + " NVL(child.STSTDT, fh.ATTM) AS STSTDT, " + + " child.MWAY AS MWAY, " + + " child.DTIN AS DTIN, " + + " child.VLSR AS VLSR, " + + " child.DTIN_TYPE AS DTIN_TYPE, " + + " child.ENABLE AS ENABLE, " + + " fh.BHHXCD AS QXDBHHXCD, " + + " fh.BHWWCD AS QXDBHWWCD, " + + " fh.DTFRQCY AS DTFRQCY, " + + " fh.INV AS QXDINV, " + + " child.RSTCDSTEPSORT AS RSTCDSTEPSORT, " + + " child.SITESTEPSORT AS SITESTEPSORT, " + + " child.RVCDSTEPSORT AS RVCDSTEPSORT, " + + " child.STTP_CODE AS STTP_CODE, " + + " 1 AS FHMONITOR " + + " FROM SD_FHBT_B_H fh " + + " LEFT JOIN SD_HYDROBASE fhBase ON fhBase.BASEID = fh.BASE_ID " + + " INNER JOIN ( " + monitorSql + " ) child ON child.FHSTCD = fh.STCD " + + " WHERE NVL(fh.IS_DELETED, 0) = 0 " + + " AND NVL(fh.BASE_ID, 'other') <> 'other' " + + " UNION ALL " + + " SELECT fh.STCD AS STCD, " + + " fh.STNM AS STNM, " + + " fh.STNM AS FHSTNM, " + + " fh.RSTCD AS RSTCD, " + + " fh.STCD AS FHSTCD, " + + " NVL(fh.BASE_ID, eng.BASE_ID) AS BASE_ID, " + + " hb.BASENAME AS BASE_NAME, " + + " hb.ORDER_INDEX AS BASESTEPSORT, " + + " eng.ENNM AS ENNM, " + + " fh.BLPRD AS BLDSTT, " + + " fh.ATTM AS ESSTDT, " + + " fh.BHDX AS QXDBHDX, " + + " fh.BHFW AS QXDBHFW, " + + " fh.BHCD AS QXDBHCD, " + + " fh.BHMJ AS QXDBHMJ, " + + " fh.BHHL AS BHHL, " + + " fh.BHHD AS BHHD, " + + " fh.BHCS AS BHCS, " + + " fh.BHFS AS QXDBHFS, " + + " fh.ATTM AS STSTDT, " + + " CAST(NULL AS NUMBER(10)) AS MWAY, " + + " fh.DTIN AS DTIN, " + + " fh.VLSR AS VLSR, " + + " CAST(NULL AS NUMBER(10)) AS DTIN_TYPE, " + + " fh.USFL AS ENABLE, " + + " fh.BHHXCD AS QXDBHHXCD, " + + " fh.BHWWCD AS QXDBHWWCD, " + + " fh.DTFRQCY AS DTFRQCY, " + + " fh.INV AS QXDINV, " + + " rstAlong.SORT AS RSTCDSTEPSORT, " + + " fh.ORDER_INDEX AS SITESTEPSORT, " + + " along.ORDER_INDEX AS RVCDSTEPSORT, " + + " 'FH' AS STTP_CODE, " + + " 0 AS FHMONITOR " + + " FROM SD_FHBT_B_H fh " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fh.RSTCD " + + " LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) " + + " LEFT JOIN MS_ALONG_B along ON along.RVCD = NVL(fh.HBRVCD, eng.HBRVCD) " + + " AND along.CODE = 'common' " + + " AND NVL(along.IS_DELETED, 0) = 0 " + + " LEFT JOIN ( " + + " SELECT det.SORT, a.RVCD, det.STCD " + + " FROM MS_ALONGDET_B det " + + " INNER JOIN MS_ALONG_B a ON a.ID = det.ALONG_ID " + + " WHERE NVL(det.IS_DELETED, 0) = 0 " + + " AND NVL(a.IS_DELETED, 0) = 0 " + + " AND a.CODE = 'common' " + + " ) rstAlong ON rstAlong.RVCD = NVL(fh.HBRVCD, eng.HBRVCD) AND rstAlong.STCD = fh.RSTCD " + + " WHERE NVL(fh.IS_DELETED, 0) = 0 " + + " AND NVL(fh.BASE_ID, 'other') <> 'other' " + + " AND NOT EXISTS ( " + + " SELECT 1 FROM ( " + monitorSql + " ) child WHERE child.FHSTCD = fh.STCD " + + " ) " + + ") t WHERE 1 = 1 "; + } + + private String buildCustMonitorSql() { + String alongSql = " 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, a.RVCD, det.STCD " + + " FROM MS_ALONGDET_B det " + + " INNER JOIN MS_ALONG_B a ON a.ID = det.ALONG_ID " + + " WHERE NVL(det.IS_DELETED, 0) = 0 " + + " AND NVL(a.IS_DELETED, 0) = 0 " + + " AND a.CODE = 'common' " + + " ) rstAlong ON rstAlong.RVCD = eng.HBRVCD AND rstAlong.STCD = childBase.RSTCD "; + return "SELECT childBase.STCD, " + + " childBase.STNM, " + + " childBase.FHSTCD, " + + " childBase.RSTCD, " + + " eng.BASE_ID, " + + " hb.BASENAME AS BASE_NAME, " + + " hb.ORDER_INDEX AS BASESTEPSORT, " + + " eng.ENNM, " + + " childBase.BLDSTT, " + + " childBase.ESSTDT, " + + " eng.PSTSTDT AS STSTDT, " + + " childBase.MWAY, " + + " childBase.DTIN, " + + " childBase.VLSR, " + + " childBase.DTIN_TYPE, " + + " childBase.ENABLE, " + + " rstAlong.SORT AS RSTCDSTEPSORT, " + + " childBase.SITESTEPSORT, " + + " along.ORDER_INDEX AS RVCDSTEPSORT, " + + " childBase.STTP_CODE " + + " FROM ( " + + " SELECT wt.STCD, wt.STNM, wt.FHSTCD, wt.RSTCD, wt.BLDSTT_CODE AS BLDSTT, wt.JCDT AS ESSTDT, " + + " wt.MWAY, wt.DTIN, wt.VLSR, wt.DTIN_TYPE, wt.USFL AS ENABLE, wt.ORDER_INDEX AS SITESTEPSORT, " + + " 'WTRV' AS STTP_CODE " + + " FROM SD_WT_B_H wt " + + " WHERE NVL(wt.IS_DELETED, 0) = 0 " + + " AND wt.STTP = 'WTRV' " + + " AND wt.FHSTCD IS NOT NULL " + + " UNION ALL " + + " SELECT river.STCD, river.STNM, river.FHSTCD, river.RSTCD, river.BLDSTT_CODE AS BLDSTT, river.JCDT AS ESSTDT, " + + " river.MWAY, river.DTIN, river.VLSR, river.DTIN_TYPE, river.USFL AS ENABLE, river.ORDER_INDEX AS SITESTEPSORT, " + + " 'ZQ' AS STTP_CODE " + + " FROM SD_RIVER_B_H river " + + " WHERE NVL(river.IS_DELETED, 0) = 0 " + + " AND river.STTP = 'ZQ' " + + " AND river.FHSTCD IS NOT NULL " + + " UNION ALL " + + " SELECT wq.STCD, wq.STNM, wq.FHSTCD, wq.RSTCD, wq.BLDSTT_CODE AS BLDSTT, wq.JCDT AS ESSTDT, " + + " wq.MWAY, wq.DTIN, wq.VLSR, wq.DTIN_TYPE, wq.USFL AS ENABLE, wq.ORDER_INDEX AS SITESTEPSORT, " + + " 'WQ' AS STTP_CODE " + + " FROM SD_WQ_B_H wq " + + " WHERE NVL(wq.IS_DELETED, 0) = 0 " + + " AND wq.FHSTCD IS NOT NULL " + + " ) childBase " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = childBase.RSTCD " + + " LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = eng.BASE_ID " + + alongSql; + } + + private void appendCustFilterSql(StringBuilder sql, + DataSourceRequest.FilterDescriptor filter, + Map paramMap) { + if (filter == null) { + return; + } + String condition = buildCustFilterCondition(filter, paramMap, new int[]{0}); + if (StrUtil.isNotBlank(condition)) { + sql.append(" AND ").append(condition); + } + } + + private String buildCustFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildCustLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childCondition = buildCustFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childCondition)) { + conditions.add("(" + childCondition + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = StrUtil.blankToDefault(filter.getLogic(), "and").trim().toUpperCase(); + return String.join(" " + logic + " ", conditions); + } + + private String buildCustLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapCustFilterColumn(filter.getField()); + if (column == null) { + 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"; + } + if ("doesnotcontain".equals(operator)) { + String paramKey = "p" + indexHolder[0]++; + paramMap.put(paramKey, "%" + value + "%"); + return "(" + column + " IS NULL OR " + column + " NOT LIKE #{map." + paramKey + "})"; + } + if ("in".equals(operator) || "ni".equals(operator)) { + List values = normalizeFilterValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String paramKey = "p" + indexHolder[0]++; + paramMap.put(paramKey, item); + placeholders.add("#{map." + paramKey + "}"); + } + String inSql = column + " IN (" + String.join(", ", placeholders) + ")"; + return "ni".equals(operator) ? "NOT (" + inSql + ")" : inSql; + } + + String paramKey = "p" + 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 "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 + "}"; + case "contains": + paramMap.put(paramKey, "%" + value + "%"); + return column + " LIKE #{map." + paramKey + "}"; + case "startswith": + paramMap.put(paramKey, value + "%"); + return column + " LIKE #{map." + paramKey + "}"; + case "endswith": + paramMap.put(paramKey, "%" + value); + return column + " LIKE #{map." + paramKey + "}"; + default: + return ""; + } + } + + private List normalizeFilterValues(Object value) { + if (value == null) { + return new ArrayList<>(); + } + if (value instanceof List list) { + return new ArrayList<>(list); + } + String valueStr = String.valueOf(value).trim(); + if (StrUtil.isBlank(valueStr)) { + return new ArrayList<>(); + } + if (valueStr.startsWith("[") && valueStr.endsWith("]")) { + valueStr = valueStr.substring(1, valueStr.length() - 1); + } + List values = new ArrayList<>(); + for (String item : valueStr.split(",")) { + String trimmed = StrUtil.trim(item); + if (StrUtil.isBlank(trimmed)) { + continue; + } + values.add(StrUtil.removeAll(trimmed, "\"")); + + } + return values; + } + + private String mapCustFilterColumn(String field) { + Map columnMap = new HashMap<>(); + columnMap.put("fhstcd", "t.FHSTCD"); + columnMap.put("stcd", "t.STCD"); + columnMap.put("stnm", "t.STNM"); + columnMap.put("sttpCode", "t.STTP_CODE"); + columnMap.put("baseId", "t.BASE_ID"); + columnMap.put("fhstnm", "t.FHSTNM"); + columnMap.put("baseName", "t.BASE_NAME"); + columnMap.put("ennm", "t.ENNM"); + columnMap.put("bldstt", "t.BLDSTT"); + columnMap.put("esstdt", "t.ESSTDT"); + columnMap.put("qxdbhdx", "t.QXDBHDX"); + columnMap.put("qxdbhfw", "t.QXDBHFW"); + columnMap.put("qxdbhcd", "t.QXDBHCD"); + columnMap.put("qxdbhmj", "t.QXDBHMJ"); + columnMap.put("bhhl", "t.BHHL"); + columnMap.put("bhhd", "t.BHHD"); + columnMap.put("bhcs", "t.BHCS"); + columnMap.put("qxdbhfs", "t.QXDBHFS"); + columnMap.put("ststdt", "t.STSTDT"); + columnMap.put("mway", "t.MWAY"); + columnMap.put("dtin", "t.DTIN"); + columnMap.put("vlsr", "t.VLSR"); + columnMap.put("dtinType", "t.DTIN_TYPE"); + columnMap.put("enable", "t.ENABLE"); + columnMap.put("qxdbhhxcd", "t.QXDBHHXCD"); + columnMap.put("qxdbhwwcd", "t.QXDBHWWCD"); + columnMap.put("dtfrqcy", "t.DTFRQCY"); + columnMap.put("qxdinv", "t.QXDINV"); + columnMap.put("fhmonitor", "t.FHMONITOR"); + columnMap.put("rstcdStepSort", "t.RSTCDSTEPSORT"); + columnMap.put("siteStepSort", "t.SITESTEPSORT"); + columnMap.put("rstcd", "t.RSTCD"); + columnMap.put("rvcdStepSort", "t.RVCDSTEPSORT"); + columnMap.put("baseStepSort", "t.BASESTEPSORT"); + return columnMap.get(field); + } + + private String buildCustOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY t.BASESTEPSORT ASC, t.RVCDSTEPSORT ASC, t.RSTCDSTEPSORT ASC, t.SITESTEPSORT ASC, t.STCD ASC"; + } + Map sortMap = new HashMap<>(); + sortMap.put("fhstcd", "t.FHSTCD"); + sortMap.put("stcd", "t.STCD"); + sortMap.put("stnm", "t.STNM"); + sortMap.put("sttpCode", "t.STTP_CODE"); + sortMap.put("baseId", "t.BASE_ID"); + sortMap.put("fhstnm", "t.FHSTNM"); + sortMap.put("baseName", "t.BASE_NAME"); + sortMap.put("ennm", "t.ENNM"); + sortMap.put("bldstt", "t.BLDSTT"); + sortMap.put("esstdt", "t.ESSTDT"); + sortMap.put("ststdt", "t.STSTDT"); + sortMap.put("mway", "t.MWAY"); + sortMap.put("dtin", "t.DTIN"); + sortMap.put("vlsr", "t.VLSR"); + sortMap.put("dtinType", "t.DTIN_TYPE"); + sortMap.put("enable", "t.ENABLE"); + sortMap.put("fhmonitor", "t.FHMONITOR"); + sortMap.put("dtfrqcy", "t.DTFRQCY"); + sortMap.put("qxdinv", "t.QXDINV"); + sortMap.put("rstcdStepSort", "t.RSTCDSTEPSORT"); + sortMap.put("siteStepSort", "t.SITESTEPSORT"); + sortMap.put("rstcd", "t.RSTCD"); + sortMap.put("rvcdStepSort", "t.RVCDSTEPSORT"); + sortMap.put("baseStepSort", "t.BASESTEPSORT"); + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || !Boolean.TRUE.equals(sort.getNeedSortFlag())) { + continue; + } + String column = sortMap.get(sort.getField()); + if (column == null) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + direction); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.BASESTEPSORT ASC, t.RVCDSTEPSORT ASC, t.RSTCDSTEPSORT ASC, t.SITESTEPSORT ASC, t.STCD ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private void appendFilterSql(StringBuilder sql, + DataSourceRequest.FilterDescriptor filter, + Map paramMap) { + if (filter == null) { + return; + } + String condition = buildFilterCondition(filter, paramMap, new int[]{0}); + if (StrUtil.isNotBlank(condition)) { + sql.append(" AND ").append(condition); + } + } + + private String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childCondition = buildFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childCondition)) { + conditions.add("(" + childCondition + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = StrUtil.blankToDefault(filter.getLogic(), "and").trim().toUpperCase(); + return String.join(" " + logic + " ", conditions); + } + + private String buildLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapFilterColumn(filter.getField()); + if (column == null) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + String paramKey = "p" + 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 "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 + "}"; + case "contains": + paramMap.put(paramKey, "%" + value + "%"); + return column + " LIKE #{map." + paramKey + "}"; + case "startswith": + paramMap.put(paramKey, value + "%"); + return column + " LIKE #{map." + paramKey + "}"; + case "endswith": + paramMap.put(paramKey, "%" + value); + return column + " LIKE #{map." + paramKey + "}"; + case "isnull": + return column + " IS NULL"; + case "isnotnull": + return column + " IS NOT NULL"; + default: + return ""; + } + } + + private String mapFilterColumn(String field) { + Map columnMap = new HashMap<>(); + columnMap.put("fhstcd", "fh.STCD"); + columnMap.put("baseId", "NVL(fh.BASE_ID, eng.BASE_ID)"); + columnMap.put("sttpCode", "'FH'"); + columnMap.put("fhstnm", "fh.STNM"); + columnMap.put("baseName", "hb.BASENAME"); + columnMap.put("ennm", "eng.ENNM"); + columnMap.put("stcd", "fh.STCD"); + columnMap.put("rstcd", "fh.RSTCD"); + columnMap.put("stnm", "fh.STNM"); + columnMap.put("fhmonitor", "CASE WHEN monitor.FHSTCD IS NULL THEN 0 ELSE 1 END"); + columnMap.put("bldstt", "fh.BLPRD"); + columnMap.put("qxdbhdx", "fh.BHDX"); + columnMap.put("qxdbhfw", "fh.BHFW"); + columnMap.put("qxdbhcd", "fh.BHCD"); + columnMap.put("qxdbhmj", "fh.BHMJ"); + columnMap.put("bhhl", "fh.BHHL"); + columnMap.put("bhhd", "fh.BHHD"); + columnMap.put("bhcs", "fh.BHCS"); + columnMap.put("qxdbhfs", "fh.BHFS"); + columnMap.put("ststdt", "fh.ATTM"); + columnMap.put("esstdt", "fh.ATTM"); + columnMap.put("dtin", "fh.DTIN"); + columnMap.put("vlsr", "fh.VLSR"); + columnMap.put("enable", "fh.USFL"); + columnMap.put("qxdbhhxcd", "fh.BHHXCD"); + columnMap.put("qxdbhwwcd", "fh.BHWWCD"); + columnMap.put("dtfrqcy", "fh.DTFRQCY"); + columnMap.put("qxdinv", "fh.INV"); + columnMap.put("baseStepSort", "hb.ORDER_INDEX"); + columnMap.put("rstcdStepSort", "rstAlong.SORT"); + columnMap.put("siteStepSort", "fh.ORDER_INDEX"); + columnMap.put("rvcdStepSort", "along.ORDER_INDEX"); + return columnMap.get(field); + } + + private String buildOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY hb.ORDER_INDEX ASC, along.ORDER_INDEX ASC, rstAlong.SORT ASC, fh.ORDER_INDEX ASC, fh.STCD ASC"; + } + Map sortMap = new HashMap<>(); + sortMap.put("fhstcd", "fh.STCD"); + sortMap.put("baseId", "NVL(fh.BASE_ID, eng.BASE_ID)"); + sortMap.put("sttpCode", "'FH'"); + sortMap.put("fhstnm", "fh.STNM"); + sortMap.put("baseName", "hb.BASENAME"); + sortMap.put("ennm", "eng.ENNM"); + sortMap.put("stcd", "fh.STCD"); + sortMap.put("rstcd", "fh.RSTCD"); + sortMap.put("stnm", "fh.STNM"); + sortMap.put("fhmonitor", "CASE WHEN monitor.FHSTCD IS NULL THEN 0 ELSE 1 END"); + sortMap.put("bldstt", "fh.BLPRD"); + sortMap.put("ststdt", "fh.ATTM"); + sortMap.put("esstdt", "fh.ATTM"); + sortMap.put("dtin", "fh.DTIN"); + sortMap.put("enable", "fh.USFL"); + sortMap.put("dtfrqcy", "fh.DTFRQCY"); + sortMap.put("qxdinv", "fh.INV"); + sortMap.put("baseStepSort", "hb.ORDER_INDEX"); + sortMap.put("rstcdStepSort", "rstAlong.SORT"); + sortMap.put("siteStepSort", "fh.ORDER_INDEX"); + sortMap.put("rvcdStepSort", "along.ORDER_INDEX"); + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || !Boolean.TRUE.equals(sort.getNeedSortFlag())) { + continue; + } + String column = sortMap.get(sort.getField()); + if (column == null) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + direction); + } + if (orderItems.isEmpty()) { + return " ORDER BY hb.ORDER_INDEX ASC, along.ORDER_INDEX ASC, rstAlong.SORT ASC, fh.ORDER_INDEX ASC, fh.STCD ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildGroupSql(String baseSql, GroupingInfo[] groups) { + List fields = Arrays.stream(groups) + .map(GroupingInfo::getSelector) + .filter(StrUtil::isNotBlank) + .collect(Collectors.toList()); + StringBuilder sql = new StringBuilder("SELECT "); + for (int i = 0; i < fields.size(); i++) { + if (i > 0) { + sql.append(", "); + } + sql.append(fields.get(i)); + } + for (String field : fields) { + sql.append(", COUNT(*) AS count_").append(field); + } + sql.append(" FROM (").append(baseSql).append(") T GROUP BY "); + for (int i = 0; i < fields.size(); i++) { + if (i > 0) { + sql.append(", "); + } + sql.append(fields.get(i)); + } + return sql.toString(); + } }