From fc0f84dc8d7f2455e508e25671870ebb7edd510e Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 13 Aug 2026 17:50:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B5=81=E5=9F=9F-=E7=8F=8D=E7=A8=80?= =?UTF-8?q?=E6=A4=8D=E7=89=A9=E5=9B=AD=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 --- .../controller/VapConstructionController.java | 6 + .../qgc_env/vap/entity/vo/VpBasinVplntVo.java | 70 ++++++ .../vap/service/VpConstructionService.java | 3 + .../impl/VpConstructionServiceImpl.java | 228 ++++++++++++++++++ 4 files changed, 307 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinVplntVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java index d6900110..126f32dd 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/controller/VapConstructionController.java @@ -47,6 +47,12 @@ public class VapConstructionController { return ResponseResult.successData(vpConstructionService.basinVpIntDetail(dataSourceRequest)); } + @PostMapping("/basin/GetKendoListCust") + @Operation(summary = "流域-珍稀植物园运行数据(SD_VP_R + V_MS_STBPRP_T)") + public ResponseResult getBasinVplntKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vpConstructionService.processBasinVplntKendoList(dataSourceRequest)); + } + @PostMapping("/wva/GetKendoListCust") @Operation(summary = "野生动物监测情况") public ResponseResult getWvaKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinVplntVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinVplntVo.java new file mode 100644 index 00000000..2ca72f76 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpBasinVplntVo.java @@ -0,0 +1,70 @@ +package com.yfd.platform.qgc_env.vap.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serializable; + +/** + * 流域-珍稀植物园运行数据 VO(对应旧系统 BasinVplnt) + */ +@Data +@Schema(description = "流域-珍稀植物园运行数据") +public class VpBasinVplntVo implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "年份") + private String year; + + @Schema(description = "植物园编码") + private String stcd; + + @Schema(description = "植物园名称") + private String stnm; + + @Schema(description = "所属电站编码") + private String rstcd; + + @Schema(description = "电站名称") + private String ennm; + + @Schema(description = "展示名称") + private String name; + + @Schema(description = "建设状态") + private Integer bldstt; + + @Schema(description = "简介") + private String introduce; + + @Schema(description = "规划设计日期") + private String ststdt; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "介绍弹窗图片") + private String inffile; + + @Schema(description = "站类名称") + private String sttpName; + + @Schema(description = "LOGO图片") + private String logo; + + @Schema(description = "建成日期") + private String jcdt; + + @Schema(description = "数据是否接入") + private Integer dtin; + + @Schema(description = "电站排序") + private Integer rstcdstepsort; + + @Schema(description = "排序") + private Integer orderIndex; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java index 634224a5..5a368a86 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/VpConstructionService.java @@ -5,6 +5,7 @@ import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.vap.entity.vo.FhvapBuiltPointVo; import com.yfd.platform.qgc_env.vap.entity.vo.WvaPointVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo; +import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinVplntVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpVarVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpStInfoResultVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpVacVo; @@ -20,6 +21,8 @@ public interface VpConstructionService { DataSourceResult basinVpIntDetail(DataSourceRequest dataSourceRequest); + DataSourceResult processBasinVplntKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult processWvaKendoList(DataSourceRequest dataSourceRequest); DataSourceResult processVacKendoList(DataSourceRequest dataSourceRequest); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java index 9a0ea040..2126f855 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/service/impl/VpConstructionServiceImpl.java @@ -12,6 +12,7 @@ import com.yfd.platform.common.PageInfo; import com.yfd.platform.qgc_env.vap.entity.vo.FhvapBuiltPointVo; import com.yfd.platform.qgc_env.vap.entity.vo.WvaPointVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo; +import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinVplntVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpConstructionSituationVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpVarVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpVacVo; @@ -29,6 +30,7 @@ import org.springframework.util.CollectionUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -174,6 +176,232 @@ public class VpConstructionServiceImpl implements VpConstructionService { return result; } + @Override + public DataSourceResult processBasinVplntKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollectionUtils.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryBasinVplntDetailList(dataSourceRequest, loadOptions); + } + return queryBasinVplntGroupList(dataSourceRequest, loadOptions); + } + + private DataSourceResult queryBasinVplntDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildBasinVplntSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildBasinVplntCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0}, + this::mapBasinVplntColumn + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildBasinVplntOrderBySql(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, VpBasinVplntVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryBasinVplntGroupList(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 = mapBasinVplntColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField().toUpperCase()); + selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase()); + if (CollectionUtils.isEmpty(descriptor.getAggregates())) { + continue; + } + for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) { + String aggregateColumn = mapBasinVplntColumn(aggregate.getField()); + if (StrUtil.isBlank(aggregateColumn) || StrUtil.isBlank(aggregate.getAggregate())) { + continue; + } + selectItems.add(buildAggregateSql(aggregate.getAggregate(), aggregateColumn, aggregate.getField())); + } + } + if (selectItems.isEmpty()) { + selectItems.add("t.STCD AS STCD"); + selectItems.add("COUNT(*) AS COUNT_STCD"); + } + + StringBuilder sql = new StringBuilder("SELECT "); + sql.append(String.join(", ", selectItems)) + .append(" FROM (") + .append(buildBasinVplntCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0}, + this::mapBasinVplntColumn + ); + 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 = mapBasinVplntColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildBasinVplntOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + + List> rows = microservicDynamicSQLMapper.pageAllList(null, sql.toString(), paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (dataSourceRequest.getGroupResultFlat() != null && 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; + } + + /** + * 流域-珍稀植物园运行数据核心 SQL: + * SD_VP_R 按年份+站点分组,关联 V_MS_STBPRP_T(植物园 DATA_SOURCE='SD_VP_B_H')取基础信息 + */ + private String buildBasinVplntCoreSql() { + return "SELECT t.year AS year, t.STCD AS STCD, t0.STNM AS STNM, t0.RSTCD AS RSTCD, t0.ENNM AS ENNM, " + + "t0.BLDSTT_CODE AS BLDSTT, t0.INTRODUCE AS INTRODUCE, TO_CHAR(t0.STDSDT, 'YYYY-MM-DD') AS STSTDT, " + + "t0.BASE_ID AS BASE_ID, t0.BASE_NAME AS BASE_NAME, t0.INFFILE AS INFFILE, " + + "t0.STTP_NAME AS STTP_NAME, t0.LOGO AS LOGO, TO_CHAR(t0.JCDT, 'YYYY-MM-DD') AS JCDT, t0.DTIN AS DTIN, " + + "t0.ORDER_INDEX AS RSTCDSTEPSORT, t0.ORDER_INDEX AS ORDER_INDEX " + + "FROM (SELECT TO_CHAR(r.TM, 'YYYY') AS year, r.STCD FROM SD_VP_R r " + + "WHERE NVL(r.IS_DELETED, 0) = 0 GROUP BY TO_CHAR(r.TM, 'YYYY'), r.STCD) t " + + "INNER JOIN V_MS_STBPRP_T t0 ON t.STCD = t0.STCD AND t0.DATA_SOURCE = 'SD_VP_B_H' " + + "WHERE NVL(t0.IS_DELETED, 0) = 0 "; + } + + private String buildBasinVplntSelectSql(List selectFields) { + Map columns = new LinkedHashMap<>(); + columns.put("year", "t.year AS year"); + columns.put("stcd", "t.STCD AS stcd"); + columns.put("stnm", "t.STNM AS stnm"); + columns.put("rstcd", "t.RSTCD AS rstcd"); + columns.put("ennm", "t.ENNM AS ennm"); + columns.put("name", "t.ENNM AS name"); + columns.put("bldstt", "t.BLDSTT AS bldstt"); + columns.put("introduce", "t.INTRODUCE AS introduce"); + columns.put("ststdt", "t.STSTDT AS ststdt"); + columns.put("baseId", "t.BASE_ID AS baseId"); + columns.put("baseName", "t.BASE_NAME AS baseName"); + columns.put("inffile", "t.INFFILE AS inffile"); + columns.put("sttpName", "t.STTP_NAME AS sttpName"); + columns.put("logo", "t.LOGO AS logo"); + columns.put("jcdt", "t.JCDT AS jcdt"); + columns.put("dtin", "t.DTIN AS dtin"); + columns.put("rstcdstepsort", "t.RSTCDSTEPSORT AS rstcdstepsort"); + columns.put("orderIndex", "t.ORDER_INDEX AS orderIndex"); + + List selected = new ArrayList<>(); + if (CollectionUtils.isEmpty(selectFields)) { + selected.addAll(columns.values()); + } else { + for (String field : selectFields) { + String column = columns.get(field); + if (StrUtil.isNotBlank(column)) { + selected.add(column); + } + } + if (selected.isEmpty()) { + selected.addAll(columns.values()); + } + } + return String.join(", ", selected); + } + + private String mapBasinVplntColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field.toLowerCase()) { + case "year" -> "t.year"; + case "stcd" -> "t.STCD"; + case "stnm" -> "t.STNM"; + case "rstcd" -> "t.RSTCD"; + case "ennm", "name" -> "t.ENNM"; + case "bldstt" -> "t.BLDSTT"; + case "introduce" -> "t.INTRODUCE"; + case "ststdt" -> "t.STSTDT"; + case "baseid" -> "t.BASE_ID"; + case "basename" -> "t.BASE_NAME"; + case "inffile" -> "t.INFFILE"; + case "sttpname" -> "t.STTP_NAME"; + case "logo" -> "t.LOGO"; + case "jcdt" -> "t.JCDT"; + case "dtin" -> "t.DTIN"; + case "rstcdstepsort" -> "t.RSTCDSTEPSORT"; + case "orderindex" -> "t.ORDER_INDEX"; + default -> null; + }; + } + + 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 String buildBasinVplntOrderBySql(List sorts) { + if (sorts == null || sorts.isEmpty()) { + return ""; +// return " ORDER BY t.RSTCDSTEPSORT ASC, t.STCD ASC"; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapBasinVplntColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String dir = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orders.add(column + " " + dir); + } + return orders.isEmpty() ? " ORDER BY t.RSTCDSTEPSORT ASC, t.STCD ASC" : " ORDER BY " + String.join(", ", orders); + } + @Override public DataSourceResult processWvaKendoList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest();