From ea911448303c0bfddf6cf09435dde29e0216e42b Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 11 Jun 2026 17:24:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=8A=A8=E7=89=A9=E6=95=91=E5=8A=A9?= =?UTF-8?q?=E7=AB=99=E5=BB=BA=E8=AE=BE=E5=8F=8A=E6=8E=A5=E5=85=A5=E6=83=85?= =?UTF-8?q?=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/VapConstructionController.java | 6 + .../qgc_env/vap/entity/vo/VpVacVo.java | 65 ++++ .../vap/service/VpConstructionService.java | 3 + .../impl/VpConstructionServiceImpl.java | 279 ++++++++++++++++++ 4 files changed, 353 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpVacVo.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 65bc8883..ef4924a8 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 @@ -52,4 +52,10 @@ public class VapConstructionController { public ResponseResult getWvaKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(vpConstructionService.processWvaKendoList(dataSourceRequest)); } + + @PostMapping("/vac/GetKendoListCust") + @Operation(summary = "动物救助站建设及接入情况") + public ResponseResult getVacKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(vpConstructionService.processVacKendoList(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpVacVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpVacVo.java new file mode 100644 index 00000000..89c52339 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/vap/entity/vo/VpVacVo.java @@ -0,0 +1,65 @@ +package com.yfd.platform.qgc_env.vap.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@Schema(description = "动物救助站建设及接入情况") +public class VpVacVo { + + @Schema(description = "测站编码") + private String stcd; + + @Schema(description = "基础对象名称") + private String stnm; + + @Schema(description = "业务类型名称") + private String sttpName; + + @Schema(description = "所属基地ID") + private String baseId; + + @Schema(description = "所属基地名称") + private String baseName; + + @Schema(description = "水电站名称") + private String ennm; + + @Schema(description = "是否接入") + private String dtin; + + @Schema(description = "是否接入名称") + private String dtinName; + + @Schema(description = "建设状态") + private String bldsttCcode; + + @Schema(description = "建设状态名称") + private String bldsttCcodeName; + + @Schema(description = "开工日期") + private Date ststdt; + + @Schema(description = "建成日期") + private Date esstdt; + + @Schema(description = "LOGO") + private String logo; + + @Schema(description = "简介") + private String introduce; + + @Schema(description = "介绍弹窗图片") + private String inffile; + + @Schema(description = "基地排序") + private Integer baseStepSort; + + @Schema(description = "电站排序") + private Integer rstcdStepSort; + + @Schema(description = "站点排序") + private Integer siteStepSort; +} 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 5e02dbd8..0cddcfec 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 @@ -4,6 +4,7 @@ import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceResult; import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpStInfoResultVo; +import com.yfd.platform.qgc_env.vap.entity.vo.VpVacVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpWvaRunVo; public interface VpConstructionService { @@ -17,4 +18,6 @@ public interface VpConstructionService { DataSourceResult basinVpIntDetail(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 4b1e1aa7..0328ba0e 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 @@ -11,6 +11,7 @@ import com.yfd.platform.common.MicroservicDynamicSQLMapper; import com.yfd.platform.common.PageInfo; import com.yfd.platform.qgc_env.vap.entity.vo.VpBasinIntDetailVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpConstructionSituationVo; +import com.yfd.platform.qgc_env.vap.entity.vo.VpVacVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpStBaseInfoVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpStInfoResultVo; import com.yfd.platform.qgc_env.vap.entity.vo.VpVmsstbprptVo; @@ -213,6 +214,284 @@ public class VpConstructionServiceImpl implements VpConstructionService { return result; } + @Override + public DataSourceResult processVacKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + PageInfo pageInfo = loadOptions == null ? new PageInfo() : QgcQueryWrapperUtil.getPageInfo(loadOptions); + Page page = pageInfo.getHasPageInfo() ? pageInfo.getPage() : null; + + String isZoo = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "isZoo"); + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(buildVacBaseSql("1".equals(isZoo))); + String filterSql = buildVacFilterCondition(dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql); + } + + String groupBy = dataSourceRequest == null ? null : KendoUtil.getGroupBy(dataSourceRequest); + GroupingInfo[] groupInfos = loadOptions == null ? null : loadOptions.getGroup(); + if (StrUtil.isNotBlank(groupBy) && groupInfos != null && groupInfos.length > 0) { + String groupedSql = buildVacGroupSql(sql.toString(), groupInfos); + List> rows = microservicDynamicSQLMapper.pageAllList(null, groupedSql, paramMap); + DataSourceResult result = new DataSourceResult(); + if (Boolean.TRUE.equals(dataSourceRequest.getGroupResultFlat())) { + result.setData(new GroupHelper().faltGroup(rows, Arrays.asList(groupInfos))); + } else { + result.setData(new GroupHelper().group(rows, Arrays.asList(groupInfos))); + } + result.setTotal(0L); + result.setAggregates(new HashMap<>()); + return result; + } + + sql.append(buildVacOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort())); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, VpVacVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildVacBaseSql(boolean isZoo) { + String baseIdExpr = isZoo ? "CASE WHEN va.BASE_ID IS NULL THEN 'null' ELSE va.BASE_ID END" : "va.BASE_ID"; + String dtinExpr = isZoo ? "CASE WHEN va.DTIN IS NULL THEN '400' ELSE TO_CHAR(va.DTIN) END" : "TO_CHAR(va.DTIN)"; + return "SELECT " + + "va.STCD AS stcd, " + + "va.STNM AS stnm, " + + "sttp.STTP_NAME AS sttpName, " + + baseIdExpr + " AS baseId, " + + "hb.BASENAME AS baseName, " + + "eng.ENNM AS ennm, " + + dtinExpr + " AS dtin, " + + "CASE WHEN NVL(va.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END AS dtinName, " + + "TO_CHAR(va.BLDSTT_CODE) AS bldsttCcode, " + + "CASE WHEN NVL(va.BLDSTT_CODE, 0) = 2 THEN '已建' WHEN NVL(va.BLDSTT_CODE, 0) = 1 THEN '在建' ELSE '未建/规划' END AS bldsttCcodeName, " + + "va.SWDT AS ststdt, " + + "va.JCDT AS esstdt, " + + "va.LOGO AS logo, " + + "va.INTRODUCE AS introduce, " + + "va.INFFILE AS inffile, " + + "NVL(hb.ORDER_INDEX, 999999) AS baseStepSort, " + + "NVL(eng.ORDER_INDEX, 999999) AS rstcdStepSort, " + + "NVL(va.ORDER_INDEX, 999999) AS siteStepSort " + + "FROM SD_VA_B_H va " + + "LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = va.BASE_ID AND NVL(hb.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = va.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " + + "LEFT JOIN SD_STTP_B sttp ON sttp.STTP_CODE = va.STTP " + + "AND NVL(sttp.IS_DELETED, 0) = 0 AND NVL(sttp.ENABLE, 1) = 1 " + + "WHERE va.STTP = 'VA' AND NVL(va.IS_DELETED, 0) = 0 "; + } + + private String buildVacFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildVacLeafCondition(filter, paramMap, indexHolder); + } + if (CollectionUtils.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildVacFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + return String.join("or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND ", conditions); + } + + private String buildVacLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + if ("isZoo".equals(field)) { + return ""; + } + Object value = filter.getValue(); + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + + if ("keyword".equals(field)) { + if (value == null || StrUtil.isBlank(String.valueOf(value))) { + return ""; + } + String paramKey = "vacParam" + indexHolder[0]++; + paramMap.put(paramKey, "%" + value + "%"); + return "(va.STNM LIKE #{map." + paramKey + "} OR hb.BASENAME LIKE #{map." + paramKey + "} OR eng.ENNM LIKE #{map." + paramKey + "})"; + } + + String column = mapVacColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("in".equals(operator)) { + List values = normalizeValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String paramKey = "vacParam" + indexHolder[0]++; + paramMap.put(paramKey, item); + placeholders.add("#{map." + paramKey + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + + String paramKey = "vacParam" + 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 "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 "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 + "}"; + default: + return ""; + } + } + + private String buildVacGroupSql(String detailSql, GroupingInfo[] groupInfos) { + List groupFields = new ArrayList<>(); + List orderItems = new ArrayList<>(); + StringBuilder sql = new StringBuilder("SELECT "); + boolean first = true; + for (GroupingInfo item : groupInfos) { + if (item == null || StrUtil.isBlank(item.getSelector())) { + continue; + } + String selector = item.getSelector(); + if (!isVacGroupSupported(selector)) { + continue; + } + if (!first) { + sql.append(", "); + } + sql.append("t.").append(selector).append(" AS ").append(selector) + .append(", COUNT(*) AS count_").append(selector); + groupFields.add("t." + selector); + orderItems.add("t." + selector + (item.getDesc() ? " DESC" : " ASC")); + first = false; + } + if (groupFields.isEmpty()) { + return "SELECT * FROM (" + detailSql + ") t WHERE 1 = 0"; + } + sql.append(" FROM (").append(detailSql).append(") t GROUP BY ") + .append(String.join(", ", groupFields)); + if (!orderItems.isEmpty()) { + sql.append(" ORDER BY ").append(String.join(", ", orderItems)); + } + return sql.toString(); + } + + private boolean isVacGroupSupported(String selector) { + return "stcd".equals(selector) + || "stnm".equals(selector) + || "sttpName".equals(selector) + || "baseId".equals(selector) + || "baseName".equals(selector) + || "ennm".equals(selector) + || "dtin".equals(selector) + || "dtinName".equals(selector) + || "bldsttCcode".equals(selector) + || "bldsttCcodeName".equals(selector); + } + + private String mapVacColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + Map columnMap = new HashMap<>(); + columnMap.put("stcd", "va.STCD"); + columnMap.put("stnm", "va.STNM"); + columnMap.put("sttpName", "sttp.STTP_NAME"); + columnMap.put("baseId", "va.BASE_ID"); + columnMap.put("baseName", "hb.BASENAME"); + columnMap.put("ennm", "eng.ENNM"); + columnMap.put("dtin", "va.DTIN"); + columnMap.put("dtinName", "CASE WHEN NVL(va.DTIN, 0) = 1 THEN '已接入' ELSE '未接入' END"); + columnMap.put("bldstt", "va.BLDSTT_CODE"); + columnMap.put("bldsttCcode", "va.BLDSTT_CODE"); + columnMap.put("bldsttCcodeName", + "CASE WHEN NVL(va.BLDSTT_CODE, 0) = 2 THEN '已建' WHEN NVL(va.BLDSTT_CODE, 0) = 1 THEN '在建' ELSE '未建/规划' END"); + columnMap.put("ststdt", "va.SWDT"); + columnMap.put("esstdt", "va.JCDT"); + columnMap.put("logo", "va.LOGO"); + columnMap.put("introduce", "va.INTRODUCE"); + columnMap.put("inffile", "va.INFFILE"); + return columnMap.get(field); + } + + private String buildVacOrderBySql(List sorts) { + if (sorts == null || sorts.isEmpty()) { + return " ORDER BY NVL(hb.ORDER_INDEX, 999999) ASC, NVL(eng.ORDER_INDEX, 999999) ASC, NVL(va.ORDER_INDEX, 999999) ASC, va.STCD ASC"; + } + List orderItems = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapVacColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + column = switch (sort.getField()) { + case "baseStepSort" -> "hb.ORDER_INDEX"; + case "rstcdStepSort" -> "eng.ORDER_INDEX"; + case "siteStepSort" -> "va.ORDER_INDEX"; + default -> null; + }; + } + 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 NVL(hb.ORDER_INDEX, 999999) ASC, NVL(eng.ORDER_INDEX, 999999) ASC, NVL(va.ORDER_INDEX, 999999) ASC, va.STCD ASC"; + } + return " ORDER BY " + String.join(", ", orderItems); + } + private String buildWvaBaseSql() { return "SELECT " + "va.STCD AS stcd, " +