From 59ff341aa087bbd29b082f89e5f51b55ee608c5f Mon Sep 17 00:00:00 2001 From: tangwei Date: Thu, 3 Sep 2026 18:14:36 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=A2=9E=E6=AE=96=E8=AE=A1=E5=88=92?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=83=85=E5=86=B5(=E6=95=B0=E9=87=8F+?= =?UTF-8?q?=E7=A7=8D=E7=B1=BB)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbStationController.java | 6 + .../qgc_env/fb/entity/vo/FbPlanFinishVo.java | 35 +++++ .../qgc_env/fb/service/FbStationService.java | 8 ++ .../fb/service/impl/FbStationServiceImpl.java | 124 ++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbPlanFinishVo.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 68b3afa7..7fed0415 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 @@ -249,6 +249,12 @@ public class FbStationController { return ResponseResult.success(); } + @PostMapping("/planFinish/GetKendoListCust") + @Operation(summary = "增殖计划完成情况(数量+种类)") + public ResponseResult getPlanFinishKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getPlanFinishKendoListCust(dataSourceRequest)); + } + @PostMapping("/fishType/GetKendoListCust") @Operation(summary = "增殖站鱼种完成情况统计") public ResponseResult getFishTypeKendoListCust(@RequestBody DataSourceRequest dataSourceRequest) { diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbPlanFinishVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbPlanFinishVo.java new file mode 100644 index 00000000..8ca46371 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbPlanFinishVo.java @@ -0,0 +1,35 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.math.BigDecimal; + +/** + * 增殖计划完成情况(数量 + 种类) + * + * @author + */ +@Data +public class FbPlanFinishVo { + + /** 增殖站站码 */ + private String stcd; + + /** 数量-计划完成总数 */ + private BigDecimal planQty; + + /** 数量-已完成总数 */ + private BigDecimal finishedQty; + + /** 数量-未完成总数 */ + private BigDecimal unfinishedQty; + + /** 种类-计划完成种类总数 */ + private Integer planFtp; + + /** 种类-已完成种类数量 */ + private Integer finishedFtp; + + /** 种类-未完成种类数量 */ + private Integer unfinishedFtp; +} \ 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 8896c6ed..d2a10a2c 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 @@ -53,6 +53,14 @@ public interface FbStationService { DataSourceResult getFishTypeKendoListCust(DataSourceRequest dataSourceRequest); + /** + * 增殖计划完成情况(数量 + 种类),按增殖站统计: + * 数量-计划完成总数/已完成总数/未完成总数,种类-计划完成种类总数/已完成种类数量/未完成种类数量。 + * + * @param dataSourceRequest 支持 stcd/rstcd/startTime/endTime 过滤与分页排序 + */ + DataSourceResult getPlanFinishKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getFishTypeStcdList(DataSourceRequest dataSourceRequest); DataSourceResult getMsfbrdmKendoListCust(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 e0ac66b7..7d98dbce 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 @@ -614,6 +614,38 @@ public class FbStationServiceImpl implements FbStationService { return result; } + @Override + public DataSourceResult getPlanFinishKendoListCust(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + String stcd = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "stcd"); + String rstcdFilter = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "rstcd"); + String startTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "startTime"); + String endTime = loadOptions == null ? null : QgcQueryWrapperUtil.getFilterFieldValue(loadOptions, "endTime"); + + Map paramMap = new HashMap<>(); + String sql = buildPlanFinishSql( + stcd, + parseFishTypeFilterValues(rstcdFilter), + parseFishTypeDate(startTime), + parseFishTypeDate(endTime), + paramMap + ) + buildPlanFinishOrderBySql(dataSourceRequest == null ? null : dataSourceRequest.getSort()); + + Page page = loadOptions == null ? null : QgcQueryWrapperUtil.buildPage(loadOptions, loadOptions.getSkip(), loadOptions.getTake()); + List list = microservicDynamicSQLMapper.pageAllListWithResultType( + page, + sql, + paramMap, + FbPlanFinishVo.class + ); + + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + @Override public DataSourceResult getFishTypeStcdList(DataSourceRequest dataSourceRequest) { DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); @@ -1390,6 +1422,98 @@ public class FbStationServiceImpl implements FbStationService { return sql.toString(); } + /** + * 增殖计划完成情况(数量 + 种类): + * 数量:计划完成总数 / 已完成总数(实际放流) / 未完成总数 + * 种类:计划完成种类总数(COUNT(DISTINCT FTP)) / 已完成种类数量(计划种类在实际放流中出现的数量) / 未完成种类数量 + */ + private String buildPlanFinishSql(String stcd, + List rstcdList, + Date startTime, + Date endTime, + Map paramMap) { + StringBuilder sql = new StringBuilder(); + sql.append("SELECT jh.RSTCD AS stcd, ") + .append("NVL(jh.PLAN_FCNT, 0) AS planQty, ") + .append("NVL(imn.FIN_FCNT, 0) AS finishedQty, ") + .append("CASE WHEN NVL(jh.PLAN_FCNT, 0) - NVL(imn.FIN_FCNT, 0) < 0 THEN 0 ") + .append("ELSE NVL(jh.PLAN_FCNT, 0) - NVL(imn.FIN_FCNT, 0) END AS unfinishedQty, ") + .append("NVL(jh.PLAN_FTP, 0) AS planFtp, ") + .append("NVL(ftp.FIN_FTP, 0) AS finishedFtp, ") + .append("CASE WHEN NVL(jh.PLAN_FTP, 0) - NVL(ftp.FIN_FTP, 0) < 0 THEN 0 ") + .append("ELSE NVL(jh.PLAN_FTP, 0) - NVL(ftp.FIN_FTP, 0) END AS unfinishedFtp ") + .append("FROM ( ") + .append("SELECT jhr.RSTCD, SUM(jhrs.FCNT) AS PLAN_FCNT, COUNT(DISTINCT jhrs.FTP) AS PLAN_FTP ") + .append("FROM SD_ENGFRPLAN_B jhr ") + .append("JOIN SD_ENGFRPLANDET_B jhrs ON jhr.ID = jhrs.RPJH_ID ") + .append("WHERE NVL(jhr.IS_DELETED, 0) = 0 AND NVL(jhrs.IS_DELETED, 0) = 0 "); + appendFishTypeFilterSql(sql, "jhr", stcd, rstcdList, startTime, endTime, true, paramMap); + sql.append("GROUP BY jhr.RSTCD ") + .append(") jh ") + .append("LEFT JOIN ( ") + .append("SELECT imnr.RSTCD, SUM(imnrs.FCNT) AS FIN_FCNT ") + .append("FROM SD_ENGFR_R imnr ") + .append("JOIN SD_RPIMNFISH_R imnrs ON imnr.ID = imnrs.RPIMN_ID ") + .append("WHERE NVL(imnr.IS_DELETED, 0) = 0 AND NVL(imnrs.IS_DELETED, 0) = 0 "); + appendFishTypeFilterSql(sql, "imnr", stcd, rstcdList, startTime, endTime, false, paramMap); + sql.append("GROUP BY imnr.RSTCD ") + .append(") imn ON jh.RSTCD = imn.RSTCD ") + .append("LEFT JOIN ( ") + .append("SELECT temp.RSTCD AS stcd, COUNT(1) AS FIN_FTP ") + .append("FROM ( ") + .append("SELECT a.RSTCD, a.FTP ") + .append("FROM ( ") + .append("SELECT jhr.RSTCD, jhrs.FTP ") + .append("FROM SD_ENGFRPLAN_B jhr ") + .append("JOIN SD_ENGFRPLANDET_B jhrs ON jhr.ID = jhrs.RPJH_ID ") + .append("WHERE NVL(jhr.IS_DELETED, 0) = 0 AND NVL(jhrs.IS_DELETED, 0) = 0 "); + appendFishTypeFilterSql(sql, "jhr", stcd, rstcdList, startTime, endTime, true, paramMap); + sql.append("GROUP BY jhr.RSTCD, jhrs.FTP ") + .append(") a ") + .append("INNER JOIN ( ") + .append("SELECT imnr.RSTCD, imnrs.FTP ") + .append("FROM SD_ENGFR_R imnr ") + .append("JOIN SD_RPIMNFISH_R imnrs ON imnr.ID = imnrs.RPIMN_ID ") + .append("WHERE NVL(imnr.IS_DELETED, 0) = 0 AND NVL(imnrs.IS_DELETED, 0) = 0 "); + appendFishTypeFilterSql(sql, "imnr", stcd, rstcdList, startTime, endTime, false, paramMap); + sql.append("GROUP BY imnr.RSTCD, imnrs.FTP ") + .append(") b ON a.RSTCD = b.RSTCD AND a.FTP = b.FTP ") + .append(") temp GROUP BY temp.RSTCD ") + .append(") ftp ON jh.RSTCD = ftp.stcd"); + return sql.toString(); + } + + private String buildPlanFinishOrderBySql(List sorts) { + if (CollUtil.isEmpty(sorts)) { + return " ORDER BY stcd ASC"; + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor sort : sorts) { + if (sort == null || StrUtil.isBlank(sort.getField())) { + continue; + } + String column = switch (sort.getField()) { + case "stcd" -> "stcd"; + case "planQty" -> "planQty"; + case "finishedQty" -> "finishedQty"; + case "unfinishedQty" -> "unfinishedQty"; + case "planFtp" -> "planFtp"; + case "finishedFtp" -> "finishedFtp"; + case "unfinishedFtp" -> "unfinishedFtp"; + default -> null; + }; + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(sort.getDir()) ? "DESC" : "ASC"; + orderByParts.add(column + " " + direction); + } + if (orderByParts.isEmpty()) { + return " ORDER BY stcd ASC"; + } + return " ORDER BY " + String.join(", ", orderByParts); + } + private String buildFishCountOrderBySql(List sorts) { if (CollUtil.isEmpty(sorts)) { return " ORDER BY stcd ASC";