From ef1a76223d2823fa598c2751e85cd0d85a431032 Mon Sep 17 00:00:00 2001 From: tangwei Date: Mon, 1 Jun 2026 09:53:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9F=A5=E8=AF=A2=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E7=9B=91=E6=8E=A7=E8=BF=90=E8=A1=8C=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vd/controller/VdMonitorController.java | 6 + .../qgc_env/vd/entity/vo/VdRunDataVo.java | 97 ++++ .../qgc_env/vd/service/VdMonitorService.java | 3 + .../vd/service/impl/VdMonitorServiceImpl.java | 419 +++++++++++++++++- 4 files changed, 511 insertions(+), 14 deletions(-) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdRunDataVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java index 03216b3d..841e56e7 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/controller/VdMonitorController.java @@ -34,4 +34,10 @@ public class VdMonitorController { public ResponseResult getStcdInfo(@RequestParam String stcd) { return ResponseResult.successData(vdMonitorService.getStcdInfo(stcd)); } + + @PostMapping("/runData/GetKendoListCust") + @Operation(summary = "查询视频监控运行数据") + public ResponseResult getRunDataKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vdMonitorService.getRunDataKendoListCust(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdRunDataVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdRunDataVo.java new file mode 100644 index 00000000..166fc84d --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/entity/vo/VdRunDataVo.java @@ -0,0 +1,97 @@ +package com.yfd.platform.qgc_env.vd.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; +import java.util.Date; + +@Data +@Schema(description = "视频监控运行数据") +public class VdRunDataVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "视频站名称") + private String stnm; + + @Schema(description = "视频监控点编码") + private String stcd; + + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + @Schema(description = "时间") + private Date tm; + + @Schema(description = "显示名称") + private String flnm; + + @Schema(description = "图片路径") + private String imgPath; + + @Schema(description = "视频路径") + private String flpth; + + @Schema(description = "设备视频信息") + private String deviceinfo; + + @Schema(description = "设备状态描述") + private String describe; + + @Schema(description = "附件ID") + private String fid; + + @Schema(description = "缩略图") + private String thumbnail; + + @Schema(description = "电站编码") + private String rstcd; + + @Schema(description = "电站名称") + private String ennm; + + @Schema(description = "栖息地编码") + private String fhstcd; + + @Schema(description = "栖息地名称") + private String fhstnm; + + @Schema(description = "测站编码") + private String stCode; + + @Schema(description = "测站名称") + private String stName; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "类型编码") + private String sttpCode; + + @Schema(description = "类型名称") + private String sttpName; + + @Schema(description = "标题名称") + private String titleName; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "站点排序") + private Integer siteStepSort; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java index 1c137839..59730582 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/VdMonitorService.java @@ -2,6 +2,7 @@ package com.yfd.platform.qgc_env.vd.service; import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.qgc_env.vd.entity.vo.VdRunDataVo; import com.yfd.platform.qgc_env.vd.entity.vo.VdVmsstbprptVo; public interface VdMonitorService { @@ -9,4 +10,6 @@ public interface VdMonitorService { DataSourceResult getVmsstbprptList(DataSourceRequest dataSourceRequest); VdVmsstbprptVo getStcdInfo(String stcd); + + DataSourceResult getRunDataKendoListCust(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java index 56d0f9c9..42f124ca 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vd/service/impl/VdMonitorServiceImpl.java @@ -9,6 +9,7 @@ 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.qgc_env.vd.entity.vo.VdRunDataVo; import com.yfd.platform.qgc_env.vd.entity.vo.VdVmsstbprptVo; import com.yfd.platform.qgc_env.vd.service.VdMonitorService; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -18,6 +19,7 @@ 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; @@ -101,6 +103,15 @@ public class VdMonitorServiceImpl implements VdMonitorService { return list.get(0); } + @Override + public DataSourceResult getRunDataKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryRunDataDetailList(dataSourceRequest, loadOptions); + } + return queryRunDataGroupList(dataSourceRequest, loadOptions); + } + private DataSourceResult buildGroupedResult(DataSourceRequest dataSourceRequest, GroupingInfo[] groups, String filterSql, @@ -194,6 +205,101 @@ public class VdMonitorServiceImpl implements VdMonitorService { return result; } + private DataSourceResult queryRunDataDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildRunDataSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildRunDataCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildRunDataFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildRunDataOrderBySql(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, VdRunDataVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryRunDataGroupList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + List groups = dataSourceRequest.getGroup(); + GroupingInfo[] groupInfos = loadOptions == null ? new GroupingInfo[0] : loadOptions.getGroup(); + List selectItems = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : groups) { + if (descriptor == null || StrUtil.isBlank(descriptor.getField())) { + continue; + } + String column = mapRunDataColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField()); + selectItems.add("COUNT(*) AS count_" + descriptor.getField()); + if (CollUtil.isNotEmpty(descriptor.getAggregates())) { + for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) { + String aggregateColumn = mapRunDataColumn(aggregate.getField()); + if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) { + continue; + } + selectItems.add(buildRunDataAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField())); + } + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.sttpCode AS sttpCode"); + selectItems.add("COUNT(*) AS count_sttpCode"); + } + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildRunDataCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildRunDataFilterCondition(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 = mapRunDataColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)); + sql.append(buildRunDataGroupOrderBySql(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((long) rows.size()); + result.setAggregates(new HashMap<>()); + return result; + } + private String buildVmsstbprptViewSql() { return "SELECT " + "src.STCD AS stcd, " + @@ -231,9 +337,18 @@ public class VdMonitorServiceImpl implements VdMonitorService { "NVL(src.ORDER_INDEX, 999999) AS siteStepSort, " + "src.SOURCE_TABLE AS sourceTable " + "FROM (" + - "SELECT vd.STCD, vd.STNM, vd.MNTP, vd.STTP, vd.LGTD, vd.LTTD, vd.ELEV, vd.STLC, " + + buildVdDeviceBaseSql() + + ") src " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = src.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(eng.BASE_ID, src.BASE_ID) AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = src.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLED, 1) = 1 "; + } + + private String buildVdDeviceBaseSql() { + return "SELECT vd.STCD, vd.STNM, vd.MNTP, vd.STTP, vd.LGTD, vd.LTTD, vd.ELEV, vd.STLC, " + " vd.JCDT, vd.WDDT, vd.BLDSTT_CODE, vd.USFL, vd.DTIN, vd.STINDX, vd.RSTCD, vd.BASE_ID, " + - " vd.HBRVCD, vd.RVCD, vd.ADDVCD, CAST(NULL AS VARCHAR2(3000)) AS INTRODUCE, " + + " vd.HBRVCD, vd.RVCD, vd.ADDVCD, vd.CSTCD, vd.FHSTCD, CAST(NULL AS VARCHAR2(3000)) AS INTRODUCE, " + " CAST(NULL AS VARCHAR2(255)) AS LOGO, CAST(NULL AS VARCHAR2(1000)) AS INFFILE, " + " vd.DTFRQCY, vd.REMARK, vd.VLSR, vd.VLSR_TM, CAST(NULL AS NUMBER(8,0)) AS ORDER_INDEX, " + " 'SD_VDINFO_B' AS SOURCE_TABLE " + @@ -241,15 +356,163 @@ public class VdMonitorServiceImpl implements VdMonitorService { "UNION ALL " + "SELECT sonar.STCD, sonar.STNM, sonar.MNTP, sonar.STTP, sonar.LGTD, sonar.LTTD, sonar.ELEV, sonar.STLC, " + " sonar.JCDT, sonar.WDDT, sonar.BLDSTT_CODE, sonar.USFL, sonar.DTIN, sonar.STINDX, sonar.RSTCD, sonar.BASE_ID, " + - " sonar.HBRVCD, sonar.RVCD, sonar.ADDVCD, sonar.INTRODUCE, sonar.LOGO, sonar.INFFILE, " + - " sonar.DTFRQCY, sonar.REMARK, sonar.VLSR, sonar.VLSR_TM, sonar.ORDER_INDEX, " + + " sonar.HBRVCD, sonar.RVCD, sonar.ADDVCD, CAST(NULL AS VARCHAR2(36)) AS CSTCD, CAST(NULL AS VARCHAR2(36)) AS FHSTCD, " + + " sonar.INTRODUCE, sonar.LOGO, sonar.INFFILE, sonar.DTFRQCY, sonar.REMARK, sonar.VLSR, sonar.VLSR_TM, sonar.ORDER_INDEX, " + " 'SD_SONAR_B_H' AS SOURCE_TABLE " + - "FROM SD_SONAR_B_H sonar WHERE NVL(sonar.IS_DELETED, 0) = 0 AND sonar.STTP IN ('VD_WVD', 'VD_SN') " + - ") src " + - "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = src.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_STTP_B sttp ON sttp.STTP_CODE = src.STTP " + - " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 "; + "FROM SD_SONAR_B_H sonar WHERE NVL(sonar.IS_DELETED, 0) = 0 AND sonar.STTP IN ('VD_WVD', 'VD_SN') "; + } + + private String buildRunDataCoreSql() { + return "SELECT " + + "run.ID AS id, " + + "run.STCD AS stcd, " + + "run.TM AS tm, " + + "NVL(run.FLNM, base.STNM || ' ' || TO_CHAR(run.TM, 'yyyy-mm-dd hh24')) AS flnm, " + + "run.IMG_PATH AS imgPath, " + + "run.FLPTH AS flpth, " + + "run.DEVICEINFO AS deviceinfo, " + + "run.DESCRIBE AS describe, " + + "run.FID AS fid, " + + "run.THUMBNAIL AS thumbnail, " + + "base.RSTCD AS rstcd, " + + "base.STNM AS stnm, " + + "eng.ENNM AS ennm, " + + "base.FHSTCD AS fhstcd, " + + "fh.STNM AS fhstnm, " + + "base.CSTCD AS stCode, " + + "cst.STNM AS stName, " + + "NVL(eng.BASE_ID, base.BASE_ID) AS baseId, " + + "hb.BASENAME AS baseName, " + + "base.STTP AS sttpCode, " + + "sttp.STTP_NAME AS sttpName, " + + "base.STNM AS titleName, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(hbrv.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(base.ORDER_INDEX, 999999) AS siteStepSort, " + + "NVL(eng.HBRVCD, base.HBRVCD) AS hbrvcd, " + + "hbrv.HBRVNM AS hbrvcdName " + + "FROM SD_VDINFO_R run " + + "INNER JOIN (" + buildVdDeviceBaseSql() + ") base ON run.STCD = base.STCD " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = base.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(eng.BASE_ID, base.BASE_ID) " + + " AND NVL(hb.IS_DELETED, 0) = 0 AND NVL(hb.ENABLED, 1) = 1 " + + "LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(eng.HBRVCD, base.HBRVCD) " + + " AND hbrv.BASEID = NVL(eng.BASE_ID, base.BASE_ID) " + + " AND NVL(hbrv.IS_DELETED, 0) = 0 AND NVL(hbrv.ENABLED, 1) = 1 " + + "LEFT JOIN SD_FHBT_B_H fh ON fh.STCD = base.FHSTCD AND NVL(fh.IS_DELETED, 0) = 0 " + + "LEFT JOIN (" + buildStationBaseSql() + ") cst ON cst.STCD = base.CSTCD " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = base.STTP " + + " AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "WHERE NVL(run.IS_DELETED, 0) = 0 "; + } + + private String buildStationBaseSql() { + return "SELECT river.STCD AS STCD, river.STNM AS STNM FROM SD_RIVER_B_H river WHERE NVL(river.IS_DELETED, 0) = 0 " + + "UNION ALL " + + "SELECT wt.STCD AS STCD, wt.STNM AS STNM FROM SD_WT_B_H wt WHERE NVL(wt.IS_DELETED, 0) = 0 " + + "UNION ALL " + + "SELECT wq.STCD AS STCD, wq.STNM AS STNM FROM SD_WQ_B_H wq WHERE NVL(wq.IS_DELETED, 0) = 0 " + + "UNION ALL " + + "SELECT fh.STCD AS STCD, fh.STNM AS STNM FROM SD_FHBT_B_H fh WHERE NVL(fh.IS_DELETED, 0) = 0 " + + "UNION ALL " + + "SELECT eng.STCD AS STCD, eng.ENNM AS STNM FROM SD_ENGINFO_B_H eng WHERE NVL(eng.IS_DELETED, 0) = 0 "; + } + + private String buildRunDataSelectSql(List selectFields) { + Map selectMap = new LinkedHashMap<>(); + selectMap.put("stnm", "t.stnm AS stnm"); + selectMap.put("stcd", "t.stcd AS stcd"); + selectMap.put("tm", "t.tm AS tm"); + selectMap.put("flnm", "t.flnm AS flnm"); + selectMap.put("imgPath", "t.imgPath AS imgPath"); + selectMap.put("flpth", "t.flpth AS flpth"); + selectMap.put("deviceinfo", "t.deviceinfo AS deviceinfo"); + selectMap.put("describe", "t.describe AS describe"); + selectMap.put("fid", "t.fid AS fid"); + selectMap.put("thumbnail", "t.thumbnail AS thumbnail"); + selectMap.put("rstcd", "t.rstcd AS rstcd"); + selectMap.put("ennm", "t.ennm AS ennm"); + selectMap.put("fhstcd", "t.fhstcd AS fhstcd"); + selectMap.put("fhstnm", "t.fhstnm AS fhstnm"); + selectMap.put("stCode", "t.stCode AS stCode"); + selectMap.put("stName", "t.stName AS stName"); + selectMap.put("baseId", "t.baseId AS baseId"); + selectMap.put("baseName", "t.baseName AS baseName"); + selectMap.put("sttpCode", "t.sttpCode AS sttpCode"); + selectMap.put("sttpName", "t.sttpName AS sttpName"); + selectMap.put("titleName", "t.titleName AS titleName"); + selectMap.put("baseStepSort", "t.baseStepSort AS baseStepSort"); + selectMap.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); + selectMap.put("rstcdStepSort", "t.rstcdStepSort AS rstcdStepSort"); + selectMap.put("siteStepSort", "t.siteStepSort AS siteStepSort"); + selectMap.put("hbrvcd", "t.hbrvcd AS hbrvcd"); + selectMap.put("hbrvcdName", "t.hbrvcdName AS hbrvcdName"); + + if (CollUtil.isEmpty(selectFields)) { + return String.join(", ", selectMap.values()); + } + List actualColumns = new ArrayList<>(); + for (String selectField : selectFields) { + String column = selectMap.get(selectField); + if (StrUtil.isNotBlank(column)) { + actualColumns.add(column); + } + } + if (actualColumns.isEmpty()) { + actualColumns.addAll(selectMap.values()); + } + return String.join(", ", actualColumns); + } + + private String buildRunDataOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY t.baseStepSort ASC, t.rvcdStepSort ASC, t.rstcdStepSort ASC, t.siteStepSort ASC, t.stcd ASC, t.tm DESC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapRunDataColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) || "des".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderItems.add(column + " " + direction + " NULLS LAST"); + } + if (orderItems.isEmpty()) { + return " ORDER BY t.baseStepSort ASC, t.rvcdStepSort ASC, t.rstcdStepSort ASC, t.siteStepSort ASC, t.stcd ASC, t.tm DESC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + + private String buildRunDataGroupOrderBySql(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 = mapRunDataColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(descriptor.getDir()) || "des".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + direction); + } + return orders.isEmpty() ? "" : " ORDER BY " + String.join(", ", orders); + } + + private String buildRunDataAggregateSql(String aggregate, String column, String field) { + String normalized = aggregate == null ? "" : aggregate.toLowerCase(); + return switch (normalized) { + case "sum", "min", "max", "avg", "count" -> + normalized.toUpperCase() + "(" + column + ") AS " + normalized + "_" + field; + default -> null; + }; } private String buildFilterCondition(DataSourceRequest.FilterDescriptor filter, @@ -278,6 +541,32 @@ public class VdMonitorServiceImpl implements VdMonitorService { return String.join(logic, conditions); } + private String buildRunDataFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildRunDataLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildRunDataFilterCondition(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 buildLeafCondition(DataSourceRequest.FilterDescriptor filter, Map paramMap, int[] indexHolder) { @@ -285,6 +574,33 @@ public class VdMonitorServiceImpl implements VdMonitorService { if (StrUtil.isBlank(column)) { return ""; } + return buildSimpleCondition(column, "vdParam", filter, paramMap, indexHolder); + } + + private String buildRunDataLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String column = mapRunDataColumn(filter.getField()); + if (StrUtil.isBlank(column)) { + return ""; + } + return buildSimpleCondition(column, "vdRunParam", filter, paramMap, indexHolder, isRunDataDateField(filter)); + } + + private String buildSimpleCondition(String column, + String paramPrefix, + DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + return buildSimpleCondition(column, paramPrefix, filter, paramMap, indexHolder, false); + } + + private String buildSimpleCondition(String column, + String paramPrefix, + 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)) { @@ -300,7 +616,7 @@ public class VdMonitorServiceImpl implements VdMonitorService { } List placeholders = new ArrayList<>(); for (Object item : values) { - String paramKey = "vdParam" + indexHolder[0]++; + String paramKey = paramPrefix + indexHolder[0]++; paramMap.put(paramKey, item); placeholders.add("#{map." + paramKey + "}"); } @@ -309,15 +625,16 @@ public class VdMonitorServiceImpl implements VdMonitorService { if (value == null) { return ""; } - String paramKey = "vdParam" + indexHolder[0]++; + String paramKey = paramPrefix + indexHolder[0]++; + String valueExpr = buildValueExpr(paramKey, dateField, value); return switch (operator) { case "eq" -> { paramMap.put(paramKey, value); - yield column + " = #{map." + paramKey + "}"; + yield column + " = " + valueExpr; } case "neq" -> { paramMap.put(paramKey, value); - yield column + " <> #{map." + paramKey + "}"; + yield column + " <> " + valueExpr; } case "contains" -> { paramMap.put(paramKey, "%" + value + "%"); @@ -331,10 +648,47 @@ public class VdMonitorServiceImpl implements VdMonitorService { paramMap.put(paramKey, "%" + value); yield column + " LIKE #{map." + paramKey + "}"; } + case "gt" -> { + paramMap.put(paramKey, value); + yield column + " > " + valueExpr; + } + case "gte" -> { + paramMap.put(paramKey, value); + yield column + " >= " + valueExpr; + } + case "lt" -> { + paramMap.put(paramKey, value); + yield column + " < " + valueExpr; + } + case "lte" -> { + paramMap.put(paramKey, value); + yield column + " <= " + valueExpr; + } default -> ""; }; } + private boolean isRunDataDateField(DataSourceRequest.FilterDescriptor filter) { + if (filter == null || StrUtil.isBlank(filter.getField())) { + return false; + } + if ("tm".equalsIgnoreCase(filter.getField())) { + return true; + } + return "date".equalsIgnoreCase(filter.getDataType()); + } + + private String buildValueExpr(String paramKey, boolean dateField, Object value) { + if (!dateField || value == null) { + return "#{map." + paramKey + "}"; + } + String text = String.valueOf(value).trim(); + if (text.length() <= 10) { + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD')"; + } + return "TO_DATE(#{map." + paramKey + "}, 'YYYY-MM-DD HH24:MI:SS')"; + } + private List normalizeValues(Object value) { List values = new ArrayList<>(); if (value instanceof List list) { @@ -384,6 +738,43 @@ public class VdMonitorServiceImpl implements VdMonitorService { }; } + private String mapRunDataColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "id" -> "t.id"; + case "stnm" -> "t.stnm"; + case "stcd" -> "t.stcd"; + case "tm" -> "t.tm"; + case "flnm" -> "t.flnm"; + case "imgPath" -> "t.imgPath"; + case "flpth" -> "t.flpth"; + case "deviceinfo" -> "t.deviceinfo"; + case "describe" -> "t.describe"; + case "fid" -> "t.fid"; + case "thumbnail" -> "t.thumbnail"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "fhstcd" -> "t.fhstcd"; + case "fhstnm" -> "t.fhstnm"; + case "stCode" -> "t.stCode"; + case "stName" -> "t.stName"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "sttpCode" -> "t.sttpCode"; + case "sttpName" -> "t.sttpName"; + case "titleName" -> "t.titleName"; + case "baseStepSort" -> "t.baseStepSort"; + case "rvcdStepSort" -> "t.rvcdStepSort"; + case "rstcdStepSort" -> "t.rstcdStepSort"; + case "siteStepSort" -> "t.siteStepSort"; + case "hbrvcd" -> "t.hbrvcd"; + case "hbrvcdName" -> "t.hbrvcdName"; + default -> null; + }; + } + private String buildOrderBySql(List groups) { if (CollUtil.isEmpty(groups)) { return " ORDER BY t.sttpCode ASC";