From bd6c3661535c4387ace898dab4b80927c024ba51 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 15 Jun 2026 09:24:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=A8=E8=BF=87=E7=A8=8B=E8=BF=87?= =?UTF-8?q?=E9=B1=BC=E8=87=AA=E5=8A=A8=E4=B8=8E=E4=BA=BA=E5=B7=A5=E7=9B=91?= =?UTF-8?q?=E6=B5=8B=E6=95=B0=E6=8D=AE=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fp/controller/FishPassageController.java | 6 + .../qgc_env/fp/entity/vo/FpFpssrlQueryVo.java | 107 ++++ .../qgc_env/fp/service/FpRunService.java | 3 + .../fp/service/impl/FpRunServiceImpl.java | 510 ++++++++++++++++++ 4 files changed, 626 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQueryVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java index a803fd10..af4d66ff 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java @@ -40,6 +40,12 @@ public class FishPassageController { return ResponseResult.successData(fpRunService.processQgcSdfpssrKendoList(dataSourceRequest)); } + @PostMapping("/query/qgc/GetKendoListCust") + @Operation(summary = "全过程过鱼自动与人工监测数据查询") + public ResponseResult getQgcFpssrlQueryKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fpRunService.processQgcFpssrlQueryKendoList(dataSourceRequest)); + } + @PostMapping("/fpssTable/qgc/GetKendoListCust") @Operation(summary = "过鱼设施监测数据查询") public ResponseResult getQgcFpssTableKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQueryVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQueryVo.java new file mode 100644 index 00000000..5094b292 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQueryVo.java @@ -0,0 +1,107 @@ +package com.yfd.platform.qgc_env.fp.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@Schema(description = "全过程过鱼自动/人工监测合并查询数据") +public class FpFpssrlQueryVo { + + @Schema(description = "数据ID") + private String id; + + @Schema(description = "过鱼年份") + private String yr; + + @Schema(description = "过鱼设施编码") + private String stcd; + + @Schema(description = "设施名称") + private String stnm; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "电站编码") + private String rstcd; + + @Schema(description = "电站名称") + private String ennm; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; + + @Schema(description = "站点排序") + private Integer siteStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "时间") + private Date tm; + + @Schema(description = "鱼类名称") + private String ftp; + + @Schema(description = "鱼类编码") + private String fishId; + + @Schema(description = "大小") + private String fsz; + + @Schema(description = "长度") + private String length; + + @Schema(description = "宽度") + private String width; + + @Schema(description = "鱼速") + private String fishspeed; + + @Schema(description = "游向") + private String direction; + + @Schema(description = "水温") + private String temperature; + + @Schema(description = "流速") + private String speed; + + @Schema(description = "通道") + private String channelno; + + @Schema(description = "数量") + private String fcnt; + + @Schema(description = "图片") + private String firstimgurl; + + @Schema(description = "视频") + private String videourl; + + @Schema(description = "监测方式") + private Integer mway; + + @Schema(description = "人工开始时间") + private Date strdt; + + @Schema(description = "人工结束时间") + private Date enddt; + + @Schema(description = "站点分类编码") + private String stCode; + + @Schema(description = "站点分类名称") + private String stName; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java index 4611c100..7a1bff34 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java @@ -3,6 +3,7 @@ package com.yfd.platform.qgc_env.fp.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.fp.entity.vo.FpFishSelectVo; +import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQueryVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisTableVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpSdfpssrVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpTableVo; @@ -17,6 +18,8 @@ public interface FpRunService { DataSourceResult processQgcSdfpssrKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processQgcFpssrlQueryKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest); DataSourceResult getAnalysisData(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java index 9f0266a2..718ecfde 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java @@ -14,6 +14,7 @@ import com.yfd.platform.common.GroupingInfo; import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.exception.BizException; import com.yfd.platform.qgc_env.fp.entity.vo.FpFishSelectVo; +import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQueryVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpFtpStatisticsVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisHeadColumnVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisTableVo; @@ -119,6 +120,15 @@ public class FpRunServiceImpl implements FpRunService { return queryQgcSdfpssrGroupList(dataSourceRequest, loadOptions); } + @Override + public DataSourceResult processQgcFpssrlQueryKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryQgcFpssrlDetailList(dataSourceRequest, loadOptions); + } + return queryQgcFpssrlGroupList(dataSourceRequest, loadOptions); + } + @Override public DataSourceResult processQgcFpssTableKendoList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -783,6 +793,106 @@ public class FpRunServiceImpl implements FpRunService { return result; } + private DataSourceResult queryQgcFpssrlDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildQgcFpssrlDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildQgcFpssrlCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildQgcFpssrlOrderBySql(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, FpFpssrlQueryVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryQgcFpssrlGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + List groups = dataSourceRequest.getGroup(); + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + + StringBuilder sql = new StringBuilder("SELECT "); + List selectItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapQgcFpssrlColumn(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 = mapQgcFpssrlColumn(aggregate.getField()); + if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) { + continue; + } + String aggregateSql = buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField()); + if (StrUtil.isNotBlank(aggregateSql)) { + selectItems.add(aggregateSql); + } + } + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + } + + sql.append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildQgcFpssrlCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcFpssrlFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + 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 = mapQgcFpssrlColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildQgcFpssrlGroupOrderBySql(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 queryQgcSdfpssrGroupList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions) { List groups = dataSourceRequest.getGroup(); @@ -911,6 +1021,160 @@ public class FpRunServiceImpl implements FpRunService { "WHERE NVL(t.IS_DELETED, 0) = 0"; } + private String buildQgcFpssrlCoreSql() { + return "SELECT " + + "src.ID AS id, " + + "src.STCD AS stcd, " + + "src.STNM AS stnm, " + + "src.BASEID AS baseId, " + + "src.BASENAME AS baseName, " + + "src.RSTCD AS rstcd, " + + "src.ENNM AS ennm, " + + "src.HBRVCD AS hbrvcd, " + + "src.BASESTEPSORT AS baseStepSort, " + + "src.RVCDSTEPSORT AS rvcdStepSort, " + + "src.SITESTEPSORT AS siteStepSort, " + + "src.RSTCDSTEPSORT AS rstcdStepSort, " + + "src.TM AS tm, " + + "src.YR AS yr, " + + "src.FTP AS ftp, " + + "src.FISHID AS fishId, " + + "src.FSZ AS fsz, " + + "src.LENGTH AS length, " + + "src.WIDTH AS width, " + + "src.FISHSPEED AS fishspeed, " + + "src.DIRECTION AS direction, " + + "src.TEMPERATURE AS temperature, " + + "src.SPEED AS speed, " + + "src.CHANNELNO AS channelno, " + + "src.FCNT AS fcnt, " + + "src.FIRSTIMGURL AS firstimgurl, " + + "src.VIDEOURL AS videourl, " + + "src.MWAY AS mway, " + + "src.STRDT AS strdt, " + + "src.ENDDT AS enddt, " + + "src.STCODE AS stCode, " + + "src.STNAME AS stName " + + "FROM ( " + + " SELECT t.ID AS ID, " + + " t.STCD AS STCD, " + + " fp.STNM AS STNM, " + + " eng.BASE_ID AS BASEID, " + + " hb.BASENAME AS BASENAME, " + + " fp.RSTCD AS RSTCD, " + + " eng.ENNM AS ENNM, " + + " eng.HBRVCD AS HBRVCD, " + + " NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " + + " NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " + + " NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " + + " NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " + + " t.TM AS TM, " + + " TO_CHAR(t.TM, 'YYYY') AS YR, " + + " COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " + + " t.FTP AS FISHID, " + + " t.FSZ AS FSZ, " + + " TO_CHAR(t.LENGTH) AS LENGTH, " + + " TO_CHAR(t.WIDTH) AS WIDTH, " + + " TO_CHAR(t.FISHSPEED) AS FISHSPEED, " + + " TO_CHAR(t.DIRECTION) AS DIRECTION, " + + " TO_CHAR(t.TEMPERATURE) AS TEMPERATURE, " + + " TO_CHAR(t.SPEED) AS SPEED, " + + " t.CHANNELNO AS CHANNELNO, " + + " TO_CHAR(t.FCNT) AS FCNT, " + + " t.FIRSTIMGURL AS FIRSTIMGURL, " + + " t.VIDEOURL AS VIDEOURL, " + + " 2 AS MWAY, " + + " CAST(NULL AS DATE) AS STRDT, " + + " CAST(NULL AS DATE) AS ENDDT, " + + " fp.STTP AS STCODE, " + + " sttp.STTP_NAME AS STNAME " + + " FROM SD_FPSSRL_R t " + + " INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD " + + " LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + " 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_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " + + " AND relRv.RVCD = eng.HBRVCD " + + " AND NVL(relRv.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " + + " AND NVL(fishRv.IS_DELETED, 0) = 0 " + + " AND NVL(fishRv.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " + + " AND relZy.RVCD = 'ZY' " + + " AND NVL(relZy.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " + + " AND NVL(fishZy.IS_DELETED, 0) = 0 " + + " AND NVL(fishZy.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " + + " AND NVL(fishDirect.IS_DELETED, 0) = 0 " + + " AND NVL(fishDirect.ENABLE, 1) = 1 " + + " WHERE NVL(t.IS_DELETED, 0) = 0 " + + " UNION ALL " + + " SELECT t.ID AS ID, " + + " t.STCD AS STCD, " + + " fp.STNM AS STNM, " + + " eng.BASE_ID AS BASEID, " + + " hb.BASENAME AS BASENAME, " + + " fp.RSTCD AS RSTCD, " + + " eng.ENNM AS ENNM, " + + " eng.HBRVCD AS HBRVCD, " + + " NVL(hb.ORDER_INDEX, 999999) AS BASESTEPSORT, " + + " NVL(hbrv.ORDER_INDEX, 999999) AS RVCDSTEPSORT, " + + " NVL(fp.ORDER_INDEX, 999999) AS SITESTEPSORT, " + + " NVL(eng.ORDER_INDEX, 999999) AS RSTCDSTEPSORT, " + + " t.STRDT AS TM, " + + " TO_CHAR(t.STRDT, 'YYYY') AS YR, " + + " COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS FTP, " + + " t.FTP AS FISHID, " + + " t.FSZ AS FSZ, " + + " CAST(NULL AS VARCHAR2(50)) AS LENGTH, " + + " CAST(NULL AS VARCHAR2(50)) AS WIDTH, " + + " CAST(NULL AS VARCHAR2(50)) AS FISHSPEED, " + + " TO_CHAR(t.DIRECTION) AS DIRECTION, " + + " CAST(NULL AS VARCHAR2(50)) AS TEMPERATURE, " + + " CAST(NULL AS VARCHAR2(50)) AS SPEED, " + + " CAST(NULL AS VARCHAR2(100)) AS CHANNELNO, " + + " TO_CHAR(t.FCNT) AS FCNT, " + + " t.PICPTH AS FIRSTIMGURL, " + + " t.VDPTH AS VIDEOURL, " + + " 1 AS MWAY, " + + " t.STRDT AS STRDT, " + + " t.ENDDT AS ENDDT, " + + " fp.STTP AS STCODE, " + + " sttp.STTP_NAME AS STNAME " + + " FROM SD_FPSS_R t " + + " INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD " + + " LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = fp.STTP AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + " 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_FISHDICTORY_RLTN_B relRv ON relRv.FISH_ID = t.FTP " + + " AND relRv.RVCD = eng.HBRVCD " + + " AND NVL(relRv.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishRv ON fishRv.ID = relRv.ZY_FISH_ID " + + " AND NVL(fishRv.IS_DELETED, 0) = 0 " + + " AND NVL(fishRv.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B relZy ON relZy.FISH_ID = t.FTP " + + " AND relZy.RVCD = 'ZY' " + + " AND NVL(relZy.IS_DELETED, 0) = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fishZy ON fishZy.ID = relZy.ZY_FISH_ID " + + " AND NVL(fishZy.IS_DELETED, 0) = 0 " + + " AND NVL(fishZy.ENABLE, 1) = 1 " + + " LEFT JOIN SD_FISHDICTORY_B fishDirect ON fishDirect.ID = t.FTP " + + " AND NVL(fishDirect.IS_DELETED, 0) = 0 " + + " AND NVL(fishDirect.ENABLE, 1) = 1 " + + " WHERE NVL(t.IS_DELETED, 0) = 0 " + +// " AND (t.TASK_STATUS = 'Approved' OR t.TASK_STATUS IS NULL) " + + ") src"; + } + private String buildQgcSdfpssrDetailSelectSql(List selectFields) { Map selectMap = new LinkedHashMap<>(); selectMap.put("stcd", "t.stcd AS stcd"); @@ -957,6 +1221,57 @@ public class FpRunServiceImpl implements FpRunService { return String.join(", ", actualColumns); } + private String buildQgcFpssrlDetailSelectSql(List selectFields) { + Map selectMap = new LinkedHashMap<>(); + selectMap.put("id", "t.id AS id"); + selectMap.put("yr", "t.yr AS yr"); + selectMap.put("stcd", "t.stcd AS stcd"); + selectMap.put("stnm", "CASE WHEN t.stName IS NULL THEN t.stnm ELSE t.stName || t.stnm END AS stnm"); + selectMap.put("baseId", "t.baseId AS baseId"); + selectMap.put("baseName", "t.baseName AS baseName"); + selectMap.put("rstcd", "t.rstcd AS rstcd"); + selectMap.put("ennm", "t.ennm AS ennm"); + selectMap.put("hbrvcd", "t.hbrvcd AS hbrvcd"); + selectMap.put("baseStepSort", "t.baseStepSort AS baseStepSort"); + selectMap.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); + selectMap.put("siteStepSort", "t.siteStepSort AS siteStepSort"); + selectMap.put("rstcdStepSort", "t.rstcdStepSort AS rstcdStepSort"); + selectMap.put("tm", "t.tm AS tm"); + selectMap.put("ftp", "t.ftp AS ftp"); + selectMap.put("fishId", "t.fishId AS fishId"); + selectMap.put("fsz", "t.fsz AS fsz"); + selectMap.put("length", "t.length AS length"); + selectMap.put("width", "t.width AS width"); + selectMap.put("fishspeed", "t.fishspeed AS fishspeed"); + selectMap.put("direction", "t.direction AS direction"); + selectMap.put("temperature", "t.temperature AS temperature"); + selectMap.put("speed", "t.speed AS speed"); + selectMap.put("channelno", "t.channelno AS channelno"); + selectMap.put("fcnt", "t.fcnt AS fcnt"); + selectMap.put("firstimgurl", "t.firstimgurl AS firstimgurl"); + selectMap.put("videourl", "t.videourl AS videourl"); + selectMap.put("mway", "t.mway AS mway"); + selectMap.put("strdt", "t.strdt AS strdt"); + selectMap.put("enddt", "t.enddt AS enddt"); + selectMap.put("stCode", "t.stCode AS stCode"); + selectMap.put("stName", "t.stName AS stName"); + + if (CollUtil.isEmpty(selectFields)) { + return String.join(", ", selectMap.values()); + } + List actualColumns = new ArrayList<>(); + for (String field : selectFields) { + String column = selectMap.get(field); + if (StrUtil.isNotBlank(column)) { + actualColumns.add(column); + } + } + if (actualColumns.isEmpty()) { + actualColumns.addAll(selectMap.values()); + } + return String.join(", ", actualColumns); + } + private String buildQgcSdfpssrFilterCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -1070,6 +1385,119 @@ public class FpRunServiceImpl implements FpRunService { }; } + private String buildQgcFpssrlFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildQgcFpssrlLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildQgcFpssrlFilterCondition(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 buildQgcFpssrlLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + + if ("keyword".equalsIgnoreCase(field)) { + if (value == null || StrUtil.isBlank(String.valueOf(value))) { + return ""; + } + String key = "fpFpssrlP" + indexHolder[0]++; + paramMap.put(key, "%" + String.valueOf(value).trim() + "%"); + return "(t.STNM LIKE #{map." + key + "} OR t.BASENAME LIKE #{map." + key + "} OR t.ENNM LIKE #{map." + key + "} OR t.FTP LIKE #{map." + key + "} OR t.FISHID LIKE #{map." + key + "})"; + } + + String column = mapQgcFpssrlColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + boolean dateField = "tm".equalsIgnoreCase(field) || "strdt".equalsIgnoreCase(field) || "enddt".equalsIgnoreCase(field); + if ("in".equals(operator)) { + List values = normalizeValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "fpFpssrlP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add(buildValueExpr(key, dateField, item)); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + + String key = "fpFpssrlP" + indexHolder[0]++; + String valueExpr = buildValueExpr(key, dateField, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, value); + yield column + " = " + valueExpr; + } + case "neq" -> { + paramMap.put(key, value); + yield 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" -> { + paramMap.put(key, value); + yield column + " > " + valueExpr; + } + case "gte" -> { + paramMap.put(key, value); + yield column + " >= " + valueExpr; + } + case "lt" -> { + paramMap.put(key, value); + yield column + " < " + valueExpr; + } + case "lte" -> { + paramMap.put(key, value); + yield column + " <= " + valueExpr; + } + default -> ""; + }; + } + private String mapQgcSdfpssrColumn(String field) { if (StrUtil.isBlank(field)) { return null; @@ -1106,6 +1534,47 @@ public class FpRunServiceImpl implements FpRunService { }; } + private String mapQgcFpssrlColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> "t.ID"; + case "yr" -> "t.YR"; + case "stcd" -> "t.STCD"; + case "stnm" -> "t.STNM"; + case "baseId" -> "t.BASEID"; + case "baseName" -> "t.BASENAME"; + case "rstcd" -> "t.RSTCD"; + case "ennm" -> "t.ENNM"; + case "hbrvcd" -> "t.HBRVCD"; + case "baseStepSort" -> "t.BASESTEPSORT"; + case "rvcdStepSort" -> "t.RVCDSTEPSORT"; + case "siteStepSort" -> "t.SITESTEPSORT"; + case "rstcdStepSort" -> "t.RSTCDSTEPSORT"; + case "tm" -> "t.TM"; + case "ftp" -> "t.FTP"; + case "fishId" -> "t.FISHID"; + case "fsz" -> "t.FSZ"; + case "length" -> "t.LENGTH"; + case "width" -> "t.WIDTH"; + case "fishspeed" -> "t.FISHSPEED"; + case "direction" -> "t.DIRECTION"; + case "temperature" -> "t.TEMPERATURE"; + case "speed" -> "t.SPEED"; + case "channelno" -> "t.CHANNELNO"; + case "fcnt" -> "t.FCNT"; + case "firstimgurl" -> "t.FIRSTIMGURL"; + case "videourl" -> "t.VIDEOURL"; + case "mway" -> "t.MWAY"; + case "strdt" -> "t.STRDT"; + case "enddt" -> "t.ENDDT"; + case "stCode" -> "t.STCODE"; + case "stName" -> "t.STNAME"; + default -> null; + }; + } + private String buildQgcSdfpssrOrderBySql(List sortList) { if (CollUtil.isEmpty(sortList)) { return " ORDER BY t.STRDT ASC, t.STCD ASC"; @@ -1128,6 +1597,28 @@ public class FpRunServiceImpl implements FpRunService { return " ORDER BY " + String.join(", ", orderColumns); } + private String buildQgcFpssrlOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY t.TM DESC NULLS LAST, t.STCD ASC"; + } + List orderColumns = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sortDescriptor : sortList) { + if (sortDescriptor == null || StrUtil.isBlank(sortDescriptor.getField())) { + continue; + } + String column = mapQgcFpssrlColumn(sortDescriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sortDescriptor.getDir()) || "des".equalsIgnoreCase(sortDescriptor.getDir()) ? "DESC" : "ASC"; + orderColumns.add(column + " " + dir + " NULLS LAST"); + } + if (orderColumns.isEmpty()) { + return " ORDER BY t.TM DESC NULLS LAST, t.STCD ASC"; + } + return " ORDER BY " + String.join(", ", orderColumns); + } + private String buildQgcSdfpssrGroupOrderBySql(List groups) { if (CollUtil.isEmpty(groups)) { return ""; @@ -1147,6 +1638,25 @@ public class FpRunServiceImpl implements FpRunService { return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); } + private String buildQgcFpssrlGroupOrderBySql(List groups) { + if (CollUtil.isEmpty(groups)) { + return ""; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapQgcFpssrlColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + dir); + } + return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); + } + private String buildAggregateSql(String aggregate, String column, String field) { String normalized = aggregate == null ? "" : aggregate.toLowerCase(); return switch (normalized) {