From 159f24eaf7fa403a331d6aabc3a8dc1d68341d45 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 1 Jul 2026 13:11:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20(=E5=85=A8=E8=BF=87=E7=A8=8B)=E5=A2=9E?= =?UTF-8?q?=E6=AE=96=E7=AB=99=E4=BA=8C=E7=BA=A7=E9=A1=B5=E9=9D=A2:=20?= =?UTF-8?q?=E8=BF=87=E7=A8=8B=E5=9B=BE-=E4=BA=A7=E5=8D=B5=E5=92=8C?= =?UTF-8?q?=E5=AD=B5=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbStationController.java | 8 + .../qgc_env/fb/entity/vo/FishhatchrecRVo.java | 17 ++ .../qgc_env/fb/entity/vo/HeadColunmsVo.java | 52 ++++ .../qgc_env/fb/entity/vo/TableVo.java | 27 ++ .../qgc_env/fb/service/FbStationService.java | 3 + .../fb/service/impl/FbStationServiceImpl.java | 233 ++++++++++++++++++ 6 files changed, 340 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java index 9d05bd9f..f0d90c09 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbStationController.java @@ -132,4 +132,12 @@ public class FbStationController { public ResponseResult getResearchKendoList(@RequestBody DataSourceRequest dataSourceRequest) { return ResponseResult.successData(fbStationService.getResearchKendoList(dataSourceRequest)); } + + @PostMapping("/fishhatchrecr/fish/GetKendoListCust") + @Operation(summary = "(全过程)增殖站二级页面: 过程图-产卵和孵化") + public ResponseResult getFishhatchrecrFishKendoListCust( + @Parameter(description = "类型:1-鱼卵数量,2-出苗数量") @RequestParam("type") Integer type, + @RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getFishhatchrecrFishKendoListCust(type, dataSourceRequest)); + } } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java new file mode 100644 index 00000000..9e767b51 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FishhatchrecRVo.java @@ -0,0 +1,17 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +@Data +public class FishhatchrecRVo { + + private String tm; + + private String ftp; + + private String ftpName; + + private String eggcount; + + private String outcount; +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java new file mode 100644 index 00000000..9093d280 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/HeadColunmsVo.java @@ -0,0 +1,52 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class HeadColunmsVo { + + private String dataIndex; + + private String title; + + private Boolean visible = true; + + private String key; + + private String unit; + + private boolean merge; + + private String dataType; + + private String dataFormat; + + private List children; + + public HeadColunmsVo(String title, String dataIndex) { + this.title = title; + this.dataIndex = dataIndex; + } + + public HeadColunmsVo(String dataIndex, String title, Boolean visible, String key, boolean merge, List children) { + this.dataIndex = dataIndex; + this.title = title; + this.visible = visible; + this.key = key; + this.merge = merge; + this.children = children; + } + + public HeadColunmsVo setDataType(String dataType) { + this.dataType = dataType; + return this; + } + + public HeadColunmsVo setDataFormat(String dataFormat) { + this.dataFormat = dataFormat; + return this; + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java new file mode 100644 index 00000000..5bd4141b --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/TableVo.java @@ -0,0 +1,27 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.List; + +@Data +public class TableVo { + + private List columns; + + private Object dataSource; + + private Long total; + + private Integer wtDeviceType; + + public TableVo() { + } + + public TableVo(List dataSource, Long total) { + this.dataSource = dataSource; + if (total != null) { + this.total = total; + } + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java index 1bada486..b9fde95c 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/FbStationService.java @@ -16,6 +16,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.YearRpStatisticsVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; +import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; import java.util.List; import java.util.Map; @@ -57,4 +58,6 @@ public interface FbStationService { DataSourceResult getOverviewSecond(DataSourceRequest dataSourceRequest); DataSourceResult getQgcOverviewSecond(DataSourceRequest dataSourceRequest); + + DataSourceResult getFishhatchrecrFishKendoListCust(Integer type, DataSourceRequest dataSourceRequest); } diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java index a3e50842..dff8e149 100644 --- a/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/service/impl/FbStationServiceImpl.java @@ -30,6 +30,9 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationStaticsRawVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FishhatchrecRVo; +import com.yfd.platform.qgc_env.fb.entity.vo.HeadColunmsVo; +import com.yfd.platform.qgc_env.fb.entity.vo.TableVo; import com.yfd.platform.qgc_env.fb.entity.vo.YearRpStatisticsVo; import com.yfd.platform.qgc_env.fb.service.FbStationService; import com.yfd.platform.utils.QgcQueryWrapperUtil; @@ -4103,4 +4106,234 @@ public class FbStationServiceImpl implements FbStationService { } values.add(text); } + + @Override + public DataSourceResult getFishhatchrecrFishKendoListCust(Integer type, DataSourceRequest dataSourceRequest) { + DataSourceResult dataSourceResult = new DataSourceResult<>(); + String unit = type == 1 ? "(万粒)" : "(万尾)"; + + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT tm, ") + .append("LISTAGG(TO_CHAR(ftp), ',') WITHIN GROUP (ORDER BY ftp) AS ftp, ") + .append("LISTAGG(TO_CHAR(NAME), ',') WITHIN GROUP (ORDER BY ftp) AS ftpName, ") + .append("LISTAGG(eggcount, ',') WITHIN GROUP (ORDER BY ftp) AS eggcount, ") + .append("LISTAGG(outcount, ',') WITHIN GROUP (ORDER BY ftp) AS outcount ") + .append("FROM (") + .append("SELECT ") + .append("TO_CHAR(tm, 'YYYY-MM') AS tm, ftp, ") + .append("CASE WHEN NAME IS NULL THEN TO_NCHAR(ftp) ELSE NAME END AS NAME, ") + .append("CASE WHEN SUM(eggcount) IS NULL THEN '-' ELSE RTRIM(TO_CHAR(SUM(eggcount), 'FM999999999999990.99'), '.') END AS eggcount, ") + .append("CASE WHEN SUM(outcount) IS NULL THEN '-' ELSE RTRIM(TO_CHAR(SUM(outcount), 'FM999999999999990.99'), '.') END AS outcount ") + .append("FROM (") + .append("SELECT ") + .append("t.tm, ") + .append("CASE WHEN fishViewZy.ZY_FISH_ID IS NULL THEN t.ftp ELSE fishViewZy.ZY_FISH_ID END AS ftp, ") + .append("CASE WHEN fishViewZy.NAME IS NULL THEN fishViewRv.NAME ELSE fishViewZy.NAME END AS NAME, ") + .append("t.eggcount, ") + .append("t.outcount ") + .append("FROM SD_FBFISHHATCHREC_R t ") + .append("LEFT JOIN SD_FBRD_B_H fb ON t.stcd = fb.STCD ") + .append("LEFT JOIN V_SD_FISHDICTORY_B fishViewRv ON t.FTP = fishViewRv.FISH_ID AND fb.HBRVCD = fishViewRv.RVCD ") + .append("LEFT JOIN V_SD_FISHDICTORY_B fishViewZy ON t.FTP = fishViewZy.FISH_ID AND fishViewZy.RVCD = 'ZY' ") + .append("WHERE NVL(t.IS_DELETED, 0) = 0 "); + + appendFishhatchrecrFishFilterConditions(sql, dataSourceRequest, paramMap); + + sql.append(") GROUP BY TO_CHAR(tm, 'YYYY-MM'), ftp, NAME ") + .append(") GROUP BY tm ") + .append("ORDER BY tm DESC "); + + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, sql.toString(), paramMap, FishhatchrecRVo.class + ); + + long total = page != null ? page.getTotal() : list.size(); + TableVo tableVo = buildFishhatchrecrFishTableVo(list, total, type, unit); + dataSourceResult.setData(Collections.singletonList(tableVo)); + dataSourceResult.setTotal(total); + dataSourceResult.setAggregates(new HashMap<>()); + return dataSourceResult; + } + + private void appendFishhatchrecrFishFilterConditions(StringBuilder sql, + DataSourceRequest dataSourceRequest, + Map paramMap) { + if (dataSourceRequest == null || dataSourceRequest.getFilter() == null) { + return; + } + String filterSql = buildFishhatchrecrFishFilterCondition(dataSourceRequest.getFilter(), paramMap, new int[]{0}); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + } + + private String buildFishhatchrecrFishFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildFishhatchrecrFishLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildFishhatchrecrFishFilterCondition(child, paramMap, indexHolder); + if (StrUtil.isNotBlank(childSql)) { + conditions.add("(" + childSql + ")"); + } + } + if (conditions.isEmpty()) { + return ""; + } + String logic = "or".equalsIgnoreCase(filter.getLogic()) ? " OR " : " AND "; + return String.join(logic, conditions); + } + + private String buildFishhatchrecrFishLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + String column = mapFishhatchrecrFishColumn(field); + if (StrUtil.isBlank(column)) { + return ""; + } + String operator = StrUtil.blankToDefault(filter.getOperator(), "eq").toLowerCase(); + Object value = filter.getValue(); + if ("isnull".equals(operator)) { + return column + " IS NULL"; + } + if ("isnotnull".equals(operator)) { + return column + " IS NOT NULL"; + } + if ("in".equals(operator)) { + List values = normalizeQgcBsmfRValues(value); + if (values.isEmpty()) { + return ""; + } + List placeholders = new ArrayList<>(); + for (Object item : values) { + String key = "hatchFishP" + indexHolder[0]++; + paramMap.put(key, item); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "hatchFishP" + indexHolder[0]++; + Object normalizedValue = normalizeFishhatchrecrFishValue(field, value); + return switch (operator) { + case "eq" -> { + paramMap.put(key, normalizedValue); + yield column + " = #{map." + key + "}"; + } + case "neq" -> { + paramMap.put(key, normalizedValue); + yield column + " <> #{map." + key + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "startswith" -> { + paramMap.put(key, normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "endswith" -> { + paramMap.put(key, "%" + normalizedValue); + yield column + " LIKE #{map." + key + "}"; + } + case "gt" -> { + paramMap.put(key, normalizedValue); + yield column + " > #{map." + key + "}"; + } + case "gte" -> { + paramMap.put(key, normalizedValue); + yield column + " >= #{map." + key + "}"; + } + case "lt" -> { + paramMap.put(key, normalizedValue); + yield column + " < #{map." + key + "}"; + } + case "lte" -> { + paramMap.put(key, normalizedValue); + yield column + " <= #{map." + key + "}"; + } + default -> ""; + }; + } + + private String mapFishhatchrecrFishColumn(String field) { + return switch (field) { + case "stcd" -> "t.STCD"; + case "ftp" -> "t.FTP"; + case "fishsrc" -> "t.FISHSRC"; + case "tm" -> "t.TM"; + case "rstcd" -> "fb.RSTCD"; + case "baseId" -> "fb.BASE_ID"; + case "hbrvcd" -> "fb.HBRVCD"; + default -> ""; + }; + } + + private Object normalizeFishhatchrecrFishValue(String field, Object value) { + if (value == null) { + return null; + } + if ("tm".equalsIgnoreCase(field) && value instanceof String text) { + return parseDateTimeSafely(text); + } + return value; + } + + private TableVo buildFishhatchrecrFishTableVo(List list, long total, Integer type, String unit) { + TableVo tableVo = new TableVo(); + List> resultData = new ArrayList<>(); + List columns = new ArrayList<>(); + Map fishMap = new LinkedHashMap<>(); + + if (CollUtil.isNotEmpty(list)) { + for (FishhatchrecRVo vo : list) { + Map rowMap = new LinkedHashMap<>(); + rowMap.put("tm", vo.getTm()); + + List ftpList = splitCsv(vo.getFtp()); + List ftpNameList = splitCsv(vo.getFtpName()); + List eggCountList = splitCsv(vo.getEggcount()); + List outCountList = splitCsv(vo.getOutcount()); + + int size = Math.min(ftpList.size(), Math.min(ftpNameList.size(), + Math.min(eggCountList.size(), outCountList.size()))); + + for (int i = 0; i < size; i++) { + String ftp = ftpList.get(i); + String ftpName = ftpNameList.get(i); + String value = type == 1 ? eggCountList.get(i) : outCountList.get(i); + rowMap.put(ftp, "-".equals(value) ? null : value); + fishMap.putIfAbsent(ftp, ftpName); + } + resultData.add(rowMap); + } + } + + columns.add(new HeadColunmsVo("tm", "时间", true, "tm", false, new ArrayList<>()) + .setDataType("date") + .setDataFormat("yyyy-MM")); + for (Map.Entry entry : fishMap.entrySet()) { + columns.add(new HeadColunmsVo(entry.getKey(), entry.getValue() + unit, true, entry.getKey(), false, new ArrayList<>())); + } + + tableVo.setColumns(columns); + tableVo.setDataSource(resultData); + tableVo.setTotal(total); + return tableVo; + } }