diff --git a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java index fb55233..8188f10 100644 --- a/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SecurityConfig.java @@ -61,6 +61,8 @@ public class SecurityConfig { .requestMatchers("/env/**").permitAll() .requestMatchers("/wt/**").permitAll() .requestMatchers("/wq/**").permitAll() + .requestMatchers("/fp/**").permitAll() + .requestMatchers("/fh/**").permitAll() .requestMatchers("/data/**").permitAll() .requestMatchers("/sms/**").permitAll() .requestMatchers(HttpMethod.GET, "/").permitAll() diff --git a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java index 6a096e4..283b05d 100644 --- a/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java +++ b/backend/src/main/java/com/yfd/platform/config/SwaggerConfig.java @@ -76,6 +76,24 @@ public class SwaggerConfig { .build(); } + @Bean + public GroupedOpenApi groupEnvFPApi() { + return GroupedOpenApi.builder() + .group("3.2 全过程-生态环保数据服务-过鱼设施") + .packagesToScan("com.yfd.platform.env.fp.controller") + .build(); + } + + @Bean + public GroupedOpenApi groupEnvFHApi() { + return GroupedOpenApi.builder() + .group("3.2 全过程-生态环保数据服务-栖息地") + .packagesToScan("com.yfd.platform.env.fh.controller") + .build(); + } + + + @Bean public GroupedOpenApi groupEngApi() { diff --git a/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java b/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java new file mode 100644 index 0000000..e881489 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/controller/FhHabitatController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.env.fh.controller; + +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; +import com.yfd.platform.env.fh.service.FhHabitatService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/fh") +@Tag(name = "栖息地统计") +@Validated +public class FhHabitatController { + + @Resource + private FhHabitatService fhHabitatService; + + @PostMapping("/default/getFhList") + @Operation(summary = "获取默认有数据的栖息地站点信息") + public ResponseResult getDefaultFhList(@RequestBody FhDefaultAo fhDefaultAo) { + return ResponseResult.successData(fhHabitatService.getDefaultFhList(fhDefaultAo)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/fh/entity/ao/FhDefaultAo.java b/backend/src/main/java/com/yfd/platform/env/fh/entity/ao/FhDefaultAo.java new file mode 100644 index 0000000..ab6309a --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/entity/ao/FhDefaultAo.java @@ -0,0 +1,20 @@ +package com.yfd.platform.env.fh.entity.ao; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.Date; + +@Data +@Schema(description = "栖息地默认数据信息") +public class FhDefaultAo { + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "开始时间") + private Date sdt; + + @Schema(description = "结束时间") + private Date edt; +} diff --git a/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/FhDefaultVo.java b/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/FhDefaultVo.java new file mode 100644 index 0000000..1aec0c8 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/entity/vo/FhDefaultVo.java @@ -0,0 +1,56 @@ +package com.yfd.platform.env.fh.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.experimental.Accessors; + +@Data +@Accessors(chain = true) +@Schema(description = "栖息地默认数据结果") +public class FhDefaultVo { + + @Schema(description = "站点编码") + private String stcd; + + @Schema(description = "站点名称") + private String stnm; + + @Schema(description = "水温站编码") + private String wtstcd; + + @Schema(description = "水温站名称") + private String wtstnm; + + @Schema(description = "基地编码") + private String baseId; + + @Schema(description = "基地名称") + private String baseName; + + @Schema(description = "基地流域编码") + private String hbrvcd; + + @Schema(description = "基地流域名称") + private String hbrvcdName; + + @Schema(description = "栖息地编码") + private String fhstcd; + + @Schema(description = "栖息地名称") + private String fhstnm; + + @Schema(description = "数据数量") + private Integer dataStatus; + + @Schema(description = "站点类型编码") + private String sttpCode; + + @Schema(description = "站点类型名称") + private String sttpName; + + @Schema(description = "流量站编码") + private String zqstcd; + + @Schema(description = "流量站名称") + private String zqstnm; +} diff --git a/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java b/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java new file mode 100644 index 0000000..f4c287f --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/service/FhHabitatService.java @@ -0,0 +1,9 @@ +package com.yfd.platform.env.fh.service; + +import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; +import com.yfd.platform.env.fh.entity.vo.FhDefaultVo; + +public interface FhHabitatService { + + FhDefaultVo getDefaultFhList(FhDefaultAo fhDefaultAo); +} diff --git a/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java new file mode 100644 index 0000000..1d6e819 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fh/service/impl/FhHabitatServiceImpl.java @@ -0,0 +1,149 @@ +package com.yfd.platform.env.fh.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.env.fh.entity.ao.FhDefaultAo; +import com.yfd.platform.env.fh.entity.vo.FhDefaultVo; +import com.yfd.platform.env.fh.service.FhHabitatService; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +@Service +public class FhHabitatServiceImpl implements FhHabitatService { + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + @Override + public FhDefaultVo getDefaultFhList(FhDefaultAo fhDefaultAo) { + Map paramMap = new LinkedHashMap<>(); + paramMap.put("baseId", fhDefaultAo == null ? null : fhDefaultAo.getBaseId()); + paramMap.put("sdt", fhDefaultAo == null ? null : fhDefaultAo.getSdt()); + paramMap.put("edt", fhDefaultAo == null ? null : fhDefaultAo.getEdt()); + + List> rows = microservicDynamicSQLMapper.getAllList(buildDefaultFhListSql(fhDefaultAo), paramMap); + if (rows == null || rows.isEmpty()) { + return new FhDefaultVo(); + } + + List list = new ArrayList<>(rows.size()); + for (Map row : rows) { + list.add(BeanUtil.fillBeanWithMap( + row, + new FhDefaultVo(), + CopyOptions.create().setIgnoreCase(true).setIgnoreError(true) + )); + } + + Map> groupByFh = new LinkedHashMap<>(); + for (FhDefaultVo item : list) { + groupByFh.computeIfAbsent(item.getFhstcd(), key -> new ArrayList<>()).add(item); + } + + List result = new ArrayList<>(); + for (Map.Entry> entry : groupByFh.entrySet()) { + List values = entry.getValue(); + FhDefaultVo merged = new FhDefaultVo(); + merged.setFhstcd(entry.getKey()) + .setFhstnm(values.get(0).getFhstnm()) + .setBaseId(values.get(0).getBaseId()) + .setBaseName(values.get(0).getBaseName()) + .setHbrvcd(values.get(0).getHbrvcd()) + .setHbrvcdName(values.get(0).getHbrvcdName()); + for (FhDefaultVo value : values) { + if ("WTRV".equals(value.getSttpCode())) { + merged.setWtstcd(value.getStcd()).setWtstnm(value.getStnm()); + } else if ("ZQ".equals(value.getSttpCode())) { + merged.setZqstcd(value.getStcd()).setZqstnm(value.getStnm()); + } + } + result.add(merged); + } + + for (FhDefaultVo item : result) { + if (StrUtil.isNotBlank(item.getWtstcd()) && StrUtil.isNotBlank(item.getZqstcd())) { + return item; + } + } + return result.get(0); + } + + private String buildDefaultFhListSql(FhDefaultAo fhDefaultAo) { + String dateConditionWtrv = ""; + String dateConditionZq = ""; + if (fhDefaultAo != null && fhDefaultAo.getSdt() != null && fhDefaultAo.getEdt() != null) { + dateConditionWtrv = " AND dayData.DT BETWEEN #{map.sdt} AND #{map.edt} "; + dateConditionZq = " AND riverDay.DT BETWEEN #{map.sdt} AND #{map.edt} "; + } + + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM ("); + sql.append(" SELECT wt.STCD AS stcd, "); + sql.append(" wt.STNM AS stnm, "); + sql.append(" eng.BASE_ID AS baseId, "); + sql.append(" hb.BASENAME AS baseName, "); + sql.append(" eng.HBRVCD AS hbrvcd, "); + sql.append(" hbrv.HBRVNM AS hbrvcdName, "); + sql.append(" fh.STCD AS fhstcd, "); + sql.append(" fh.STNM AS fhstnm, "); + sql.append(" 'WTRV' AS sttpCode, "); + sql.append(" '河道水温站' AS sttpName, "); + sql.append(" (SELECT COUNT(*) FROM SD_WTRVDAY_S dayData "); + sql.append(" WHERE dayData.STCD = wt.STCD "); + sql.append(" AND NVL(dayData.IS_DELETED, 0) = 0 "); + sql.append(dateConditionWtrv); + sql.append(" ) AS dataStatus "); + sql.append(" FROM SD_WT_B_H wt "); + sql.append(" INNER JOIN SD_FHBT_B_H fh ON fh.STCD = wt.FHSTCD AND NVL(fh.IS_DELETED, 0) = 0 "); + sql.append(" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = wt.RSTCD "); + sql.append(" LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) "); + sql.append(" LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(fh.HBRVCD, eng.HBRVCD) "); + sql.append(" AND hbrv.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) "); + sql.append(" AND NVL(hbrv.IS_DELETED, 0) = 0 "); + sql.append(" WHERE wt.STTP = 'WTRV' "); + sql.append(" AND NVL(wt.IS_DELETED, 0) = 0 "); + sql.append(" AND wt.FHSTCD IS NOT NULL "); + if (fhDefaultAo != null && StrUtil.isNotBlank(fhDefaultAo.getBaseId())) { + sql.append(" AND NVL(fh.BASE_ID, eng.BASE_ID) = #{map.baseId} "); + } + sql.append(" UNION ALL "); + sql.append(" SELECT river.STCD AS stcd, "); + sql.append(" river.STNM AS stnm, "); + sql.append(" eng.BASE_ID AS baseId, "); + sql.append(" hb.BASENAME AS baseName, "); + sql.append(" eng.HBRVCD AS hbrvcd, "); + sql.append(" hbrv.HBRVNM AS hbrvcdName, "); + sql.append(" fh.STCD AS fhstcd, "); + sql.append(" fh.STNM AS fhstnm, "); + sql.append(" 'ZQ' AS sttpCode, "); + sql.append(" '流量站' AS sttpName, "); + sql.append(" (SELECT COUNT(*) FROM SD_RIVERDAY_S riverDay "); + sql.append(" WHERE riverDay.STCD = river.STCD "); + sql.append(" AND NVL(riverDay.IS_DELETED, 0) = 0 "); + sql.append(dateConditionZq); + sql.append(" ) AS dataStatus "); + sql.append(" FROM SD_RIVER_B_H river "); + sql.append(" INNER JOIN SD_FHBT_B_H fh ON fh.STCD = river.FHSTCD AND NVL(fh.IS_DELETED, 0) = 0 "); + sql.append(" LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = river.RSTCD "); + sql.append(" LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) "); + sql.append(" LEFT JOIN SD_HBRV_DIC hbrv ON hbrv.HBRVCD = NVL(fh.HBRVCD, eng.HBRVCD) "); + sql.append(" AND hbrv.BASEID = NVL(fh.BASE_ID, eng.BASE_ID) "); + sql.append(" AND NVL(hbrv.IS_DELETED, 0) = 0 "); + sql.append(" WHERE river.STTP = 'ZQ' "); + sql.append(" AND NVL(river.IS_DELETED, 0) = 0 "); + sql.append(" AND river.FHSTCD IS NOT NULL "); + if (fhDefaultAo != null && StrUtil.isNotBlank(fhDefaultAo.getBaseId())) { + sql.append(" AND NVL(fh.BASE_ID, eng.BASE_ID) = #{map.baseId} "); + } + sql.append(") t WHERE t.dataStatus > 0 "); + sql.append("ORDER BY t.fhstcd, t.sttpCode, t.dataStatus DESC"); + return sql.toString(); + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/fp/controller/FpRunController.java b/backend/src/main/java/com/yfd/platform/env/fp/controller/FpRunController.java new file mode 100644 index 0000000..fbcc43c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fp/controller/FpRunController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.env.fp.controller; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.env.fp.service.FpRunService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/fp/run") +@Tag(name = "过鱼设施建设及运行情况") +@Validated +public class FpRunController { + + @Resource + private FpRunService fpRunService; + + @PostMapping("/secondPlan/qgc/GetKendoListCust") + @Operation(summary = "环保部-建设及运行运行情况(二级级页面 已建设施运行情况-计划接口)") + public ResponseResult getQgcSecondPlanKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fpRunService.processQgcSecondPlanKendoList(dataSourceRequest)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FdFishVo.java b/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FdFishVo.java new file mode 100644 index 0000000..210e89b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FdFishVo.java @@ -0,0 +1,15 @@ +package com.yfd.platform.env.fp.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +@Schema(description = "过鱼鱼类信息") +public class FdFishVo { + + @Schema(description = "鱼类编码") + private String ftp; + + @Schema(description = "鱼类名称") + private String name; +} diff --git a/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FpRunPlanVo.java b/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FpRunPlanVo.java new file mode 100644 index 0000000..6f2c545 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fp/entity/vo/FpRunPlanVo.java @@ -0,0 +1,47 @@ +package com.yfd.platform.env.fp.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.util.List; + +@Data +@Schema(description = "过鱼设施运行情况二级弹窗标题数据") +public class FpRunPlanVo { + + @Schema(description = "设施编码") + private String stcd; + + @Schema(description = "计划开始月份") + private String designStartDate; + + @Schema(description = "计划结束月份") + private String designEndDate; + + @Schema(description = "计划运行月数") + private Integer mon; + + @Schema(description = "计划运行频次") + private Integer pyRate; + + @Schema(description = "计划运行次数") + private Integer pycnt; + + @Schema(description = "设施类型编码") + private String sttpCode; + + @Schema(description = "过鱼类型 0鱼道 1过鱼机") + private Integer dwtp; + + @Schema(description = "计划过鱼种类") + private String planFtp; + + @Schema(description = "计划过鱼列表") + private List planList; + + @Schema(description = "设计过鱼列表") + private List designList; + + @Schema(description = "过鱼对象列表") + private List objList; +} diff --git a/backend/src/main/java/com/yfd/platform/env/fp/service/FpRunService.java b/backend/src/main/java/com/yfd/platform/env/fp/service/FpRunService.java new file mode 100644 index 0000000..b531a5c --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fp/service/FpRunService.java @@ -0,0 +1,10 @@ +package com.yfd.platform.env.fp.service; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.env.fp.entity.vo.FpRunPlanVo; + +public interface FpRunService { + + DataSourceResult processQgcSecondPlanKendoList(DataSourceRequest dataSourceRequest); +} diff --git a/backend/src/main/java/com/yfd/platform/env/fp/service/impl/FpRunServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/fp/service/impl/FpRunServiceImpl.java new file mode 100644 index 0000000..e06ec8e --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/env/fp/service/impl/FpRunServiceImpl.java @@ -0,0 +1,177 @@ +package com.yfd.platform.env.fp.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.bean.copier.CopyOptions; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import com.yfd.platform.common.DataSourceLoadOptionsBase; +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.common.DataSourceResult; +import com.yfd.platform.common.MicroservicDynamicSQLMapper; +import com.yfd.platform.common.exception.BizException; +import com.yfd.platform.env.fp.entity.vo.FpRunPlanVo; +import com.yfd.platform.env.fp.service.FpRunService; +import com.yfd.platform.utils.QgcQueryWrapperUtil; +import jakarta.annotation.Resource; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Service +public class FpRunServiceImpl implements FpRunService { + + private static final String FP_1 = "FP_1"; + private static final String FP_2 = "FP_2"; + private static final Pattern FISH_NAME_PATTERN = Pattern.compile("name\\s*[::]\\s*([^,,}\\]]+)"); + + @Resource + private MicroservicDynamicSQLMapper microservicDynamicSQLMapper; + + @Override + public DataSourceResult processQgcSecondPlanKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest.toDevRequest(); + String stcd = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String yr = QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "yr"); + if (StrUtil.isBlank(stcd)) { + throw new BizException("设施编码(stcd)不能为空."); + } + if (StrUtil.isBlank(yr)) { + throw new BizException("年份(yr)不能为空."); + } + + Map paramMap = new HashMap<>(); + paramMap.put("stcd", stcd); + paramMap.put("yr", yr); + + Map row = microservicDynamicSQLMapper.getOneBySql(buildQgcSecondPlanSql(), paramMap); + FpRunPlanVo vo = row == null || row.isEmpty() + ? new FpRunPlanVo() + : BeanUtil.fillBeanWithMap( + row, + new FpRunPlanVo(), + CopyOptions.create().setIgnoreCase(true).setIgnoreError(true) + ); + + String fallbackFishJson = row == null ? null : Convert.toStr(row.get("fallbackFishJson"), null); + String fallbackFishText = row == null ? null : Convert.toStr(row.get("fallbackFishText"), null); + if (StrUtil.isBlank(vo.getPlanFtp())) { + vo.setPlanFtp(resolveFallbackFishText(fallbackFishJson, fallbackFishText)); + } + + if (StrUtil.isNotBlank(vo.getDesignStartDate()) && StrUtil.isNotBlank(vo.getDesignEndDate())) { + try { + int startMonth = Integer.parseInt(vo.getDesignStartDate()); + int endMonth = Integer.parseInt(vo.getDesignEndDate()); + vo.setMon(Math.abs(endMonth - startMonth) + 1); + } catch (Exception ignored) { + // Keep the old behavior: ignore invalid month format and return the raw values. + } + } + + if (FP_1.equals(vo.getSttpCode()) || FP_2.equals(vo.getSttpCode())) { + vo.setDwtp(0); + } else { + vo.setDwtp(1); + if (vo.getPycnt() != null && vo.getPycnt() != 0 && vo.getMon() != null && vo.getMon() != 0) { + vo.setPyRate(new BigDecimal(vo.getPycnt()) + .divide(new BigDecimal(vo.getMon()), 2, RoundingMode.HALF_UP) + .intValue()); + } + } + + DataSourceResult result = new DataSourceResult<>(); + result.setData(Collections.singletonList(vo)); + result.setTotal(1L); + result.setAggregates(new HashMap<>()); + return result; + } + + private String buildQgcSecondPlanSql() { + return "SELECT t.STCD AS stcd, " + + " t2.stm AS designStartDate, " + + " t2.edm AS designEndDate, " + + " t2.pycnt AS pycnt, " + + " NULL AS pyRate, " + + " t.STTP AS sttpCode, " + + " t1.planFtp AS planFtp, " + + " t.ZYGYDX AS fallbackFishJson, " + + " NVL(t.ZYGYDXMS, t.JGGYDXMS) AS fallbackFishText " + + "FROM SD_FPSS_B_H t " + + "LEFT JOIN ( " + + " SELECT a.STCD, " + + " REGEXP_REPLACE(LISTAGG(TO_CHAR(fish.NAME), ',') WITHIN GROUP (ORDER BY NVL(rel.ORDER_INDEX, 999999), a.FTP), '([^,]+)(,\\1)*(,|$)', '\\1\\3') AS planFtp " + + " FROM ( " + + " SELECT STCD, TRIM(REGEXP_SUBSTR(FTP, '[^,]+', 1, LEVEL)) AS FTP " + + " FROM ( " + + " SELECT STCD, FTP " + + " FROM SD_FPRUNPLAN_B " + + " WHERE (TASK_STATUS = 'Approved' OR TASK_STATUS IS NULL) " + + " AND IS_DELETED = 0 " + + " AND STCD = #{map.stcd} " + + " AND TO_CHAR(START_TIME, 'yyyy') = #{map.yr} " + + " ) " + + " CONNECT BY REGEXP_SUBSTR(FTP, '[^,]+', 1, LEVEL) IS NOT NULL " + + " AND PRIOR TO_CHAR(SYS_GUID()) IS NOT NULL " + + " AND PRIOR FTP = FTP " + + " AND PRIOR STCD = STCD " + + " ) a " + + " INNER JOIN SD_FPSS_B_H fpss ON fpss.STCD = a.STCD " + + " LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fpss.RSTCD " + + " LEFT JOIN SD_FISHDICTORY_RLTN_B rel ON rel.RVCD = eng.HBRVCD " + + " AND rel.FISH_ID = a.FTP " + + " AND rel.IS_DELETED = 0 " + + " LEFT JOIN SD_FISHDICTORY_B fish ON fish.ID = NVL(rel.ZY_FISH_ID, a.FTP) " + + " AND fish.IS_DELETED = 0 " + + " GROUP BY a.STCD " + + ") t1 ON t.STCD = t1.STCD " + + "LEFT JOIN ( " + + " SELECT a.STCD, MIN(a.stm) AS stm, MAX(a.edm) AS edm, MAX(a.pycnt) AS pycnt " + + " FROM ( " + + " SELECT STCD, TO_CHAR(START_TIME, 'mm') AS stm, TO_CHAR(END_TIME, 'mm') AS edm, PYCNT AS pycnt " + + " FROM SD_FPRUNPLAN_B " + + " WHERE (TASK_STATUS = 'Approved' OR TASK_STATUS IS NULL) " + + " AND IS_DELETED = 0 " + + " AND STCD = #{map.stcd} " + + " AND TO_CHAR(START_TIME, 'yyyy') = #{map.yr} " + + " UNION ALL " + + " SELECT STCD, STMONTH AS stm, ETMMONTH AS edm, FREQUENCY AS pycnt " + + " FROM SD_FPDESIGNSTAND_B " + + " WHERE IS_DELETED = 0 " + + " AND STCD = #{map.stcd} " + + " AND STCD NOT IN ( " + + " SELECT STCD " + + " FROM SD_FPRUNPLAN_B " + + " WHERE (TASK_STATUS = 'Approved' OR TASK_STATUS IS NULL) " + + " AND IS_DELETED = 0 " + + " AND STCD = #{map.stcd} " + + " AND TO_CHAR(START_TIME, 'yyyy') = #{map.yr} " + + " GROUP BY STCD " + + " ) " + + " ) a " + + " GROUP BY a.STCD " + + ") t2 ON t.STCD = t2.STCD " + + "WHERE t.STCD = #{map.stcd}"; + } + + private String resolveFallbackFishText(String fallbackFishJson, String fallbackFishText) { + if (StrUtil.isNotBlank(fallbackFishJson)) { + Set fishNames = new LinkedHashSet<>(); + Matcher matcher = FISH_NAME_PATTERN.matcher(fallbackFishJson); + while (matcher.find()) { + fishNames.add(StrUtil.trim(matcher.group(1))); + } + if (!fishNames.isEmpty()) { + return String.join(",", fishNames); + } + } + return StrUtil.blankToDefault(StrUtil.trim(fallbackFishText), null); + } +} diff --git a/backend/src/main/java/com/yfd/platform/env/wq/controller/EnvWqDataController.java b/backend/src/main/java/com/yfd/platform/env/wq/controller/EnvWqDataController.java index be6c330..b0e0082 100644 --- a/backend/src/main/java/com/yfd/platform/env/wq/controller/EnvWqDataController.java +++ b/backend/src/main/java/com/yfd/platform/env/wq/controller/EnvWqDataController.java @@ -48,7 +48,7 @@ public class EnvWqDataController { } @PostMapping("/data/noAuth/GetKendoListCust") - @Operation(summary = "水质统计分析") + @Operation(summary = "水质统计分析(完成)") public ResponseResult getNoAuthKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(envWqDataService.processKendoList(dataSourceRequest)); } @@ -66,13 +66,13 @@ public class EnvWqDataController { } @PostMapping("/vmsstbprpt/GetKendoList") - @Operation(summary = "根据条件查询水质基础站点数据") + @Operation(summary = "根据条件查询水质基础站点数据(完成)") public ResponseResult getVmsstbprptList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(envWqDataService.getVmsstbprptList(dataSourceRequest)); } @GetMapping("/msstbprpt/getStcdInfo") - @Operation(summary = "根据站码查询单条水质基础数据") + @Operation(summary = "根据站码查询单条水质基础数据(完成)") public ResponseResult getStcdInfo(@RequestParam String stcd) { return ResponseResult.successData(envWqDataService.getStcdInfo(stcd)); } diff --git a/backend/src/main/java/com/yfd/platform/env/wq/service/impl/EnvWqDataServiceImpl.java b/backend/src/main/java/com/yfd/platform/env/wq/service/impl/EnvWqDataServiceImpl.java index 96932db..9a62d97 100644 --- a/backend/src/main/java/com/yfd/platform/env/wq/service/impl/EnvWqDataServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/env/wq/service/impl/EnvWqDataServiceImpl.java @@ -322,7 +322,7 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { .append("SWR.WQGRD, MSB.WWQTG, SWR.SFDB, SWR.WQ_SFDBHN_YS, ") .append("MSB.BASE_ID, MSB.BASE_NAME, MSB.RVCD_NAME, MSB.ADDVCD_NAME, MSB.DTIN_TYPE, ") .append("MSB.BASESTEPSORT, MSB.RVCDSTEPSORT, MSB.RSTCDSTEPSORT, MSB.SITESTEPSORT, ") - .append("MSB.TTPWR, MSB.STTP_CODE, "); + .append("MSB.STTP_CODE, "); if (calculated) { sql.append("CAST(NULL AS NUMBER(15,3)) AS QI, CAST(NULL AS NUMBER(15,3)) AS QO "); } else { @@ -337,8 +337,7 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { sql.append("INNER JOIN (").append(buildEnvWqDataStationBaseSql()).append(") MSB ON MSB.STCD = SWR.STCD "); if (!calculated) { sql.append("LEFT JOIN SD_HYDROPW_R SHR ON MSB.RSTCD = SHR.STCD AND SWR.TM = SHR.TM AND MSB.DTIN_TYPE = 0 ") - .append("WHERE SWR.TM <= SYSDATE ") - .append("AND (SWR.TASK_ID IS NULL OR SWR.TASK_ID = '' OR SWR.TASK_STATUS = 'Approved') "); + .append("WHERE SWR.TM <= SYSDATE "); } else { sql.append("WHERE 1 = 1 "); } @@ -362,7 +361,6 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { "wq.DTIN_TYPE, " + "siteAlong.SORT AS SITESTEPSORT, " + "hb.ORDER_INDEX AS BASESTEPSORT, " + - "eng.TTPWR AS TTPWR, " + "rstAlong.SORT AS RSTCDSTEPSORT, " + "rvAlong.ORDER_INDEX AS RVCDSTEPSORT, " + "wq.STTP AS STTP_CODE " + @@ -506,7 +504,6 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { case "wqSfdbhnYs" -> "T.WQ_SFDBHN_YS"; case "siteStepSort" -> "T.SITESTEPSORT"; case "baseStepSort" -> "T.BASESTEPSORT"; - case "ttpwr" -> "T.TTPWR"; case "rstcdStepSort" -> "T.RSTCDSTEPSORT"; case "sttpCode" -> "T.STTP_CODE"; default -> null; @@ -899,7 +896,6 @@ public class EnvWqDataServiceImpl implements EnvWqDataService { case "baseStepSort" -> "T.BASESTEPSORT"; case "rvcdStepSort" -> "T.RVCDSTEPSORT"; case "siteStepSort" -> "T.SITESTEPSORT"; - case "drMonth" -> "T.DR_MONTH"; case "drYear" -> "T.DR_YEAR"; case "wqSfdbHy" -> "T.WQ_SFDB_HY"; case "wqSfdbHn" -> "T.WQ_SFDB_HN";