From 2e2c91f6796f8da999af5eb2fa401bebd3f2d71c Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 13 Aug 2026 08:14:32 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=BF=87=E9=B1=BC=E8=AE=BE=E6=96=BD?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=95=B0=E6=8D=AE=E6=97=A5=E7=BB=9F=E8=AE=A1?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fp/controller/FishPassageController.java | 6 + .../qgc_env/fp/entity/vo/FpFpssrlQdaySVo.java | 83 +++++++ .../qgc_env/fp/service/FpRunService.java | 3 + .../fp/service/impl/FpRunServiceImpl.java | 220 ++++++++++++++++++ 4 files changed, 312 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQdaySVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java index aeaeca8d..763a2697 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/controller/FishPassageController.java @@ -142,4 +142,10 @@ public class FishPassageController { public ResponseResult getQgcOverfishTotal(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(fpRunService.processQgcOverfishTotalKendoList(dataSourceRequest)); } + + @PostMapping("/fpssrlQdays/GetKendoListCust") + @Operation(summary = "过鱼设施自动数据日统计表(SD_FPSSRLDAY_S)") + public ResponseResult getQgcFpssrlQdaySKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fpRunService.processQgcFpssrlQdaySKendoList(dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQdaySVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQdaySVo.java new file mode 100644 index 00000000..176d7281 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/entity/vo/FpFpssrlQdaySVo.java @@ -0,0 +1,83 @@ +package com.yfd.platform.qgc_env.fp.entity.vo; + +import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.math.BigDecimal; +import java.util.Date; + +/** + *

+ * 过鱼设施自动数据(带水温,流速)日统计表 VO + *

+ *

对应新表 SD_FPSSRLDAY_S(旧系统 SD_FPSSRLQDAY_S)

+ */ +@Data +@Schema(description = "过鱼设施自动数据日统计表") +public class FpFpssrlQdaySVo { + + @Schema(description = "主键ID") + private String id; + + @Schema(description = "过鱼设施编码") + private String stcd; + + @Schema(description = "日期。精确到天") + @JsonFormat(pattern = "yyyy-MM-dd") + private Date dt; + + @Schema(description = "鱼类") + private String ftp; + + @Schema(description = "自动过鱼设施过鱼数量") + private BigDecimal fcnt; + + @Schema(description = "水温,单位:℃") + private BigDecimal temperature; + + @Schema(description = "水位,单位:m") + private BigDecimal waterlevel; + + @Schema(description = "流速,单位:m/s") + private BigDecimal speed; + + @Schema(description = "流量,单位:m3/s") + private BigDecimal q; + + @Schema(description = "溶氧,单位:mg/L") + private BigDecimal dox; + + @Schema(description = "浊度,单位:NTU") + private BigDecimal tu; + + @Schema(description = "鱼尺寸") + private String fsz; + + @Schema(description = "鱼长度") + private BigDecimal length; + + @Schema(description = "鱼宽度") + private BigDecimal width; + + @Schema(description = "鱼速度") + private String fishspeed; + + @Schema(description = "游向:0=上行 1=下行") + private BigDecimal direction; + + @Schema(description = "鱼位置") + private BigDecimal fishposition; + + @Schema(description = "鱼截图主图片url") + private String firstimgurl; + + @Schema(description = "鱼截图副图片url") + private String secondimgurl; + + @Schema(description = "视频url") + private String videourl; + + @Schema(description = "过鱼通道") + private String channelno; +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java index c6eea469..833178df 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/FpRunService.java @@ -11,6 +11,7 @@ import com.yfd.platform.qgc_env.fp.entity.vo.FpTableVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpTreeStcdGroupVo; import com.yfd.platform.qgc_env.fp.entity.vo.YearFpStatisticsVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpOverfishTotalVo; +import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQdaySVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunPlanVo; import java.util.List; @@ -38,4 +39,6 @@ public interface FpRunService { DataSourceResult getTreeStcdList(DataSourceRequest dataSourceRequest); DataSourceResult processQgcOverfishTotalKendoList(DataSourceRequest dataSourceRequest); + + DataSourceResult processQgcFpssrlQdaySKendoList(DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java index 9c753d0a..2991a0a9 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fp/service/impl/FpRunServiceImpl.java @@ -16,6 +16,7 @@ import com.yfd.platform.common.exception.BizException; import com.yfd.platform.qgc_env.fp.entity.vo.FbFishRunVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpFishSelectVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQueryVo; +import com.yfd.platform.qgc_env.fp.entity.vo.FpFpssrlQdaySVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpFtpStatisticsVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpOverfishTotalVo; import com.yfd.platform.qgc_env.fp.entity.vo.FpRunAnalysisHeadColumnVo; @@ -3092,4 +3093,223 @@ public class FpRunServiceImpl implements FpRunService { return orders.isEmpty() ? " ORDER BY t.TM DESC" : " ORDER BY " + String.join(", ", orders); } + // ==================== 过鱼设施自动数据日统计表 ==================== + + @Override + public DataSourceResult processQgcFpssrlQdaySKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + if (CollUtil.isEmpty(dataSourceRequest == null ? null : dataSourceRequest.getGroup())) { + return queryFpssrlQdaySDetailList(dataSourceRequest, loadOptions); + } + return queryFpssrlQdaySGroupList(dataSourceRequest, loadOptions); + } + + private DataSourceResult queryFpssrlQdaySDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildFpssrlQdaySSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildFpssrlQdaySCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0}, + this::mapFpssrlQdaySColumn + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildFpssrlQdaySOrderBySql(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, FpFpssrlQdaySVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + private DataSourceResult queryFpssrlQdaySGroupList(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 = mapFpssrlQdaySColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + selectItems.add(column + " AS " + descriptor.getField().toUpperCase()); + selectItems.add("COUNT(*) AS COUNT_" + descriptor.getField().toUpperCase()); + if (CollUtil.isNotEmpty(descriptor.getAggregates())) { + for (DataSourceRequest.AggregateDescriptor aggregate : descriptor.getAggregates()) { + String aggregateColumn = mapFpssrlQdaySColumn(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(buildFpssrlQdaySCoreSql()) + .append(") t WHERE 1 = 1 "); + + Map paramMap = new HashMap<>(); + String filterSql = QgcQueryWrapperUtil.buildFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0}, + this::mapFpssrlQdaySColumn + ); + 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 = mapFpssrlQdaySColumn(descriptor.getField()); + if (StrUtil.isNotBlank(column)) { + groupByColumns.add(column); + } + } + if (!groupByColumns.isEmpty()) { + sql.append(" GROUP BY ").append(String.join(", ", groupByColumns)).append(" "); + } + sql.append(buildFpssrlQdaySOrderBySql(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_FPSSRLDAY_S + */ + private String buildFpssrlQdaySCoreSql() { + return "SELECT t.ID, t.STCD, t.DT, t.FTP, t.FCNT, t.TEMPERATURE, t.WATERLEVEL, t.SPEED, " + + "t.Q, t.DOX, t.TU, t.FSZ, t.LENGTH, t.WIDTH, t.FISHSPEED, t.DIRECTION, " + + "t.FISHPOSITION, t.FIRSTIMGURL, t.SECONDIMGURL, t.VIDEOURL, t.CHANNELNO " + + "FROM SD_FPSSRLDAY_S t " + + "WHERE NVL(t.IS_DELETED, 0) = 0 "; + } + + private String buildFpssrlQdaySSelectSql(List selectFields) { + Map columns = new LinkedHashMap<>(); + columns.put("id", "t.ID AS id"); + columns.put("stcd", "t.STCD AS stcd"); + columns.put("dt", "t.DT AS dt"); + columns.put("ftp", "t.FTP AS ftp"); + columns.put("fcnt", "t.FCNT AS fcnt"); + columns.put("temperature", "t.TEMPERATURE AS temperature"); + columns.put("waterlevel", "t.WATERLEVEL AS waterlevel"); + columns.put("speed", "t.SPEED AS speed"); + columns.put("q", "t.Q AS q"); + columns.put("dox", "t.DOX AS dox"); + columns.put("tu", "t.TU AS tu"); + columns.put("fsz", "t.FSZ AS fsz"); + columns.put("length", "t.LENGTH AS length"); + columns.put("width", "t.WIDTH AS width"); + columns.put("fishspeed", "t.FISHSPEED AS fishspeed"); + columns.put("direction", "t.DIRECTION AS direction"); + columns.put("fishposition", "t.FISHPOSITION AS fishposition"); + columns.put("firstimgurl", "t.FIRSTIMGURL AS firstimgurl"); + columns.put("secondimgurl", "t.SECONDIMGURL AS secondimgurl"); + columns.put("videourl", "t.VIDEOURL AS videourl"); + columns.put("channelno", "t.CHANNELNO AS channelno"); + + List selected = new ArrayList<>(); + if (CollUtil.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 mapFpssrlQdaySColumn(String field) { + if (StrUtil.isBlank(field)) { + return null; + } + return switch (field.toLowerCase()) { + case "id" -> "t.ID"; + case "stcd" -> "t.STCD"; + case "dt" -> "t.DT"; + case "ftp" -> "t.FTP"; + case "fcnt" -> "t.FCNT"; + case "temperature" -> "t.TEMPERATURE"; + case "waterlevel" -> "t.WATERLEVEL"; + case "speed" -> "t.SPEED"; + case "q" -> "t.Q"; + case "dox" -> "t.DOX"; + case "tu" -> "t.TU"; + case "fsz" -> "t.FSZ"; + case "length" -> "t.LENGTH"; + case "width" -> "t.WIDTH"; + case "fishspeed" -> "t.FISHSPEED"; + case "direction" -> "t.DIRECTION"; + case "fishposition" -> "t.FISHPOSITION"; + case "firstimgurl" -> "t.FIRSTIMGURL"; + case "secondimgurl" -> "t.SECONDIMGURL"; + case "videourl" -> "t.VIDEOURL"; + case "channelno" -> "t.CHANNELNO"; + default -> null; + }; + } + + private String buildFpssrlQdaySOrderBySql(List sortList) { + if (CollUtil.isEmpty(sortList)) { + return " ORDER BY t.DT DESC"; + } + List orders = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sortList) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = mapFpssrlQdaySColumn(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.DT DESC" : " ORDER BY " + String.join(", ", orders); + } + }