feat: 环保部-过鱼设施描点接口

This commit is contained in:
tangwei 2026-07-09 08:53:03 +08:00
parent ab084c2f7c
commit 1240ad91af
5 changed files with 337 additions and 2 deletions

View File

@ -106,6 +106,12 @@ public class FishPassageController {
return ResponseResult.successData(fpBuildService.getStInfoByStcd(stcd));
}
@PostMapping("/point/qgc/GetKendoListCust")
@Operation(summary = "环保部-过鱼设施描点接口")
public ResponseResult getQgcFpPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {
return ResponseResult.successData(fpBuildService.getQgcFpPointKendoListCust(dataSourceRequest));
}
@PostMapping("/point/built/GetKendoListCust")
@Operation(summary = "过鱼设施地图描点接口(仅查询在建状态的)")
public ResponseResult getFpBuiltPointKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) {

View File

@ -15,6 +15,9 @@ public class FpAnchoPointVo {
@Schema(description = "站名")
private String stnm;
@Schema(description = "站点图片")
private String logo;
@Schema(description = "弹框站点名称")
private String titleName;
@ -45,6 +48,9 @@ public class FpAnchoPointVo {
@Schema(description = "运行状态")
private String run;
@Schema(description = "运行状态名称")
private String runName;
@Schema(description = "设施类型")
private String dwtp;
@ -78,9 +84,21 @@ public class FpAnchoPointVo {
@Schema(description = "达标状态子类型")
private Integer stdSstate;
@Schema(description = "达标状态子类型名称")
private String stdSstateName;
@Schema(description = "地图避让")
private Integer distance;
@Schema(description = "澜沧江运行状态")
private Integer lcjStatus;
@Schema(description = "澜沧江运行状态名称")
private String lcjStatusName;
@Schema(description = "年份")
private String yr;
@Schema(description = "过鱼种类")
private Integer ftpTypeCount;

View File

@ -0,0 +1,21 @@
package com.yfd.platform.qgc_env.fp.entity.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Data
@Schema(description = "过鱼设施鱼类统计")
public class FpFishStatisticsVo {
@Schema(description = "站点编码")
private String stcd;
@Schema(description = "鱼类名称")
private String ftp;
@Schema(description = "鱼编码")
private String fishId;
@Schema(description = "数量")
private Integer count;
}

View File

@ -21,5 +21,7 @@ public interface FpBuildService {
FpVmsstbprptVo getStInfoByStcd(String stcd);
DataSourceResult<FpAnchoPointVo> getQgcFpPointKendoListCust(DataSourceRequest dataSourceRequest);
DataSourceResult<FpAnchoPointVo> getFpBuiltPointKendoListCust(DataSourceRequest dataSourceRequest);
}

View File

@ -14,6 +14,7 @@ import com.yfd.platform.common.exception.BizException;
import com.yfd.platform.qgc_env.fp.entity.vo.FpAnchoPointVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpConstructionSituationVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpFishDicVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpFishStatisticsVo;
import com.yfd.platform.qgc_env.fp.entity.vo.FpVmsstbprptVo;
import com.yfd.platform.qgc_env.wt.utils.SiteAvoidanceUtils;
import com.yfd.platform.qgc_env.fp.service.FpBuildService;
@ -28,6 +29,8 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@Service
public class FpBuildServiceImpl implements FpBuildService {
@ -214,6 +217,99 @@ public class FpBuildServiceImpl implements FpBuildService {
return list.getFirst();
}
@Override
public DataSourceResult<FpAnchoPointVo> getQgcFpPointKendoListCust(DataSourceRequest dataSourceRequest) {
DataSourceResult<FpAnchoPointVo> dataSourceResult = new DataSourceResult<>();
dataSourceResult.setAggregates(new HashMap<>());
if (dataSourceRequest == null) {
dataSourceResult.setData(new ArrayList<>());
dataSourceResult.setTotal(0L);
return dataSourceResult;
}
StringBuilder sql = new StringBuilder("SELECT " +
"fp.STCD AS stcd, " +
"fp.STNM AS stnm, " +
"fp.LOGO AS logo, " +
"fp.STNM AS titleName, " +
"fp.BLDSTT_CODE AS bldsttCcode, " +
"fp.BLDSTT_CODE AS bldstt, " +
"fp.LTTD AS lttd, " +
"fp.LGTD AS lgtd, " +
"fp.ELEV AS dtmel, " +
"fp.RSTCD AS rstcds, " +
"eng.ENNM AS ennm, " +
"'FP' AS sttpCode, " +
"state.RUN_STATE AS run, " +
"CASE WHEN state.RUN_STATE = 1 THEN '运行中' WHEN state.RUN_STATE IN (0, 2) THEN '未运行' ELSE NULL END AS runName, " +
"fp.STTP AS dwtp, " +
"CASE " +
"WHEN fp.STTP = 'FP_1' THEN '鱼道' " +
"WHEN fp.STTP = 'FP_2' THEN '仿自然通道' " +
"WHEN fp.STTP = 'FP_3' THEN '集运鱼系统' " +
"WHEN fp.STTP = 'FP_4' THEN '升鱼机' " +
"ELSE '其它' END AS dwtpName, " +
"fp.STTP AS sttpMap, " +
"eng.RVCD AS rvcd, " +
"eng.ADDVCD AS addvcd, " +
"eng.BASE_ID AS baseId, " +
"fp.STTP AS sttp, " +
"CASE " +
"WHEN fp.STTP = 'FP_1' THEN 'GY_1' " +
"WHEN fp.STTP = 'FP_2' THEN 'GY_2' " +
"WHEN fp.STTP = 'FP_3' THEN 'GY_3' " +
"WHEN fp.STTP = 'FP_4' THEN 'GY_4' " +
"ELSE 'GY_5' END AS anchoPointState, " +
"fp.MWAY AS mway, " +
"fp.DTIN AS dtin, " +
"state.STD_SSTATE AS stdSstate, " +
"CASE WHEN state.STD_SSTATE = 1 THEN '正常运行' " +
"WHEN state.STD_SSTATE IN (0, 2) THEN '暂无数据' " +
"WHEN state.STD_SSTATE = 3 THEN '未正常运行' ELSE NULL END AS stdSstateName, " +
"CASE WHEN recent.STCD IS NULL THEN 2 ELSE 1 END AS lcjStatus, " +
"CASE WHEN recent.STCD IS NULL THEN '暂无数据' ELSE '正常运行' END AS lcjStatusName, " +
"fp.ORDER_INDEX AS orderIndex " +
"FROM SD_FPSS_B_H fp " +
"LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
"LEFT JOIN (SELECT s.STCD, s.RUN_STATE, s.STD_SSTATE " +
" FROM MS_STSTATE_T s " +
" INNER JOIN (SELECT STCD, MAX(YR) AS YR FROM MS_STSTATE_T WHERE NVL(IS_DELETED, 0) = 0 GROUP BY STCD) latest " +
" ON latest.STCD = s.STCD AND latest.YR = s.YR " +
" WHERE NVL(s.IS_DELETED, 0) = 0) state ON state.STCD = fp.STCD " +
"LEFT JOIN (SELECT STCD FROM SD_FPSSRL_R WHERE NVL(IS_DELETED, 0) = 0 AND TM BETWEEN ADD_MONTHS(SYSDATE, -12) AND SYSDATE GROUP BY STCD " +
" UNION " +
" SELECT STCD FROM SD_FPSS_R WHERE NVL(IS_DELETED, 0) = 0 AND STRDT >= ADD_MONTHS(SYSDATE, -12) AND NVL(ENDDT, STRDT) <= SYSDATE GROUP BY STCD) recent " +
"ON recent.STCD = fp.STCD " +
"WHERE NVL(fp.IS_DELETED, 0) = 0 ");
Map<String, Object> paramMap = new HashMap<>();
DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest();
String filterSql = buildFpPointFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0});
if (StrUtil.isNotBlank(filterSql)) {
sql.append(" AND ").append(filterSql).append(" ");
}
sql.append(buildFpPointOrderBySql(dataSourceRequest.getSort()));
Page<?> page = QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake());
List<FpAnchoPointVo> resultList = microservicDynamicSQLMapper.pageAllListWithResultType(
page, sql.toString(), paramMap, FpAnchoPointVo.class);
if (CollUtil.isNotEmpty(resultList)) {
fillQgcFpPointStatistics(resultList);
applyFpPointLegend(resultList);
SiteAvoidanceUtils.calcSiteMapLev(resultList,
FpAnchoPointVo::getStcd,
FpAnchoPointVo::getLgtd,
FpAnchoPointVo::getLttd,
FpAnchoPointVo::getAnchoPointState,
FpAnchoPointVo::setDistance);
}
dataSourceResult.setData(resultList);
dataSourceResult.setTotal(page == null ? resultList.size() : page.getTotal());
return dataSourceResult;
}
private String buildFishDicBaseSql() {
return "SELECT " +
"src.ID AS id, " +
@ -1232,6 +1328,193 @@ public class FpBuildServiceImpl implements FpBuildService {
return dataSourceResult;
}
private void fillQgcFpPointStatistics(List<FpAnchoPointVo> pointList) {
List<String> stcdList = pointList.stream()
.map(FpAnchoPointVo::getStcd)
.filter(StrUtil::isNotBlank)
.distinct()
.collect(Collectors.toList());
if (CollUtil.isEmpty(stcdList)) {
return;
}
String year = queryLatestFpYear(stcdList);
List<FpFishStatisticsVo> manualList = queryQgcFpManualFishStatistics(stcdList, year);
Set<String> manualStcdSet = manualList.stream()
.map(FpFishStatisticsVo::getStcd)
.filter(StrUtil::isNotBlank)
.collect(Collectors.toSet());
List<String> autoQueryStcdList = stcdList.stream()
.filter(stcd -> !manualStcdSet.contains(stcd))
.collect(Collectors.toList());
List<FpFishStatisticsVo> autoList = queryQgcFpAutoFishStatistics(autoQueryStcdList, year);
if (CollUtil.isNotEmpty(autoList)) {
manualList.addAll(autoList);
}
Map<String, List<FpFishStatisticsVo>> stcdDataMap = manualList.stream()
.collect(Collectors.groupingBy(FpFishStatisticsVo::getStcd));
for (FpAnchoPointVo vo : pointList) {
vo.setYr(year);
List<FpFishStatisticsVo> fishStatistics = stcdDataMap.get(vo.getStcd());
if (CollUtil.isEmpty(fishStatistics)) {
continue;
}
vo.setFtpTypeCount(fishStatistics.size());
vo.setFtpCount(fishStatistics.stream()
.filter(item -> item.getCount() != null)
.mapToInt(FpFishStatisticsVo::getCount)
.sum());
}
}
private String queryLatestFpYear(List<String> stcdList) {
Map<String, Object> paramMap = new HashMap<>();
StringBuilder sql = new StringBuilder("SELECT MAX(t.YR) AS yr FROM (" +
"SELECT TO_CHAR(STRDT, 'yyyy') AS YR, STCD FROM SD_FPSS_R WHERE NVL(IS_DELETED, 0) = 0 " +
"UNION ALL " +
"SELECT TO_CHAR(TM, 'yyyy') AS YR, STCD FROM SD_FPSSRL_R WHERE NVL(IS_DELETED, 0) = 0) t WHERE 1 = 1 ");
appendInCondition(sql, paramMap, "t.STCD", stcdList, "fpYear");
List<FpAnchoPointVo> list = microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpAnchoPointVo.class);
if (CollUtil.isEmpty(list) || StrUtil.isBlank(list.getFirst().getYr())) {
return String.valueOf(java.time.LocalDate.now().getYear());
}
return list.getFirst().getYr();
}
private List<FpFishStatisticsVo> queryQgcFpManualFishStatistics(List<String> stcdList, String year) {
if (CollUtil.isEmpty(stcdList)) {
return new ArrayList<>();
}
Map<String, Object> paramMap = new HashMap<>();
StringBuilder sql = new StringBuilder("SELECT data.STCD AS stcd, data.FTP AS fishId, dict.NAME AS ftp, SUM(data.FCNT) AS count " +
"FROM (SELECT t.STCD, t.FTP, t.FCNT, eng.HBRVCD " +
" FROM SD_FPSS_R t " +
" INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD AND NVL(fp.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
" WHERE NVL(t.IS_DELETED, 0) = 0 ");
paramMap.put("manualYear", year);
sql.append(" AND TO_CHAR(t.STRDT, 'yyyy') = #{map.manualYear}) data ")
.append("INNER JOIN (SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME " +
" FROM SD_FISHDICTORY_RLTN_B rel " +
" LEFT JOIN SD_FISHDICTORY_B dic ON dic.ID = rel.ZY_FISH_ID " +
" WHERE NVL(rel.IS_DELETED, 0) = 0 AND NVL(dic.IS_DELETED, 0) = 0 " +
" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY')) dict " +
"ON dict.FISH_ID = data.FTP AND (dict.RVCD = data.HBRVCD OR dict.RVCD = 'ZY') WHERE 1 = 1 ");
appendInCondition(sql, paramMap, "data.STCD", stcdList, "fpManual");
sql.append(" GROUP BY data.STCD, data.FTP, dict.NAME");
return microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpFishStatisticsVo.class);
}
private List<FpFishStatisticsVo> queryQgcFpAutoFishStatistics(List<String> stcdList, String year) {
if (CollUtil.isEmpty(stcdList)) {
return new ArrayList<>();
}
Map<String, Object> paramMap = new HashMap<>();
StringBuilder sql = new StringBuilder("SELECT data.STCD AS stcd, data.FTP AS fishId, dict.NAME AS ftp, SUM(data.FCNT) AS count " +
"FROM (SELECT t.STCD, t.FTP, t.FCNT, eng.HBRVCD " +
" FROM SD_FPSSRL_R t " +
" INNER JOIN SD_FPSS_B_H fp ON fp.STCD = t.STCD AND NVL(fp.IS_DELETED, 0) = 0 " +
" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fp.RSTCD AND NVL(eng.IS_DELETED, 0) = 0 " +
" WHERE NVL(t.IS_DELETED, 0) = 0 ");
paramMap.put("autoYear", year);
sql.append(" AND TO_CHAR(t.TM, 'yyyy') = #{map.autoYear}) data ")
.append("INNER JOIN (SELECT DISTINCT rel.FISH_ID, rel.RVCD, dic.NAME " +
" FROM SD_FISHDICTORY_RLTN_B rel " +
" LEFT JOIN SD_FISHDICTORY_B dic ON dic.ID = rel.ZY_FISH_ID " +
" WHERE NVL(rel.IS_DELETED, 0) = 0 AND NVL(dic.IS_DELETED, 0) = 0 " +
" AND (rel.FISH_ID <> rel.ZY_FISH_ID OR rel.RVCD = 'ZY')) dict " +
"ON dict.FISH_ID = data.FTP AND (dict.RVCD = data.HBRVCD OR dict.RVCD = 'ZY') WHERE 1 = 1 ");
appendInCondition(sql, paramMap, "data.STCD", stcdList, "fpAuto");
sql.append(" GROUP BY data.STCD, data.FTP, dict.NAME");
return microservicDynamicSQLMapper.getAllListWithResultType(sql.toString(), paramMap, FpFishStatisticsVo.class);
}
private void applyFpPointLegend(List<FpAnchoPointVo> voList) {
for (FpAnchoPointVo pointVo : voList) {
if (!"2".equals(pointVo.getBldstt())) {
if ("FP_1".equals(pointVo.getSttp())) {
pointVo.setAnchoPointState("GY_1_INCOMPLETE");
} else if ("FP_2".equals(pointVo.getSttp())) {
pointVo.setAnchoPointState("GY_2_INCOMPLETE");
} else if ("FP_3".equals(pointVo.getSttp())) {
pointVo.setAnchoPointState("GY_3_INCOMPLETE");
} else if ("FP_4".equals(pointVo.getSttp())) {
pointVo.setAnchoPointState("GY_4_INCOMPLETE");
} else {
pointVo.setAnchoPointState("GY_5_INCOMPLETE");
}
}
}
}
private void appendInCondition(StringBuilder sql,
Map<String, Object> paramMap,
String column,
List<String> values,
String prefix) {
if (CollUtil.isEmpty(values)) {
return;
}
List<String> placeholders = new ArrayList<>();
int index = 0;
for (String value : values) {
if (StrUtil.isBlank(value)) {
continue;
}
String key = prefix + 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 buildFpPointOrderBySql(List<DataSourceRequest.SortDescriptor> sorts) {
if (CollUtil.isEmpty(sorts)) {
return " ORDER BY fp.ORDER_INDEX ASC NULLS LAST, fp.STCD ASC";
}
List<String> orderItems = new ArrayList<>();
for (DataSourceRequest.SortDescriptor sort : sorts) {
if (sort == null || StrUtil.isBlank(sort.getField())) {
continue;
}
String column = mapFpPointOrderColumn(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 fp.ORDER_INDEX ASC NULLS LAST, fp.STCD ASC";
}
return " ORDER BY " + String.join(", ", orderItems);
}
private String mapFpPointOrderColumn(String field) {
if (StrUtil.isBlank(field)) {
return null;
}
return switch (field) {
case "stcd" -> "fp.STCD";
case "stnm", "titleName" -> "fp.STNM";
case "bldsttCcode", "bldstt" -> "fp.BLDSTT_CODE";
case "lgtd" -> "fp.LGTD";
case "lttd" -> "fp.LTTD";
case "ennm" -> "eng.ENNM";
case "baseId" -> "eng.BASE_ID";
case "rvcd" -> "eng.RVCD";
case "addvcd" -> "eng.ADDVCD";
case "run" -> "state.RUN_STATE";
case "stdSstate" -> "state.STD_SSTATE";
default -> null;
};
}
private String mapFpColumn(String field) {
if (StrUtil.isBlank(field)) {
return null;
@ -1240,7 +1523,6 @@ public class FpBuildServiceImpl implements FpBuildService {
case "bldsttccode" -> "fp.BLDSTT_CODE";
case "lgtd" -> "fp.LGTD";
case "lttd" -> "fp.LTTD";
case "fhstcd" -> "fp.FHSTCD";
default -> null;
};
}
@ -1285,6 +1567,12 @@ public class FpBuildServiceImpl implements FpBuildService {
case "rvcd" -> "eng.RVCD";
case "addvcd" -> "eng.ADDVCD";
case "sttp" -> "fp.STTP";
case "bldsttCcode", "bldstt" -> "fp.BLDSTT_CODE";
case "lgtd" -> "fp.LGTD";
case "lttd" -> "fp.LTTD";
case "run" -> "state.RUN_STATE";
case "stdSstate" -> "state.STD_SSTATE";
case "lcjStatus" -> "CASE WHEN recent.STCD IS NULL THEN 2 ELSE 1 END";
default -> null;
};
if (column == null) {