From da213852f62583e2e0a9a9856c9757e395a1d1b9 Mon Sep 17 00:00:00 2001 From: tangwei Date: Wed, 17 Jun 2026 14:42:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=B1=BC=E7=B1=BB=E5=A2=9E=E6=AE=96?= =?UTF-8?q?=E7=AB=99=E7=A7=91=E7=A0=94=E6=83=85=E5=86=B5=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fb/controller/FbResearchbController.java | 29 ++ .../qgc_env/fb/entity/vo/FbResearchVo.java | 49 +++ .../qgc_env/fb/service/FbStationService.java | 3 + .../fb/service/impl/FbStationServiceImpl.java | 331 ++++++++++++++++++ 4 files changed, 412 insertions(+) create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbResearchbController.java create mode 100644 backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbResearchVo.java diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbResearchbController.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbResearchbController.java new file mode 100644 index 00000000..4861d4c1 --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/controller/FbResearchbController.java @@ -0,0 +1,29 @@ +package com.yfd.platform.qgc_env.fb.controller; + +import com.yfd.platform.common.DataSourceRequest; +import com.yfd.platform.config.ResponseResult; +import com.yfd.platform.qgc_env.fb.service.FbStationService; +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("/fb/base/researchb") +@Tag(name = "鱼类增殖站科研情况") +@Validated +public class FbResearchbController { + + @Resource + private FbStationService fbStationService; + + @PostMapping("/GetKendoList") + @Operation(summary = "鱼类增殖站科研情况列表") + public ResponseResult getKendoList(@RequestBody DataSourceRequest dataSourceRequest) { + return ResponseResult.successData(fbStationService.getResearchKendoList(dataSourceRequest)); + } +} diff --git a/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbResearchVo.java b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbResearchVo.java new file mode 100644 index 00000000..6af5dbcd --- /dev/null +++ b/backend/src/main/java/com/yfd/platform/qgc_env/fb/entity/vo/FbResearchVo.java @@ -0,0 +1,49 @@ +package com.yfd.platform.qgc_env.fb.entity.vo; + +import lombok.Data; + +import java.util.Date; + +@Data +public class FbResearchVo { + + private String id; + + private String stcd; + + private Date dt; + + private String ftp; + + private String ftpName; + + private String wco; + + private String jd; + + private String fid; + + private String recordUser; + + private Date recordTime; + + private String modifyUser; + + private Date modifyTime; + + private Integer isDeleted; + + private String deleteUser; + + private Date deleteTime; + + private String rstcd; + + private String ennm; + + private String baseId; + + private String baseName; + + private String hbrvcd; +} 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 a768fd7e..d62ac4d5 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 @@ -6,6 +6,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRQgcVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishTableVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbFlDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbRelatedYrVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FbResearchVo; 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; @@ -25,6 +26,8 @@ public interface FbStationService { DataSourceResult getBsmfRFishKendoListCust(DataSourceRequest dataSourceRequest); + DataSourceResult getResearchKendoList(DataSourceRequest dataSourceRequest); + DataSourceResult getFbRelatedYrByStcd(String stcd); FbStInfoResultVo getStInfoByStcd(String stcd); 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 6a3965a9..fdb4c098 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 @@ -18,6 +18,7 @@ import com.yfd.platform.qgc_env.fb.entity.vo.FbBsmfRFishTableVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbFtpStatisticsVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbFlDataVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbRelatedYrVo; +import com.yfd.platform.qgc_env.fb.entity.vo.FbResearchVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStBaseInfoVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStInfoResultVo; import com.yfd.platform.qgc_env.fb.entity.vo.FbStationOverviewSecondVo; @@ -118,6 +119,16 @@ public class FbStationServiceImpl implements FbStationService { return result; } + @Override + public DataSourceResult getResearchKendoList(DataSourceRequest dataSourceRequest) { + DataSourceLoadOptionsBase loadOptions = dataSourceRequest == null ? null : dataSourceRequest.toDevRequest(); + GroupingInfo[] groups = loadOptions == null ? null : loadOptions.getGroup(); + if (groups != null && groups.length > 0) { + return queryResearchGroupList(dataSourceRequest, groups); + } + return queryResearchDetailList(dataSourceRequest, loadOptions); + } + @Override public DataSourceResult getFbRelatedYrByStcd(String stcd) { DataSourceResult result = new DataSourceResult<>(); @@ -755,6 +766,68 @@ public class FbStationServiceImpl implements FbStationService { return result; } + private DataSourceResult queryResearchDetailList(DataSourceRequest dataSourceRequest, + DataSourceLoadOptionsBase loadOptions) { + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT ") + .append(buildResearchDetailSelectSql(dataSourceRequest == null ? null : dataSourceRequest.getSelect())) + .append(" FROM (") + .append(buildResearchCoreSql()) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildResearchFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + sql.append(buildResearchOrderBySql(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, FbResearchVo.class + ); + DataSourceResult result = new DataSourceResult<>(); + result.setData(list); + result.setTotal(page != null ? page.getTotal() : list.size()); + result.setAggregates(new HashMap<>()); + return result; + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + private DataSourceResult queryResearchGroupList(DataSourceRequest dataSourceRequest, + GroupingInfo[] groupInfos) { + Map paramMap = new HashMap<>(); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT * FROM (") + .append(buildResearchCoreSql()) + .append(") t WHERE 1 = 1 "); + + String filterSql = buildResearchFilterCondition( + dataSourceRequest == null ? null : dataSourceRequest.getFilter(), + paramMap, + new int[]{0} + ); + if (StrUtil.isNotBlank(filterSql)) { + sql.append(" AND ").append(filterSql).append(" "); + } + + String groupSql = buildResearchGroupSql(sql.toString(), dataSourceRequest == null ? null : dataSourceRequest.getGroup()); + List> rows = microservicDynamicSQLMapper.pageAllList(null, groupSql, paramMap); + DataSourceResult result = new DataSourceResult<>(); + if (Boolean.TRUE.equals(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; + } + @SuppressWarnings({"rawtypes", "unchecked"}) private DataSourceResult queryQgcBsmfRGroupList(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions, @@ -808,6 +881,264 @@ public class FbStationServiceImpl implements FbStationService { } } + private String buildResearchCoreSql() { + String fishNameExpr = buildFishNameExpr("res.FTP"); + StringBuilder sql = new StringBuilder(); + sql.append("SELECT res.ID AS id, ") + .append("res.STCD AS stcd, ") + .append("res.DT AS dt, ") + .append("res.FTP AS ftp, ") + .append(fishNameExpr).append(" AS ftpName, ") + .append("res.WCO AS wco, ") + .append("res.JD AS jd, ") + .append("res.FID AS fid, ") + .append("res.RECORD_USER AS recordUser, ") + .append("res.RECORD_TIME AS recordTime, ") + .append("res.MODIFY_USER AS modifyUser, ") + .append("res.MODIFY_TIME AS modifyTime, ") + .append("res.IS_DELETED AS isDeleted, ") + .append("res.DELETE_USER AS deleteUser, ") + .append("res.DELETE_TIME AS deleteTime, ") + .append("fb.RSTCD AS rstcd, ") + .append("eng.ENNM AS ennm, ") + .append("fb.BASE_ID AS baseId, ") + .append("hb.BASENAME AS baseName, ") + .append("fb.HBRVCD AS hbrvcd ") + .append("FROM SD_FBRESEARCH_B res ") + .append("LEFT JOIN SD_FBRD_B_H fb ON fb.STCD = res.STCD ") +// .append(" AND NVL(fb.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_ENGINFO_B_H eng ON eng.STCD = fb.RSTCD ") + .append(" AND NVL(eng.IS_DELETED, 0) = 0 ") + .append("LEFT JOIN SD_HYDROBASE hb ON hb.BASEID = fb.BASE_ID ") + .append(" AND NVL(hb.IS_DELETED, 0) = 0 ") + .append(" AND NVL(hb.ENABLED, 1) = 1 ") + .append(buildFishJoinSql("res.FTP", "fb.HBRVCD")) + .append("WHERE NVL(res.IS_DELETED, 0) = 0 "); + return sql.toString(); + } + + private String buildResearchDetailSelectSql(List select) { + List fields = CollUtil.isEmpty(select) + ? List.of("id", "stcd", "dt", "ftp", "ftpName", "wco", "jd", "fid", + "recordUser", "recordTime", "modifyUser", "modifyTime", "isDeleted", + "deleteUser", "deleteTime", "rstcd", "ennm", "baseId", "baseName", "hbrvcd") + : select; + List selectParts = new ArrayList<>(); + for (String field : fields) { + String column = mapResearchColumn(field); + if (StrUtil.isNotBlank(column)) { + selectParts.add(column + " AS " + field); + } + } + if (selectParts.isEmpty()) { + selectParts.add("t.id AS id"); + } + return String.join(", ", selectParts); + } + + private String buildResearchFilterCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + if (filter == null) { + return ""; + } + if (StrUtil.isNotBlank(filter.getField())) { + return buildResearchLeafCondition(filter, paramMap, indexHolder); + } + if (CollUtil.isEmpty(filter.getFilters())) { + return ""; + } + List conditions = new ArrayList<>(); + for (DataSourceRequest.FilterDescriptor child : filter.getFilters()) { + String childSql = buildResearchFilterCondition(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 buildResearchLeafCondition(DataSourceRequest.FilterDescriptor filter, + Map paramMap, + int[] indexHolder) { + String field = filter.getField(); + String column = mapResearchColumn(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 = "researchP" + indexHolder[0]++; + paramMap.put(key, normalizeResearchValue(field, item)); + placeholders.add("#{map." + key + "}"); + } + return column + " IN (" + String.join(", ", placeholders) + ")"; + } + if (value == null) { + return ""; + } + String key = "researchP" + indexHolder[0]++; + Object normalizedValue = normalizeResearchValue(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 "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 + "}"; + } + case "contains" -> { + paramMap.put(key, "%" + normalizedValue + "%"); + yield column + " LIKE #{map." + key + "}"; + } + case "doesnotcontain" -> { + paramMap.put(key, "%" + normalizedValue + "%"); + yield column + " NOT 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 + "}"; + } + default -> ""; + }; + } + + private String buildResearchOrderBySql(List sortDescriptors) { + if (CollUtil.isEmpty(sortDescriptors)) { + return " ORDER BY t.dt DESC, t.recordTime DESC"; + } + List parts = new ArrayList<>(); + for (DataSourceRequest.SortDescriptor descriptor : sortDescriptors) { + String column = mapResearchColumn(descriptor.getField()); + if (StrUtil.isBlank(column)) { + continue; + } + String direction = "desc".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + parts.add(column + " " + direction); + } + if (parts.isEmpty()) { + return " ORDER BY t.dt DESC, t.recordTime DESC"; + } + return " ORDER BY " + String.join(", ", parts); + } + + private String buildResearchGroupSql(String baseSql, List groups) { + if (CollUtil.isEmpty(groups)) { + return baseSql; + } + List validGroups = groups.stream() + .filter(group -> StrUtil.isNotBlank(mapResearchColumn(group.getField()))) + .toList(); + if (validGroups.isEmpty()) { + return baseSql; + } + List fields = validGroups.stream().map(DataSourceRequest.GroupDescriptor::getField).toList(); + StringBuilder sql = new StringBuilder("SELECT "); + for (int i = 0; i < fields.size(); i++) { + if (i > 0) { + sql.append(", "); + } + sql.append(fields.get(i)); + } + for (String field : fields) { + sql.append(", COUNT(*) AS count_").append(field); + } + sql.append(" FROM (").append(baseSql).append(") t GROUP BY "); + for (int i = 0; i < fields.size(); i++) { + if (i > 0) { + sql.append(", "); + } + sql.append(fields.get(i)); + } + List orderByParts = new ArrayList<>(); + for (DataSourceRequest.GroupDescriptor descriptor : validGroups) { + if (Boolean.FALSE.equals(descriptor.getNeedSortFlag())) { + continue; + } + String direction = "desc".equalsIgnoreCase(descriptor.getDir()) ? "DESC" : "ASC"; + orderByParts.add(descriptor.getField() + " " + direction); + } + if (!orderByParts.isEmpty()) { + sql.append(" ORDER BY ").append(String.join(", ", orderByParts)); + } + return sql.toString(); + } + + private String mapResearchColumn(String field) { + return switch (field) { + case "id" -> "t.id"; + case "stcd" -> "t.stcd"; + case "dt" -> "t.dt"; + case "ftp" -> "t.ftp"; + case "ftpName" -> "t.ftpName"; + case "wco" -> "t.wco"; + case "jd" -> "t.jd"; + case "fid" -> "t.fid"; + case "recordUser" -> "t.recordUser"; + case "recordTime" -> "t.recordTime"; + case "modifyUser" -> "t.modifyUser"; + case "modifyTime" -> "t.modifyTime"; + case "isDeleted" -> "t.isDeleted"; + case "deleteUser" -> "t.deleteUser"; + case "deleteTime" -> "t.deleteTime"; + case "rstcd" -> "t.rstcd"; + case "ennm" -> "t.ennm"; + case "baseId" -> "t.baseId"; + case "baseName" -> "t.baseName"; + case "hbrvcd" -> "t.hbrvcd"; + default -> ""; + }; + } + + private Object normalizeResearchValue(String field, Object value) { + if (value == null) { + return null; + } + if (Set.of("dt", "recordTime", "modifyTime", "deleteTime").contains(field) + && value instanceof String text) { + return parseDateTimeSafely(text); + } + return value; + } + private String buildBsmfRFishInnerSql(DataSourceRequest dataSourceRequest, DataSourceLoadOptionsBase loadOptions, Map paramMap) {