diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java index d5f145ee..fd5847af 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/controller/WeFishController.java @@ -150,6 +150,12 @@ public class WeFishController { return ResponseResult.successData(weFishService.getQgcWeFishPoint(dataSourceRequest)); } + @PostMapping("/we/point/qgc/GetKendoListCust") + @Operation(summary = "环保部-水生生态调查-地图锚点") + public ResponseResult getQgcWePoint(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(weFishService.getQgcWePoint(dataSourceRequest)); + } + @PostMapping("/te/tet/spec/GetKendoListCust") @Operation(summary = "重点陆生动物二级页面") public ResponseResult getTeSpecialAnimalList(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointFishStatVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointFishStatVo.java new file mode 100644 index 00000000..89e46bf5 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointFishStatVo.java @@ -0,0 +1,18 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "水生生态调查锚点鱼类统计") +public class WePointFishStatVo { + + @Schema(description = "断面编码") + private String stcd; + + @Schema(description = "鱼类名称") + private String fishName; + + @Schema(description = "数量") + private Integer count; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointQgcVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointQgcVo.java new file mode 100644 index 00000000..736d09ab --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/entity/vo/WePointQgcVo.java @@ -0,0 +1,72 @@ +package com.yfd.platform.qgc_env.wte.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.List; + +@Data +@Schema(description = "环保部-水生生态调查-锚点") +public class WePointQgcVo { + + @Schema(description = "站点编码") + private String stcd; + + @Schema(description = "断面名称") + private String stnm; + + @Schema(description = "经度") + private BigDecimal lgtd; + + @Schema(description = "纬度") + private BigDecimal lttd; + + @Schema(description = "高程") + private BigDecimal dtmel; + + @Schema(description = "关联电站编码冗余") + private String rstcds; + + @Schema(description = "电站名称") + private String ennm; + + @Schema(description = "最新调查时间") + private String tm; + + @Schema(description = "描点状态") + private String anchoPointState; + + @Schema(description = "锚点类型") + private String sttpMap; + + @Schema(description = "站点类型") + private String sttp; + + @Schema(description = "设施类型") + private String sttpCode; + + @Schema(description = "弹框标题") + private String titleName; + + @Schema(description = "流域编码") + private String rvcd; + + @Schema(description = "行政编码") + private String addvcd; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "关联电站编码") + private String rstcd; + + @Schema(description = "沿程排序") + private Integer siteStepSort; + + @Schema(description = "地图避让") + private Integer distance; + + @Schema(description = "调查鱼类列表") + private List fishList; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java index ba33bd32..eccab325 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/WeFishService.java @@ -53,6 +53,8 @@ public interface WeFishService { DataSourceResult getQgcWeFishPoint(DataSourceRequest dataSourceRequest); + DataSourceResult getQgcWePoint(DataSourceRequest dataSourceRequest); + DataSourceResult getTeSpecialAnimalList(DataSourceRequest dataSourceRequest); List getWeDefaultData(String stcd); diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java index 35996aa1..66c1865d 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/wte/service/impl/WeFishServiceImpl.java @@ -10,6 +10,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.wt.utils.SiteAvoidanceUtils; import com.yfd.platform.qgc_env.wte.entity.vo.*; import com.yfd.platform.qgc_env.wte.service.WeFishService; import com.yfd.platform.utils.KendoUtil; @@ -1065,6 +1066,170 @@ public class WeFishServiceImpl implements WeFishService { return result; } + @Override + public DataSourceResult getQgcWePoint(DataSourceRequest dataSourceRequest) { + DataSourceResult result = new DataSourceResult<>(); + result.setAggregates(new HashMap<>()); + if (dataSourceRequest == null) { + result.setData(new ArrayList<>()); + result.setTotal(0L); + return result; + } + + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + String stcd = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "stcd"); + String startTime = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "startTime"); + String endTime = resolveWeFishStringFilterValue(dataSourceRequest, loadOptions, "endTime"); + + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("section.STCD AS stcd, ") + .append("section.STNM AS stnm, ") + .append("section.LGTD AS lgtd, ") + .append("section.LTTD AS lttd, ") + .append("section.ELEV AS dtmel, ") + .append("section.RSTCD AS rstcds, ") + .append("eng.ENNM AS ennm, ") + .append("TO_CHAR(latest.TM, 'yyyy-mm-dd hh24:mi:ss') AS tm, ") + .append("'WE' AS anchoPointState, ") + .append("'WE' AS sttpMap, ") + .append("'WE' AS sttp, ") + .append("'WE' AS sttpCode, ") + .append("section.STNM AS titleName, ") + .append("section.RVCD AS rvcd, ") + .append("section.ADDVCD AS addvcd, ") + .append("section.BASE_ID AS baseId, ") + .append("section.RSTCD AS rstcd, ") + .append("siteSort.SORT AS siteStepSort ") + .append("FROM SD_WE_B_H section ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = section.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN ( ") + .append(" SELECT STCD, MAX(TM) AS TM ") + .append(" FROM SD_WE_R ") + .append(" WHERE NVL(IS_DELETED, 0) = 0 AND STATUS = 1 ") + .append(" GROUP BY STCD ") + .append(") latest ON latest.STCD = section.STCD ") + .append("LEFT JOIN MS_ALONG_B along ON along.RVCD = section.HBRVCD ") + .append(" AND along.CODE = 'common' AND NVL(along.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN ( ") + .append(" SELECT det.SORT, cfg.RVCD, det.STCD ") + .append(" FROM MS_ALONGDET_B det ") + .append(" INNER JOIN MS_ALONG_B cfg ON det.ALONG_ID = cfg.ID ") + .append(" WHERE NVL(det.IS_DELETED, 0) = 0 ") + .append(" AND NVL(cfg.IS_DELETED, 0) = 0 ") + .append(" AND cfg.CODE = 'common' ") + .append(") siteSort ON siteSort.RVCD = section.HBRVCD AND siteSort.STCD = section.STCD ") + .append("WHERE NVL(section.USFL, 1) = 1 "); + + String filterSql = buildWePointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append("AND ").append(filterSql).append(" "); + } + sql.append(buildWePointOrderBySql(dataSourceRequest.getSort())); + + Page page = loadOptions == null ? null + : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql.toString(), + paramMap, + WePointQgcVo.class + ); + + if (CollUtil.isEmpty(list)) { + result.setData(list); + result.setTotal(page != null ? page.getTotal() : 0L); + return result; + } + + Map> fishMap = queryWePointFishMap( + list.stream().map(WePointQgcVo::getStcd).filter(StrUtil::isNotBlank).distinct().toList(), + stcd, + startTime, + endTime + ); + for (WePointQgcVo vo : list) { + vo.setFishList(fishMap.get(vo.getStcd())); + } + + SiteAvoidanceUtils.calcSiteMapLev(list, + WePointQgcVo::getStcd, + WePointQgcVo::getLgtd, + WePointQgcVo::getLttd, + WePointQgcVo::getAnchoPointState, + WePointQgcVo::setDistance); + + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + return result; + } + + private Map> queryWePointFishMap(List stcdList, + String stcd, + String startTime, + String endTime) { + Map> result = new LinkedHashMap<>(); + if (CollUtil.isEmpty(stcdList)) { + return result; + } + + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append("we.STCD AS stcd, ") + .append("dict.NAME AS fishName, ") + .append("SUM(fish.FCNT) AS count ") + .append("FROM SD_WE_R we ") + .append("INNER JOIN SD_WEFISH_R fish ON fish.WER_ID = we.ID ") + .append(" AND NVL(fish.IS_DELETED, 0) = 0 ") + .append("INNER JOIN SD_WE_B_H section ON section.STCD = we.STCD ") + .append(" AND NVL(section.USFL, 1) = 1 ") + .append("INNER JOIN ( ") + .append(" SELECT STCD, MAX(TM) AS TM ") + .append(" FROM SD_WE_R ") + .append(" WHERE NVL(IS_DELETED, 0) = 0 AND STATUS = 1 ") + .append(" GROUP BY STCD ") + .append(") latest ON latest.STCD = we.STCD AND latest.TM = we.TM ") + .append("LEFT JOIN ( ") + .append(" SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME ") + .append(" FROM SD_FISHDICTORY_RLTN_B rel ") + .append(" LEFT JOIN SD_FISHDICTORY_B dic ON rel.ZY_FISH_ID = dic.ID ") + .append(" WHERE NVL(rel.IS_DELETED, 0) = 0 ") + .append(" AND NVL(dic.IS_DELETED, 0) = 0 ") + .append(" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY') ") + .append(") dict ON fish.FTP = dict.FISH_ID AND (section.HBRVCD = dict.RVCD OR dict.RVCD = 'ZY') ") + .append("WHERE fish.FCNT IS NOT NULL ") + .append("AND NVL(we.IS_DELETED, 0) = 0 ") + .append("AND NVL(we.STATUS, 1) = 1 "); + + appendWePointInCondition(sql, paramMap, "we.STCD", stcdList, "stcdList"); + if (StrUtil.isNotBlank(stcd)) { + paramMap.put("filterStcd", stcd); + sql.append("AND we.STCD = #{map.filterStcd} "); + } + if (StrUtil.isNotBlank(startTime) && StrUtil.isNotBlank(endTime)) { + paramMap.put("startTime", startTime); + paramMap.put("endTime", endTime); + sql.append("AND we.TM BETWEEN TO_DATE(#{map.startTime}, 'yyyy-mm-dd hh24:mi:ss') ") + .append("AND TO_DATE(#{map.endTime}, 'yyyy-mm-dd hh24:mi:ss') "); + } + sql.append("GROUP BY we.STCD, dict.NAME ORDER BY SUM(fish.FCNT)"); + + List rows = microservicDynamicSQLMapper.getAllListWithResultType( + sql.toString(), + paramMap, + WePointFishStatVo.class + ); + for (WePointFishStatVo row : rows) { + if (row == null || StrUtil.isBlank(row.getStcd())) { + continue; + } + result.computeIfAbsent(row.getStcd(), key -> new ArrayList<>()).add(row); + } + return result; + } + @Override public DataSourceResult getTeSpecialAnimalList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -2489,6 +2654,94 @@ public class WeFishServiceImpl implements WeFishService { return sql.toString(); } + private String buildWePointFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + return QgcQueryWrapperUtil.buildFilterCondition(filter, paramMap, indexHolder, this::mapWePointColumn); + } + + private String mapWePointColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "section.STCD"; + case "stnm", "titleName" -> "section.STNM"; + case "ennm" -> "eng.ENNM"; + case "rvcd" -> "section.RVCD"; + case "addvcd" -> "section.ADDVCD"; + case "baseId" -> "section.BASE_ID"; + case "rstcd", "rstcds" -> "section.RSTCD"; + case "tm" -> "latest.TM"; + default -> null; + }; + } + + private String buildWePointOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY siteSort.SORT NULLS LAST"; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapWePointSortColumn(sort.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction + " NULLS LAST"); + } + if (orderByParts.isEmpty()) { + return " ORDER BY siteSort.SORT NULLS LAST"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + + private String mapWePointSortColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field) { + case "stcd" -> "section.STCD"; + case "stnm", "titleName" -> "section.STNM"; + case "ennm" -> "eng.ENNM"; + case "tm" -> "latest.TM"; + case "rvcd" -> "section.RVCD"; + case "addvcd" -> "section.ADDVCD"; + case "baseId" -> "section.BASE_ID"; + case "siteStepSort" -> "siteSort.SORT"; + default -> null; + }; + } + + private void appendWePointInCondition(StringBuilder sql, + Map paramMap, + String column, + List values, + String paramPrefix) { + if (CollUtil.isEmpty(values) || StrUtil.isBlank(column)) { + return; + } + List placeholders = new ArrayList<>(); + int index = 0; + for (String value : values) { + if (StrUtil.isBlank(value)) { + continue; + } + String key = paramPrefix + "_" + index++; + paramMap.put(key, value); + placeholders.add("#{map." + key + "}"); + } + if (CollUtil.isEmpty(placeholders)) { + return; + } + sql.append("AND ").append(column).append(" IN (") + .append(String.join(", ", placeholders)) + .append(") "); + } + private String buildTeSpecialAnimalDetailSql() { return "SELECT DISTINCT " + "b.ID AS id, " +