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 104b5e69..f4668f03 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 @@ -34,6 +34,12 @@ public class FishPassageController { return ResponseResult.successData(fpRunService.processQgcSecondPlanKendoList(dataSourceRequest)); } + @PostMapping("/query/qgc/sdfpssr/GetKendoListCust") + @Operation(summary = "全过程过鱼人工监测数据查询") + public ResponseResult getQgcSdfpssrKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fpRunService.processQgcSdfpssrKendoList(dataSourceRequest)); + } + @PostMapping("/build/GetKendoListCust") @Operation(summary = "过鱼设施建设及接入情况统计") public ResponseResult getKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpSdfpssrVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpSdfpssrVo.java new file mode 100644 index 00000000..19e357fc --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpSdfpssrVo.java @@ -0,0 +1,83 @@ +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 FpSdfpssrVo { + + @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 Date tm; + + @Schema(description = "站点排序") + private Integer siteStepSort; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "流域排序") + private Integer rvcdStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "鱼类名称") + private String name; + + @Schema(description = "鱼类编码") + private String ftp; + + @Schema(description = "鱼类编码") + private String fishId; + + @Schema(description = "过鱼数量") + private Integer fcnt; + + @Schema(description = "大小") + private String fsz; + + @Schema(description = "附件ID") + private String fid; + + @Schema(description = "游向") + private Integer direction; + + @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 3088f708..8b247f4d 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 @@ -2,6 +2,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.FpSdfpssrVo; import com.yfd.platform.qgc_env.fp.entity.vo.YearFpStatisticsVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunPlanVo; @@ -11,5 +12,7 @@ public interface FpRunService { DataSourceResult processQgcSecondPlanKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processQgcSdfpssrKendoList(DataSourceRequest dataSourceRequest); + List getYearFpStatic(String year); } 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 d0591911..80f480be 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 @@ -2,15 +2,20 @@ package com.yfd.platform.qgc_env.fp.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.convert.Convert; 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.exception.BizException; import com.yfd.platform.qgc_env.fp.entity.vo.FpFtpStatisticsVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunPlanVo; +import com.yfd.platform.qgc_env.fp.entity.vo.FpSdfpssrVo; import com.yfd.platform.qgc_env.fp.entity.vo.YearFpStatisticsVo; import com.yfd.platform.qgc_env.fp.service.FpRunService; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -20,6 +25,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; import java.math.RoundingMode; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashMap; @@ -99,6 +105,15 @@ public class FpRunServiceImpl implements FpRunService { return result; } + @Override + public DataSourceResult processQgcSdfpssrKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryQgcSdfpssrDetailList(dataSourceRequest, loadOptions); + } + return queryQgcSdfpssrGroupList(dataSourceRequest, loadOptions); + } + @Override public List getYearFpStatic(String year) { Map paramMap = new HashMap<>(); @@ -129,6 +144,430 @@ public class FpRunServiceImpl implements FpRunService { return new ArrayList<>(grouped.values()); } + private DataSourceResult queryQgcSdfpssrDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildQgcSdfpssrDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildQgcSdfpssrCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcSdfpssrFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildQgcSdfpssrOrderBySql(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, FpSdfpssrVo.class); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryQgcSdfpssrGroupList(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 = mapQgcSdfpssrColumn(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 = mapQgcSdfpssrColumn(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(buildQgcSdfpssrCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = buildQgcSdfpssrFilterCondition(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 = mapQgcSdfpssrColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildQgcSdfpssrGroupOrderBySql(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 String buildQgcSdfpssrCoreSql() { + return "SELECT " + + "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, " + + "t.TM AS tm, " + + "NVL(fp.ORDER_INDEX, 999999) AS siteStepSort, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(hbrv.ORDER_INDEX, 999999) AS rvcdStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "COALESCE(fishRv.NAME, relRv.FISH_NAME, fishZy.NAME, relZy.FISH_NAME, fishDirect.NAME, t.FTP) AS name, " + + "t.FTP AS ftp, " + + "t.FTP AS fishId, " + + "t.FCNT AS fcnt, " + + "t.FSZ AS fsz, " + + "t.FID AS fid, " + + "t.DIRECTION AS direction, " + + "1 AS mway, " + + "t.STRDT AS strdt, " + + "t.ENDDT AS enddt, " + + "CAST(NULL AS VARCHAR2(100)) AS stCode, " + + "CAST(NULL AS VARCHAR2(200)) AS stName " + + "FROM SD_FPSS_R t " + + "INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD " + + "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"; + } + + private String buildQgcSdfpssrDetailSelectSql(List selectFields) { + Map selectMap = new LinkedHashMap<>(); + selectMap.put("stcd", "t.stcd AS stcd"); + selectMap.put("stnm", "t.stnm 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("tm", "t.tm AS tm"); + selectMap.put("siteStepSort", "t.siteStepSort AS siteStepSort"); + selectMap.put("baseStepSort", "t.baseStepSort AS baseStepSort"); + selectMap.put("rvcdStepSort", "t.rvcdStepSort AS rvcdStepSort"); + selectMap.put("rstcdStepSort", "t.rstcdStepSort AS rstcdStepSort"); + selectMap.put("name", "t.name AS name"); + selectMap.put("ftp", "t.ftp AS ftp"); + selectMap.put("fishId", "t.fishId AS fishId"); + selectMap.put("fcnt", "t.fcnt AS fcnt"); + selectMap.put("fsz", "t.fsz AS fsz"); + selectMap.put("fid", "t.fid AS fid"); + selectMap.put("direction", "t.direction AS direction"); + 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) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildQgcSdfpssrLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildQgcSdfpssrFilterCondition(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 buildQgcSdfpssrLeafCondition(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 = "fpSdfpssrP" + 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.NAME LIKE #{map." + key + "} OR t.FTP LIKE #{map." + key + "})"; + } + + String column = mapQgcSdfpssrColumn(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 = "fpSdfpssrP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add(buildValueExpr(key, dateField, item)); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + + String key = "fpSdfpssrP" + 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; + } + return switch (field) { + 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 "tm" -> "t.TM"; + case "siteStepSort" -> "t.SITESTEPSORT"; + case "baseStepSort" -> "t.BASESTEPSORT"; + case "rvcdStepSort" -> "t.RVCDSTEPSORT"; + case "rstcdStepSort" -> "t.RSTCDSTEPSORT"; + case "name" -> "t.NAME"; + case "ftp" -> "t.FTP"; + case "fishId" -> "t.FISHID"; + case "fcnt" -> "t.FCNT"; + case "fsz" -> "t.FSZ"; + case "fid" -> "t.FID"; + case "direction" -> "t.DIRECTION"; + 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"; + } + List orderColumns = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sortDescriptor : sortList) { + if (sortDescriptor == null || StrUtil.isBlank(sortDescriptor.getField())) { + continue; + } + String column = mapQgcSdfpssrColumn(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.STRDT ASC, t.STCD ASC"; + } + return " ORDER BY " + String.join(", ", orderColumns); + } + + private String buildQgcSdfpssrGroupOrderBySql(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 = mapQgcSdfpssrColumn(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) { + case "sum", "min", "max", "avg", "count" -> + normalized.toUpperCase() + "(" + column + ") AS " + normalized + "_" + field; + default -> ""; + }; + } + + private List normalizeValues(Object value) { + if (value == null) { + return new ArrayList<>(); + } + if (value instanceof List list) { + return new ArrayList<>(list); + } + String text = String.valueOf(value).trim(); + if (StrUtil.isBlank(text)) { + return new ArrayList<>(); + } + if (text.startsWith("[") && text.endsWith("]")) { + text = text.substring(1, text.length() - 1); + } + List values = new ArrayList<>(); + for (String item : text.split(",")) { + String trimmed = StrUtil.trim(item); + if (StrUtil.isNotBlank(trimmed)) { + values.add(StrUtil.removeAll(trimmed, "\"")); + } + } + return values; + } + + 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 String buildQgcSecondPlanSql() { return "SELECT t.STCD AS stcd, " + " t2.stm AS designStartDate, " +